• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef SRC_INSPECTOR_MAIN_THREAD_INTERFACE_H_
2 #define SRC_INSPECTOR_MAIN_THREAD_INTERFACE_H_
3 
4 #if !HAVE_INSPECTOR
5 #error("This header can only be used when inspector is enabled")
6 #endif
7 
8 #include "inspector_agent.h"
9 #include "node_mutex.h"
10 
11 #include <atomic>
12 #include <deque>
13 #include <memory>
14 #include <unordered_map>
15 
16 namespace v8_inspector {
17 class StringBuffer;
18 class StringView;
19 }  // namespace v8_inspector
20 
21 namespace node {
22 namespace inspector {
23 class MainThreadInterface;
24 
25 class Request {
26  public:
27   virtual void Call(MainThreadInterface*) = 0;
28   virtual ~Request() = default;
29 };
30 
31 class Deletable {
32  public:
33   virtual ~Deletable() = default;
34 };
35 
36 std::unique_ptr<v8_inspector::StringBuffer> Utf8ToStringView(
37     const std::string_view message);
38 
39 using MessageQueue = std::deque<std::unique_ptr<Request>>;
40 
41 class MainThreadHandle : public std::enable_shared_from_this<MainThreadHandle> {
42  public:
MainThreadHandle(MainThreadInterface * main_thread)43   explicit MainThreadHandle(MainThreadInterface* main_thread)
44                             : main_thread_(main_thread) {
45   }
~MainThreadHandle()46   ~MainThreadHandle() {
47     Mutex::ScopedLock scoped_lock(block_lock_);
48     CHECK_NULL(main_thread_);  // main_thread_ should have called Reset
49   }
50   std::unique_ptr<InspectorSession> Connect(
51       std::unique_ptr<InspectorSessionDelegate> delegate,
52       bool prevent_shutdown);
newObjectId()53   int newObjectId() {
54     return ++next_object_id_;
55   }
56   bool Post(std::unique_ptr<Request> request);
57   std::unique_ptr<InspectorSessionDelegate> MakeDelegateThreadSafe(
58       std::unique_ptr<InspectorSessionDelegate> delegate);
59   bool Expired();
60 
61  private:
62   void Reset();
63 
64   MainThreadInterface* main_thread_;
65   Mutex block_lock_;
66   int next_session_id_ = 0;
67   std::atomic_int next_object_id_ = {1};
68 
69   friend class MainThreadInterface;
70 };
71 
72 class MainThreadInterface :
73     public std::enable_shared_from_this<MainThreadInterface> {
74  public:
75   explicit MainThreadInterface(Agent* agent);
76   ~MainThreadInterface();
77 
78   void DispatchMessages();
79   void Post(std::unique_ptr<Request> request);
80   bool WaitForFrontendEvent();
81   std::shared_ptr<MainThreadHandle> GetHandle();
inspector_agent()82   Agent* inspector_agent() {
83     return agent_;
84   }
85   void AddObject(int handle, std::unique_ptr<Deletable> object);
86   Deletable* GetObject(int id);
87   Deletable* GetObjectIfExists(int id);
88   void RemoveObject(int handle);
89 
90  private:
91   MessageQueue requests_;
92   Mutex requests_lock_;   // requests_ live across threads
93   // This queue is to maintain the order of the messages for the cases
94   // when we reenter the DispatchMessages function.
95   MessageQueue dispatching_message_queue_;
96   bool dispatching_messages_ = false;
97   ConditionVariable incoming_message_cond_;
98   // Used from any thread
99   Agent* const agent_;
100   std::shared_ptr<MainThreadHandle> handle_;
101   std::unordered_map<int, std::unique_ptr<Deletable>> managed_objects_;
102 };
103 
104 }  // namespace inspector
105 }  // namespace node
106 #endif  // SRC_INSPECTOR_MAIN_THREAD_INTERFACE_H_
107