16
16
17
17
#include < map>
18
18
#include < sstream>
19
+ #include < tuple>
19
20
#include < unicode/unistr.h>
20
21
21
22
#include < string.h>
@@ -30,9 +31,6 @@ namespace {
30
31
using v8_inspector::StringBuffer;
31
32
using v8_inspector::StringView;
32
33
33
- const char TAG_CONNECT[] = " #connect" ;
34
- const char TAG_DISCONNECT[] = " #disconnect" ;
35
-
36
34
static const uint8_t PROTOCOL_JSON[] = {
37
35
#include " v8_inspector_protocol_json.h" // NOLINT(build/include_order)
38
36
};
@@ -105,6 +103,14 @@ std::unique_ptr<StringBuffer> Utf8ToStringView(const std::string& message) {
105
103
106
104
class V8NodeInspector ;
107
105
106
+ enum class InspectorAction {
107
+ kStartSession , kEndSession , kSendMessage
108
+ };
109
+
110
+ enum class TransportAction {
111
+ kSendMessage , kStop
112
+ };
113
+
108
114
class InspectorAgentDelegate : public node ::inspector::SocketServerDelegate {
109
115
public:
110
116
InspectorAgentDelegate (AgentImpl* agent, const std::string& script_path,
@@ -144,14 +150,16 @@ class AgentImpl {
144
150
void FatalException (v8::Local<v8::Value> error,
145
151
v8::Local<v8::Message> message);
146
152
147
- void PostIncomingMessage (int session_id, const std::string& message);
153
+ void PostIncomingMessage (InspectorAction action, int session_id,
154
+ const std::string& message);
148
155
void ResumeStartup () {
149
156
uv_sem_post (&start_sem_);
150
157
}
151
158
152
159
private:
160
+ template <typename Action>
153
161
using MessageQueue =
154
- std::vector<std::pair< int , std::unique_ptr<StringBuffer>>>;
162
+ std::vector<std::tuple<Action, int , std::unique_ptr<StringBuffer>>>;
155
163
enum class State { kNew , kAccepting , kConnected , kDone , kError };
156
164
157
165
static void ThreadCbIO (void * agent);
@@ -162,10 +170,13 @@ class AgentImpl {
162
170
void WorkerRunIO ();
163
171
void SetConnected (bool connected);
164
172
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);
169
180
void WaitForFrontendMessage ();
170
181
void NotifyMessageReceived ();
171
182
State ToState (State state);
@@ -187,8 +198,8 @@ class AgentImpl {
187
198
uv_async_t io_thread_req_;
188
199
V8NodeInspector* inspector_;
189
200
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_;
192
203
bool dispatching_messages_;
193
204
int session_id_;
194
205
InspectorSocketServer* server_;
@@ -238,7 +249,7 @@ class ChannelImpl final : public v8_inspector::V8Inspector::Channel {
238
249
void flushProtocolNotifications () override { }
239
250
240
251
void sendMessageToFrontend (const StringView& message) {
241
- agent_->Write (agent_->session_id_ , message);
252
+ agent_->Write (TransportAction:: kSendMessage , agent_->session_id_ , message);
242
253
}
243
254
244
255
AgentImpl* const agent_;
@@ -457,9 +468,7 @@ bool AgentImpl::IsStarted() {
457
468
void AgentImpl::WaitForDisconnect () {
458
469
if (state_ == State::kConnected ) {
459
470
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 ());
463
472
fprintf (stderr, " Waiting for the debugger to disconnect...\n " );
464
473
fflush (stderr);
465
474
inspector_->runMessageLoopOnPause (0 );
@@ -534,15 +543,17 @@ void AgentImpl::ThreadCbIO(void* agent) {
534
543
// static
535
544
void AgentImpl::WriteCbIO (uv_async_t * async) {
536
545
AgentImpl* agent = static_cast <AgentImpl*>(async->data );
537
- MessageQueue outgoing_messages;
546
+ MessageQueue<TransportAction> outgoing_messages;
538
547
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 :
542
551
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 ;
546
557
}
547
558
}
548
559
}
@@ -586,22 +597,26 @@ void AgentImpl::WorkerRunIO() {
586
597
server_ = nullptr ;
587
598
}
588
599
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,
590
603
std::unique_ptr<StringBuffer> buffer) {
591
604
Mutex::ScopedLock scoped_lock (state_lock_);
592
605
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)));
594
607
return trigger_pumping;
595
608
}
596
609
597
- void AgentImpl::SwapBehindLock (MessageQueue* vector1, MessageQueue* vector2) {
610
+ template <typename ActionType>
611
+ void AgentImpl::SwapBehindLock (MessageQueue<ActionType>* vector1,
612
+ MessageQueue<ActionType>* vector2) {
598
613
Mutex::ScopedLock scoped_lock (state_lock_);
599
614
vector1->swap (*vector2);
600
615
}
601
616
602
- void AgentImpl::PostIncomingMessage (int session_id,
617
+ void AgentImpl::PostIncomingMessage (InspectorAction action, int session_id,
603
618
const std::string& message) {
604
- if (AppendMessage (&incoming_message_queue_, session_id,
619
+ if (AppendMessage (&incoming_message_queue_, action, session_id,
605
620
Utf8ToStringView (message))) {
606
621
v8::Isolate* isolate = parent_env_->isolate ();
607
622
platform_->CallOnForegroundThread (isolate,
@@ -631,25 +646,21 @@ void AgentImpl::DispatchMessages() {
631
646
if (dispatching_messages_)
632
647
return ;
633
648
dispatching_messages_ = true ;
634
- MessageQueue tasks;
649
+ MessageQueue<InspectorAction> tasks;
635
650
do {
636
651
tasks.clear ();
637
652
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 :
647
657
CHECK_EQ (State::kAccepting , state_);
648
- session_id_ = pair. first ;
658
+ session_id_ = std::get< 1 >(task) ;
649
659
state_ = State::kConnected ;
650
660
fprintf (stderr, " Debugger attached.\n " );
651
661
inspector_->connectFrontend ();
652
- } else if (tag == TAG_DISCONNECT) {
662
+ break ;
663
+ case InspectorAction::kEndSession :
653
664
CHECK_EQ (State::kConnected , state_);
654
665
if (shutting_down_) {
655
666
state_ = State::kDone ;
@@ -658,17 +669,20 @@ void AgentImpl::DispatchMessages() {
658
669
}
659
670
inspector_->quitMessageLoopOnPause ();
660
671
inspector_->disconnectFrontend ();
661
- } else {
672
+ break ;
673
+ case InspectorAction::kSendMessage :
662
674
inspector_->dispatchMessageFromFrontend (message);
675
+ break ;
663
676
}
664
677
}
665
678
} while (!tasks.empty ());
666
679
uv_async_send (data_written_);
667
680
dispatching_messages_ = false ;
668
681
}
669
682
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,
672
686
StringBuffer::create (inspector_message));
673
687
int err = uv_async_send (&io_thread_req_);
674
688
CHECK_EQ (0 , err);
@@ -725,7 +739,8 @@ bool InspectorAgentDelegate::StartSession(int session_id,
725
739
if (connected_)
726
740
return false ;
727
741
connected_ = true ;
728
- agent_->PostIncomingMessage (session_id, TAG_CONNECT);
742
+ session_id_++;
743
+ agent_->PostIncomingMessage (InspectorAction::kStartSession , session_id, " " );
729
744
return true ;
730
745
}
731
746
@@ -742,12 +757,13 @@ void InspectorAgentDelegate::MessageReceived(int session_id,
742
757
agent_->ResumeStartup ();
743
758
}
744
759
}
745
- agent_->PostIncomingMessage (session_id, message);
760
+ agent_->PostIncomingMessage (InspectorAction::kSendMessage , session_id,
761
+ message);
746
762
}
747
763
748
764
void InspectorAgentDelegate::EndSession (int session_id) {
749
765
connected_ = false ;
750
- agent_->PostIncomingMessage (session_id, TAG_DISCONNECT );
766
+ agent_->PostIncomingMessage (InspectorAction:: kEndSession , session_id, " " );
751
767
}
752
768
753
769
std::vector<std::string> InspectorAgentDelegate::GetTargetIds () {
0 commit comments