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,
@@ -143,14 +149,16 @@ class AgentImpl {
143
149
void FatalException (v8::Local<v8::Value> error,
144
150
v8::Local<v8::Message> message);
145
151
146
- void PostIncomingMessage (int session_id, const std::string& message);
152
+ void PostIncomingMessage (InspectorAction action, int session_id,
153
+ const std::string& message);
147
154
void ResumeStartup () {
148
155
uv_sem_post (&start_sem_);
149
156
}
150
157
151
158
private:
159
+ template <typename Action>
152
160
using MessageQueue =
153
- std::vector<std::pair< int , std::unique_ptr<StringBuffer>>>;
161
+ std::vector<std::tuple<Action, int , std::unique_ptr<StringBuffer>>>;
154
162
enum class State { kNew , kAccepting , kConnected , kDone , kError };
155
163
156
164
static void ThreadCbIO (void * agent);
@@ -161,10 +169,13 @@ class AgentImpl {
161
169
void WorkerRunIO ();
162
170
void SetConnected (bool connected);
163
171
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);
168
179
void WaitForFrontendMessage ();
169
180
void NotifyMessageReceived ();
170
181
State ToState (State state);
@@ -185,8 +196,8 @@ class AgentImpl {
185
196
uv_async_t io_thread_req_;
186
197
V8NodeInspector* inspector_;
187
198
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_;
190
201
bool dispatching_messages_;
191
202
int session_id_;
192
203
InspectorSocketServer* server_;
@@ -236,7 +247,7 @@ class ChannelImpl final : public v8_inspector::V8Inspector::Channel {
236
247
void flushProtocolNotifications () override { }
237
248
238
249
void sendMessageToFrontend (const StringView& message) {
239
- agent_->Write (agent_->session_id_ , message);
250
+ agent_->Write (TransportAction:: kSendMessage , agent_->session_id_ , message);
240
251
}
241
252
242
253
AgentImpl* const agent_;
@@ -444,9 +455,7 @@ bool AgentImpl::IsStarted() {
444
455
void AgentImpl::WaitForDisconnect () {
445
456
if (state_ == State::kConnected ) {
446
457
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 ());
450
459
fprintf (stderr, " Waiting for the debugger to disconnect...\n " );
451
460
fflush (stderr);
452
461
inspector_->runMessageLoopOnPause (0 );
@@ -521,15 +530,17 @@ void AgentImpl::ThreadCbIO(void* agent) {
521
530
// static
522
531
void AgentImpl::WriteCbIO (uv_async_t * async) {
523
532
AgentImpl* agent = static_cast <AgentImpl*>(async->data );
524
- MessageQueue outgoing_messages;
533
+ MessageQueue<TransportAction> outgoing_messages;
525
534
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 :
529
538
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 ;
533
544
}
534
545
}
535
546
}
@@ -573,22 +584,26 @@ void AgentImpl::WorkerRunIO() {
573
584
server_ = nullptr ;
574
585
}
575
586
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,
577
590
std::unique_ptr<StringBuffer> buffer) {
578
591
Mutex::ScopedLock scoped_lock (state_lock_);
579
592
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)));
581
594
return trigger_pumping;
582
595
}
583
596
584
- void AgentImpl::SwapBehindLock (MessageQueue* vector1, MessageQueue* vector2) {
597
+ template <typename ActionType>
598
+ void AgentImpl::SwapBehindLock (MessageQueue<ActionType>* vector1,
599
+ MessageQueue<ActionType>* vector2) {
585
600
Mutex::ScopedLock scoped_lock (state_lock_);
586
601
vector1->swap (*vector2);
587
602
}
588
603
589
- void AgentImpl::PostIncomingMessage (int session_id,
604
+ void AgentImpl::PostIncomingMessage (InspectorAction action, int session_id,
590
605
const std::string& message) {
591
- if (AppendMessage (&incoming_message_queue_, session_id,
606
+ if (AppendMessage (&incoming_message_queue_, action, session_id,
592
607
Utf8ToStringView (message))) {
593
608
v8::Isolate* isolate = parent_env_->isolate ();
594
609
platform_->CallOnForegroundThread (isolate,
@@ -617,25 +632,21 @@ void AgentImpl::DispatchMessages() {
617
632
if (dispatching_messages_)
618
633
return ;
619
634
dispatching_messages_ = true ;
620
- MessageQueue tasks;
635
+ MessageQueue<InspectorAction> tasks;
621
636
do {
622
637
tasks.clear ();
623
638
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 :
633
643
CHECK_EQ (State::kAccepting , state_);
634
- session_id_ = pair. first ;
644
+ session_id_ = std::get< 1 >(task) ;
635
645
state_ = State::kConnected ;
636
646
fprintf (stderr, " Debugger attached.\n " );
637
647
inspector_->connectFrontend ();
638
- } else if (tag == TAG_DISCONNECT) {
648
+ break ;
649
+ case InspectorAction::kEndSession :
639
650
CHECK_EQ (State::kConnected , state_);
640
651
if (shutting_down_) {
641
652
state_ = State::kDone ;
@@ -644,16 +655,19 @@ void AgentImpl::DispatchMessages() {
644
655
}
645
656
inspector_->quitMessageLoopOnPause ();
646
657
inspector_->disconnectFrontend ();
647
- } else {
658
+ break ;
659
+ case InspectorAction::kSendMessage :
648
660
inspector_->dispatchMessageFromFrontend (message);
661
+ break ;
649
662
}
650
663
}
651
664
} while (!tasks.empty ());
652
665
dispatching_messages_ = false ;
653
666
}
654
667
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,
657
671
StringBuffer::create (inspector_message));
658
672
int err = uv_async_send (&io_thread_req_);
659
673
CHECK_EQ (0 , err);
@@ -710,7 +724,8 @@ bool InspectorAgentDelegate::StartSession(int session_id,
710
724
if (connected_)
711
725
return false ;
712
726
connected_ = true ;
713
- agent_->PostIncomingMessage (session_id, TAG_CONNECT);
727
+ session_id_++;
728
+ agent_->PostIncomingMessage (InspectorAction::kStartSession , session_id, " " );
714
729
return true ;
715
730
}
716
731
@@ -727,12 +742,13 @@ void InspectorAgentDelegate::MessageReceived(int session_id,
727
742
agent_->ResumeStartup ();
728
743
}
729
744
}
730
- agent_->PostIncomingMessage (session_id, message);
745
+ agent_->PostIncomingMessage (InspectorAction::kSendMessage , session_id,
746
+ message);
731
747
}
732
748
733
749
void InspectorAgentDelegate::EndSession (int session_id) {
734
750
connected_ = false ;
735
- agent_->PostIncomingMessage (session_id, TAG_DISCONNECT );
751
+ agent_->PostIncomingMessage (InspectorAction:: kEndSession , session_id, " " );
736
752
}
737
753
738
754
std::vector<std::string> InspectorAgentDelegate::GetTargetIds () {
0 commit comments