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 |
|
32612 |
virtual ~Request() = default; |
29 |
|
|
}; |
30 |
|
|
|
31 |
|
|
class Deletable { |
32 |
|
|
public: |
33 |
|
13058 |
virtual ~Deletable() = default; |
34 |
|
|
}; |
35 |
|
|
|
36 |
|
|
std::unique_ptr<v8_inspector::StringBuffer> Utf8ToStringView( |
37 |
|
|
const std::string& message); |
38 |
|
|
|
39 |
|
|
using MessageQueue = std::deque<std::unique_ptr<Request>>; |
40 |
|
|
|
41 |
|
|
class MainThreadHandle : public std::enable_shared_from_this<MainThreadHandle> { |
42 |
|
|
public: |
43 |
|
6019 |
explicit MainThreadHandle(MainThreadInterface* main_thread) |
44 |
|
6019 |
: main_thread_(main_thread) { |
45 |
|
6019 |
} |
46 |
|
5488 |
~MainThreadHandle() { |
47 |
|
10976 |
Mutex::ScopedLock scoped_lock(block_lock_); |
48 |
✗✓ |
5488 |
CHECK_NULL(main_thread_); // main_thread_ should have called Reset |
49 |
|
5488 |
} |
50 |
|
|
std::unique_ptr<InspectorSession> Connect( |
51 |
|
|
std::unique_ptr<InspectorSessionDelegate> delegate, |
52 |
|
|
bool prevent_shutdown); |
53 |
|
7040 |
int newObjectId() { |
54 |
|
7040 |
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(); |
82 |
|
1835 |
Agent* inspector_agent() { |
83 |
|
1835 |
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_ |