//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// /// \file /// This file contains the declarations of the DAPSessionManager and /// ManagedEventThread classes, which are used to multiple concurrent DAP /// sessions in a single lldb-dap process. /// //===----------------------------------------------------------------------===// #ifndef LLDB_TOOLS_LLDB_DAP_DAPSESSIONMANAGER_H #define LLDB_TOOLS_LLDB_DAP_DAPSESSIONMANAGER_H #include "lldb/API/SBBroadcaster.h" #include "lldb/API/SBDebugger.h" #include "lldb/API/SBTarget.h" #include "lldb/Host/MainLoop.h" #include "lldb/lldb-types.h" #include "llvm/Support/Error.h" #include #include #include #include #include #include #include namespace lldb_dap { // Forward declarations struct DAP; class ManagedEventThread { public: // Constructor declaration ManagedEventThread(lldb::SBBroadcaster broadcaster, std::thread t); ~ManagedEventThread(); ManagedEventThread(const ManagedEventThread &) = delete; ManagedEventThread &operator=(const ManagedEventThread &) = delete; private: lldb::SBBroadcaster m_broadcaster; std::thread m_event_thread; }; /// Global DAP session manager that manages multiple concurrent DAP sessions in /// a single lldb-dap process. Handles session lifecycle tracking, coordinates /// shared debugger event threads, and facilitates target handoff between /// sessions for dynamically created targets. class DAPSessionManager { public: /// Get the singleton instance of the DAP session manager. static DAPSessionManager &GetInstance(); /// Register a DAP session. void RegisterSession(lldb_private::MainLoop *loop, DAP *dap); /// Unregister a DAP session. Called by sessions when they complete their /// disconnection, which unblocks WaitForAllSessionsToDisconnect(). void UnregisterSession(lldb_private::MainLoop *loop); /// Get all active DAP sessions. std::vector GetActiveSessions(); /// Disconnect all registered sessions by calling Disconnect() on /// each and requesting their event loops to terminate. Used during /// shutdown to force all sessions to begin disconnecting. void DisconnectAllSessions(); /// Block until all sessions disconnect and unregister. Returns an error if /// DisconnectAllSessions() was called and any disconnection failed. llvm::Error WaitForAllSessionsToDisconnect(); /// Get or create event thread for a specific debugger. std::shared_ptr GetEventThreadForDebugger(lldb::SBDebugger debugger, DAP *requesting_dap); /// Find the DAP instance that owns the given target. DAP *FindDAPForTarget(lldb::SBTarget target); /// Static convenience method for FindDAPForTarget. static DAP *FindDAP(lldb::SBTarget target) { return GetInstance().FindDAPForTarget(target); } /// Clean up expired event threads from the collection. void ReleaseExpiredEventThreads(); private: DAPSessionManager() = default; ~DAPSessionManager() = default; // Non-copyable and non-movable. DAPSessionManager(const DAPSessionManager &) = delete; DAPSessionManager &operator=(const DAPSessionManager &) = delete; DAPSessionManager(DAPSessionManager &&) = delete; DAPSessionManager &operator=(DAPSessionManager &&) = delete; bool m_client_failed = false; std::mutex m_sessions_mutex; std::condition_variable m_sessions_condition; std::map m_active_sessions; /// Map from debugger ID to its event thread, used when multiple DAP sessions /// share the same debugger instance. std::map> m_debugger_event_threads; }; } // namespace lldb_dap #endif // LLDB_TOOLS_LLDB_DAP_DAPSESSIONMANAGER_H