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,
@@ -144,14 +150,16 @@ class AgentImpl {
144150 void FatalException (v8::Local<v8::Value> error,
145151 v8::Local<v8::Message> message);
146152
147- void PostIncomingMessage (int session_id, const std::string& message);
153+ void PostIncomingMessage (InspectorAction action, int session_id,
154+ const std::string& message);
148155 void ResumeStartup () {
149156 uv_sem_post (&start_sem_);
150157 }
151158
152159 private:
160+ template <typename Action>
153161 using MessageQueue =
154- std::vector<std::pair< int , std::unique_ptr<StringBuffer>>>;
162+ std::vector<std::tuple<Action, int , std::unique_ptr<StringBuffer>>>;
155163 enum class State { kNew , kAccepting , kConnected , kDone , kError };
156164
157165 static void ThreadCbIO (void * agent);
@@ -162,10 +170,13 @@ class AgentImpl {
162170 void WorkerRunIO ();
163171 void SetConnected (bool connected);
164172 void DispatchMessages ();
165- void Write (int session_id, const StringView& message);
166- bool AppendMessage (MessageQueue* vector, int session_id,
167- std::unique_ptr<StringBuffer> buffer);
168- void SwapBehindLock (MessageQueue* vector1, MessageQueue* vector2);
173+ void Write (TransportAction action, int session_id, const StringView& message);
174+ template <typename ActionType>
175+ bool AppendMessage (MessageQueue<ActionType>* vector, ActionType action,
176+ int session_id, std::unique_ptr<StringBuffer> buffer);
177+ template <typename ActionType>
178+ void SwapBehindLock (MessageQueue<ActionType>* vector1,
179+ MessageQueue<ActionType>* vector2);
169180 void WaitForFrontendMessage ();
170181 void NotifyMessageReceived ();
171182 State ToState (State state);
@@ -187,8 +198,8 @@ class AgentImpl {
187198 uv_async_t io_thread_req_;
188199 V8NodeInspector* inspector_;
189200 v8::Platform* platform_;
190- MessageQueue incoming_message_queue_;
191- MessageQueue outgoing_message_queue_;
201+ MessageQueue<InspectorAction> incoming_message_queue_;
202+ MessageQueue<TransportAction> outgoing_message_queue_;
192203 bool dispatching_messages_;
193204 int session_id_;
194205 InspectorSocketServer* server_;
@@ -238,7 +249,7 @@ class ChannelImpl final : public v8_inspector::V8Inspector::Channel {
238249 void flushProtocolNotifications () override { }
239250
240251 void sendMessageToFrontend (const StringView& message) {
241- agent_->Write (agent_->session_id_ , message);
252+ agent_->Write (TransportAction:: kSendMessage , agent_->session_id_ , message);
242253 }
243254
244255 AgentImpl* const agent_;
@@ -457,9 +468,7 @@ bool AgentImpl::IsStarted() {
457468void AgentImpl::WaitForDisconnect () {
458469 if (state_ == State::kConnected ) {
459470 shutting_down_ = true ;
460- // Gives a signal to stop accepting new connections
461- // TODO(eugeneo): Introduce an API with explicit request names.
462- Write (0 , StringView ());
471+ Write (TransportAction::kStop , 0 , StringView ());
463472 fprintf (stderr, " Waiting for the debugger to disconnect...\n " );
464473 fflush (stderr);
465474 inspector_->runMessageLoopOnPause (0 );
@@ -534,15 +543,17 @@ void AgentImpl::ThreadCbIO(void* agent) {
534543// static
535544void AgentImpl::WriteCbIO (uv_async_t * async) {
536545 AgentImpl* agent = static_cast <AgentImpl*>(async->data );
537- MessageQueue outgoing_messages;
546+ MessageQueue<TransportAction> outgoing_messages;
538547 agent->SwapBehindLock (&agent->outgoing_message_queue_ , &outgoing_messages);
539- for (const MessageQueue::value_type & outgoing : outgoing_messages) {
540- StringView view = outgoing. second -> string ();
541- if (view. length () == 0 ) {
548+ for (const auto & outgoing : outgoing_messages) {
549+ switch (std::get< 0 >(outgoing)) {
550+ case TransportAction:: kStop :
542551 agent->server_ ->Stop (nullptr );
543- } else {
544- agent->server_ ->Send (outgoing.first ,
545- StringViewToUtf8 (outgoing.second ->string ()));
552+ break ;
553+ case TransportAction::kSendMessage :
554+ std::string message = StringViewToUtf8 (std::get<2 >(outgoing)->string ());
555+ agent->server_ ->Send (std::get<1 >(outgoing), message);
556+ break ;
546557 }
547558 }
548559}
@@ -586,22 +597,26 @@ void AgentImpl::WorkerRunIO() {
586597 server_ = nullptr ;
587598}
588599
589- bool AgentImpl::AppendMessage (MessageQueue* queue, int session_id,
600+ template <typename ActionType>
601+ bool AgentImpl::AppendMessage (MessageQueue<ActionType>* queue,
602+ ActionType action, int session_id,
590603 std::unique_ptr<StringBuffer> buffer) {
591604 Mutex::ScopedLock scoped_lock (state_lock_);
592605 bool trigger_pumping = queue->empty ();
593- queue->push_back (std::make_pair ( session_id, std::move (buffer)));
606+ queue->push_back (std::make_tuple (action, session_id, std::move (buffer)));
594607 return trigger_pumping;
595608}
596609
597- void AgentImpl::SwapBehindLock (MessageQueue* vector1, MessageQueue* vector2) {
610+ template <typename ActionType>
611+ void AgentImpl::SwapBehindLock (MessageQueue<ActionType>* vector1,
612+ MessageQueue<ActionType>* vector2) {
598613 Mutex::ScopedLock scoped_lock (state_lock_);
599614 vector1->swap (*vector2);
600615}
601616
602- void AgentImpl::PostIncomingMessage (int session_id,
617+ void AgentImpl::PostIncomingMessage (InspectorAction action, int session_id,
603618 const std::string& message) {
604- if (AppendMessage (&incoming_message_queue_, session_id,
619+ if (AppendMessage (&incoming_message_queue_, action, session_id,
605620 Utf8ToStringView (message))) {
606621 v8::Isolate* isolate = parent_env_->isolate ();
607622 platform_->CallOnForegroundThread (isolate,
@@ -631,25 +646,21 @@ void AgentImpl::DispatchMessages() {
631646 if (dispatching_messages_)
632647 return ;
633648 dispatching_messages_ = true ;
634- MessageQueue tasks;
649+ MessageQueue<InspectorAction> tasks;
635650 do {
636651 tasks.clear ();
637652 SwapBehindLock (&incoming_message_queue_, &tasks);
638- for (const MessageQueue::value_type& pair : tasks) {
639- StringView message = pair.second ->string ();
640- std::string tag;
641- if (message.length () == sizeof (TAG_CONNECT) - 1 ||
642- message.length () == sizeof (TAG_DISCONNECT) - 1 ) {
643- tag = StringViewToUtf8 (message);
644- }
645-
646- if (tag == TAG_CONNECT) {
653+ for (const auto & task : tasks) {
654+ StringView message = std::get<2 >(task)->string ();
655+ switch (std::get<0 >(task)) {
656+ case InspectorAction::kStartSession :
647657 CHECK_EQ (State::kAccepting , state_);
648- session_id_ = pair. first ;
658+ session_id_ = std::get< 1 >(task) ;
649659 state_ = State::kConnected ;
650660 fprintf (stderr, " Debugger attached.\n " );
651661 inspector_->connectFrontend ();
652- } else if (tag == TAG_DISCONNECT) {
662+ break ;
663+ case InspectorAction::kEndSession :
653664 CHECK_EQ (State::kConnected , state_);
654665 if (shutting_down_) {
655666 state_ = State::kDone ;
@@ -658,17 +669,20 @@ void AgentImpl::DispatchMessages() {
658669 }
659670 inspector_->quitMessageLoopOnPause ();
660671 inspector_->disconnectFrontend ();
661- } else {
672+ break ;
673+ case InspectorAction::kSendMessage :
662674 inspector_->dispatchMessageFromFrontend (message);
675+ break ;
663676 }
664677 }
665678 } while (!tasks.empty ());
666679 uv_async_send (data_written_);
667680 dispatching_messages_ = false ;
668681}
669682
670- void AgentImpl::Write (int session_id, const StringView& inspector_message) {
671- AppendMessage (&outgoing_message_queue_, session_id,
683+ void AgentImpl::Write (TransportAction action, int session_id,
684+ const StringView& inspector_message) {
685+ AppendMessage (&outgoing_message_queue_, action, session_id,
672686 StringBuffer::create (inspector_message));
673687 int err = uv_async_send (&io_thread_req_);
674688 CHECK_EQ (0 , err);
@@ -725,7 +739,8 @@ bool InspectorAgentDelegate::StartSession(int session_id,
725739 if (connected_)
726740 return false ;
727741 connected_ = true ;
728- agent_->PostIncomingMessage (session_id, TAG_CONNECT);
742+ session_id_++;
743+ agent_->PostIncomingMessage (InspectorAction::kStartSession , session_id, " " );
729744 return true ;
730745}
731746
@@ -742,12 +757,13 @@ void InspectorAgentDelegate::MessageReceived(int session_id,
742757 agent_->ResumeStartup ();
743758 }
744759 }
745- agent_->PostIncomingMessage (session_id, message);
760+ agent_->PostIncomingMessage (InspectorAction::kSendMessage , session_id,
761+ message);
746762}
747763
748764void InspectorAgentDelegate::EndSession (int session_id) {
749765 connected_ = false ;
750- agent_->PostIncomingMessage (session_id, TAG_DISCONNECT );
766+ agent_->PostIncomingMessage (InspectorAction:: kEndSession , session_id, " " );
751767}
752768
753769std::vector<std::string> InspectorAgentDelegate::GetTargetIds () {
0 commit comments