1616
1717#include < map>
1818#include < sstream>
19+ #include < tuple>
1920#include < unicode/unistr.h>
2021
2122#include < string.h>
@@ -30,9 +31,6 @@ namespace {
3031using v8_inspector::StringBuffer;
3132using v8_inspector::StringView;
3233
33- const char TAG_CONNECT[] = " #connect" ;
34- const char TAG_DISCONNECT[] = " #disconnect" ;
35-
3634static const uint8_t PROTOCOL_JSON[] = {
3735#include " v8_inspector_protocol_json.h" // NOLINT(build/include_order)
3836};
@@ -105,6 +103,14 @@ std::unique_ptr<StringBuffer> Utf8ToStringView(const std::string& message) {
105103
106104class V8NodeInspector ;
107105
106+ enum class InspectorAction {
107+ kStartSession , kEndSession , kSendMessage
108+ };
109+
110+ enum class TransportAction {
111+ kSendMessage , kStop
112+ };
113+
108114class InspectorAgentDelegate : public node ::inspector::SocketServerDelegate {
109115 public:
110116 InspectorAgentDelegate (AgentImpl* agent, const std::string& script_path,
@@ -143,14 +149,16 @@ class AgentImpl {
143149 void FatalException (v8::Local<v8::Value> error,
144150 v8::Local<v8::Message> message);
145151
146- void PostIncomingMessage (int session_id, const std::string& message);
152+ void PostIncomingMessage (InspectorAction action, int session_id,
153+ const std::string& message);
147154 void ResumeStartup () {
148155 uv_sem_post (&start_sem_);
149156 }
150157
151158 private:
159+ template <typename Action>
152160 using MessageQueue =
153- std::vector<std::pair< int , std::unique_ptr<StringBuffer>>>;
161+ std::vector<std::tuple<Action, int , std::unique_ptr<StringBuffer>>>;
154162 enum class State { kNew , kAccepting , kConnected , kDone , kError };
155163
156164 static void ThreadCbIO (void * agent);
@@ -161,10 +169,13 @@ class AgentImpl {
161169 void WorkerRunIO ();
162170 void SetConnected (bool connected);
163171 void DispatchMessages ();
164- void Write (int session_id, const StringView& message);
165- bool AppendMessage (MessageQueue* vector, int session_id,
166- std::unique_ptr<StringBuffer> buffer);
167- void SwapBehindLock (MessageQueue* vector1, MessageQueue* vector2);
172+ void Write (TransportAction action, int session_id, const StringView& message);
173+ template <typename ActionType>
174+ bool AppendMessage (MessageQueue<ActionType>* vector, ActionType action,
175+ int session_id, std::unique_ptr<StringBuffer> buffer);
176+ template <typename ActionType>
177+ void SwapBehindLock (MessageQueue<ActionType>* vector1,
178+ MessageQueue<ActionType>* vector2);
168179 void WaitForFrontendMessage ();
169180 void NotifyMessageReceived ();
170181 State ToState (State state);
@@ -185,8 +196,8 @@ class AgentImpl {
185196 uv_async_t io_thread_req_;
186197 V8NodeInspector* inspector_;
187198 v8::Platform* platform_;
188- MessageQueue incoming_message_queue_;
189- MessageQueue outgoing_message_queue_;
199+ MessageQueue<InspectorAction> incoming_message_queue_;
200+ MessageQueue<TransportAction> outgoing_message_queue_;
190201 bool dispatching_messages_;
191202 int session_id_;
192203 InspectorSocketServer* server_;
@@ -236,7 +247,7 @@ class ChannelImpl final : public v8_inspector::V8Inspector::Channel {
236247 void flushProtocolNotifications () override { }
237248
238249 void sendMessageToFrontend (const StringView& message) {
239- agent_->Write (agent_->session_id_ , message);
250+ agent_->Write (TransportAction:: kSendMessage , agent_->session_id_ , message);
240251 }
241252
242253 AgentImpl* const agent_;
@@ -444,9 +455,7 @@ bool AgentImpl::IsStarted() {
444455void AgentImpl::WaitForDisconnect () {
445456 if (state_ == State::kConnected ) {
446457 shutting_down_ = true ;
447- // Gives a signal to stop accepting new connections
448- // TODO(eugeneo): Introduce an API with explicit request names.
449- Write (0 , StringView ());
458+ Write (TransportAction::kStop , 0 , StringView ());
450459 fprintf (stderr, " Waiting for the debugger to disconnect...\n " );
451460 fflush (stderr);
452461 inspector_->runMessageLoopOnPause (0 );
@@ -521,15 +530,17 @@ void AgentImpl::ThreadCbIO(void* agent) {
521530// static
522531void AgentImpl::WriteCbIO (uv_async_t * async) {
523532 AgentImpl* agent = static_cast <AgentImpl*>(async->data );
524- MessageQueue outgoing_messages;
533+ MessageQueue<TransportAction> outgoing_messages;
525534 agent->SwapBehindLock (&agent->outgoing_message_queue_ , &outgoing_messages);
526- for (const MessageQueue::value_type & outgoing : outgoing_messages) {
527- StringView view = outgoing. second -> string ();
528- if (view. length () == 0 ) {
535+ for (const auto & outgoing : outgoing_messages) {
536+ switch (std::get< 0 >(outgoing)) {
537+ case TransportAction:: kStop :
529538 agent->server_ ->Stop (nullptr );
530- } else {
531- agent->server_ ->Send (outgoing.first ,
532- StringViewToUtf8 (outgoing.second ->string ()));
539+ break ;
540+ case TransportAction::kSendMessage :
541+ std::string message = StringViewToUtf8 (std::get<2 >(outgoing)->string ());
542+ agent->server_ ->Send (std::get<1 >(outgoing), message);
543+ break ;
533544 }
534545 }
535546}
@@ -573,22 +584,26 @@ void AgentImpl::WorkerRunIO() {
573584 server_ = nullptr ;
574585}
575586
576- bool AgentImpl::AppendMessage (MessageQueue* queue, int session_id,
587+ template <typename ActionType>
588+ bool AgentImpl::AppendMessage (MessageQueue<ActionType>* queue,
589+ ActionType action, int session_id,
577590 std::unique_ptr<StringBuffer> buffer) {
578591 Mutex::ScopedLock scoped_lock (state_lock_);
579592 bool trigger_pumping = queue->empty ();
580- queue->push_back (std::make_pair ( session_id, std::move (buffer)));
593+ queue->push_back (std::make_tuple (action, session_id, std::move (buffer)));
581594 return trigger_pumping;
582595}
583596
584- void AgentImpl::SwapBehindLock (MessageQueue* vector1, MessageQueue* vector2) {
597+ template <typename ActionType>
598+ void AgentImpl::SwapBehindLock (MessageQueue<ActionType>* vector1,
599+ MessageQueue<ActionType>* vector2) {
585600 Mutex::ScopedLock scoped_lock (state_lock_);
586601 vector1->swap (*vector2);
587602}
588603
589- void AgentImpl::PostIncomingMessage (int session_id,
604+ void AgentImpl::PostIncomingMessage (InspectorAction action, int session_id,
590605 const std::string& message) {
591- if (AppendMessage (&incoming_message_queue_, session_id,
606+ if (AppendMessage (&incoming_message_queue_, action, session_id,
592607 Utf8ToStringView (message))) {
593608 v8::Isolate* isolate = parent_env_->isolate ();
594609 platform_->CallOnForegroundThread (isolate,
@@ -617,25 +632,21 @@ void AgentImpl::DispatchMessages() {
617632 if (dispatching_messages_)
618633 return ;
619634 dispatching_messages_ = true ;
620- MessageQueue tasks;
635+ MessageQueue<InspectorAction> tasks;
621636 do {
622637 tasks.clear ();
623638 SwapBehindLock (&incoming_message_queue_, &tasks);
624- for (const MessageQueue::value_type& pair : tasks) {
625- StringView message = pair.second ->string ();
626- std::string tag;
627- if (message.length () == sizeof (TAG_CONNECT) - 1 ||
628- message.length () == sizeof (TAG_DISCONNECT) - 1 ) {
629- tag = StringViewToUtf8 (message);
630- }
631-
632- if (tag == TAG_CONNECT) {
639+ for (const auto & task : tasks) {
640+ StringView message = std::get<2 >(task)->string ();
641+ switch (std::get<0 >(task)) {
642+ case InspectorAction::kStartSession :
633643 CHECK_EQ (State::kAccepting , state_);
634- session_id_ = pair. first ;
644+ session_id_ = std::get< 1 >(task) ;
635645 state_ = State::kConnected ;
636646 fprintf (stderr, " Debugger attached.\n " );
637647 inspector_->connectFrontend ();
638- } else if (tag == TAG_DISCONNECT) {
648+ break ;
649+ case InspectorAction::kEndSession :
639650 CHECK_EQ (State::kConnected , state_);
640651 if (shutting_down_) {
641652 state_ = State::kDone ;
@@ -644,16 +655,19 @@ void AgentImpl::DispatchMessages() {
644655 }
645656 inspector_->quitMessageLoopOnPause ();
646657 inspector_->disconnectFrontend ();
647- } else {
658+ break ;
659+ case InspectorAction::kSendMessage :
648660 inspector_->dispatchMessageFromFrontend (message);
661+ break ;
649662 }
650663 }
651664 } while (!tasks.empty ());
652665 dispatching_messages_ = false ;
653666}
654667
655- void AgentImpl::Write (int session_id, const StringView& inspector_message) {
656- AppendMessage (&outgoing_message_queue_, session_id,
668+ void AgentImpl::Write (TransportAction action, int session_id,
669+ const StringView& inspector_message) {
670+ AppendMessage (&outgoing_message_queue_, action, session_id,
657671 StringBuffer::create (inspector_message));
658672 int err = uv_async_send (&io_thread_req_);
659673 CHECK_EQ (0 , err);
@@ -710,7 +724,8 @@ bool InspectorAgentDelegate::StartSession(int session_id,
710724 if (connected_)
711725 return false ;
712726 connected_ = true ;
713- agent_->PostIncomingMessage (session_id, TAG_CONNECT);
727+ session_id_++;
728+ agent_->PostIncomingMessage (InspectorAction::kStartSession , session_id, " " );
714729 return true ;
715730}
716731
@@ -727,12 +742,13 @@ void InspectorAgentDelegate::MessageReceived(int session_id,
727742 agent_->ResumeStartup ();
728743 }
729744 }
730- agent_->PostIncomingMessage (session_id, message);
745+ agent_->PostIncomingMessage (InspectorAction::kSendMessage , session_id,
746+ message);
731747}
732748
733749void InspectorAgentDelegate::EndSession (int session_id) {
734750 connected_ = false ;
735- agent_->PostIncomingMessage (session_id, TAG_DISCONNECT );
751+ agent_->PostIncomingMessage (InspectorAction:: kEndSession , session_id, " " );
736752}
737753
738754std::vector<std::string> InspectorAgentDelegate::GetTargetIds () {
0 commit comments