55
66#include < functional>
77#include < map>
8+ #include < mutex>
89#include < string>
910#include < vector>
1011
1516
1617namespace v8_inspector {
1718
19+ class WorkerInspectorClient ;
20+
1821class JsV8InspectorClient : V8InspectorClient, V8Inspector::Channel {
1922 public:
2023 JsV8InspectorClient (tns::Runtime* runtime);
@@ -23,6 +26,20 @@ class JsV8InspectorClient : V8InspectorClient, V8Inspector::Channel {
2326 void disconnect ();
2427 void dispatchMessage (const std::string& message);
2528
29+ // The single instance debugging the main isolate (created when IsDebug);
30+ // also acts as the router for worker sessions. Null in release builds.
31+ static JsV8InspectorClient* GetInstance ();
32+
33+ // Thread-safe write to the connected frontend (no-op when disconnected).
34+ void SendToFrontend (const std::string& message);
35+
36+ // Worker targets (Chrome DevTools Target domain, flat-session mode).
37+ // Register/Unregister are called on the worker's own thread.
38+ void RegisterWorkerTarget (int workerId, WorkerInspectorClient* client);
39+ void UnregisterWorkerTarget (int workerId);
40+ // Called on a worker thread by the Debugger.pause interrupt.
41+ void SchedulePauseInWorker (int workerId);
42+
2643 // Overrides of V8Inspector::Channel
2744 void sendResponse (int callId, std::unique_ptr<StringBuffer> message) override ;
2845 void sendNotification (std::unique_ptr<StringBuffer> message) override ;
@@ -63,13 +80,39 @@ class JsV8InspectorClient : V8InspectorClient, V8Inspector::Channel {
6380
6481 // Streams backing Network.loadNetworkResource responses, read by the
6582 // frontend through IO.read/IO.close (how Chrome DevTools fetches source
66- // maps from the target). Only touched from dispatchMessage (main thread).
83+ // maps from the target). Served on the socket thread for any session;
84+ // guarded by resourceStreamsMutex_.
6785 struct ResourceStream {
6886 std::string data;
6987 size_t offset = 0 ;
7088 };
7189 std::map<std::string, ResourceStream> resourceStreams_;
7290 int lastStreamId_ = 0 ;
91+ std::mutex resourceStreamsMutex_;
92+
93+ // Worker targets announced to the frontend via Target.attachedToTarget,
94+ // keyed by their flat-protocol sessionId. Guarded by workerTargetsMutex_;
95+ // a registered client pointer stays valid until UnregisterWorkerTarget
96+ // (which runs on the worker's own thread, before the client is deleted).
97+ struct WorkerTarget {
98+ int workerId;
99+ WorkerInspectorClient* client;
100+ bool announced = false ;
101+ };
102+ std::map<std::string, WorkerTarget> workerTargets_;
103+ std::mutex workerTargetsMutex_;
104+ bool autoAttach_ = false ; // guarded by workerTargetsMutex_
105+
106+ static JsV8InspectorClient* instance_;
107+
108+ std::mutex senderMutex_;
109+
110+ // Routes a frontend message carrying a sessionId to its worker session
111+ // (socket thread). msgId is -1 when the message has no id.
112+ void RouteToWorker (const std::string& sessionId, const std::string& method,
113+ long long msgId, const std::string& message);
114+ // Announces all not-yet-announced workers (after Target.setAutoAttach).
115+ void AnnounceWorkerTargets ();
73116
74117 // Override of V8InspectorClient
75118 v8::Local<v8::Context> ensureDefaultContextInGroup (
@@ -90,10 +133,15 @@ class JsV8InspectorClient : V8InspectorClient, V8Inspector::Channel {
90133 const v8::FunctionCallbackInfo<v8::Value>& args);
91134
92135 // Source map delivery to Chrome DevTools (Network.loadNetworkResource + IO
93- // domain). V8's inspector doesn't implement these embedder domains.
94- void HandleLoadNetworkResource (int msgId, const std::string& url);
95- void HandleIORead (int msgId, const std::string& handle, int size);
96- void HandleIOClose (int msgId, const std::string& handle);
136+ // domain). V8's inspector doesn't implement these embedder domains. The
137+ // handlers are filesystem-only and thread-safe; they serve any session
138+ // (sessionId is echoed in the reply when non-empty).
139+ void HandleLoadNetworkResource (int msgId, const std::string& url,
140+ const std::string& sessionId);
141+ void HandleIORead (int msgId, const std::string& handle, int size,
142+ const std::string& sessionId);
143+ void HandleIOClose (int msgId, const std::string& handle,
144+ const std::string& sessionId);
97145
98146 // {N} specific helpers
99147 bool CallDomainHandlerFunction (v8::Local<v8::Context> context,
0 commit comments