Skip to content

Commit 27fd2d7

Browse files
Eugene Ostroukhovofrobots
Eugene Ostroukhov
authored andcommitted
inspector: make sure all messages are dispatched
This fixes a race condition when messages are coming while V8 is still dispatching the previous batch. PR-URL: #8264 Reviewed-By: bnoordhuis - Ben Noordhuis <[email protected]>
1 parent b6db963 commit 27fd2d7

File tree

1 file changed

+38
-28
lines changed

1 file changed

+38
-28
lines changed

src/inspector_agent.cc

+38-28
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ class AgentImpl {
197197
void SetConnected(bool connected);
198198
void DispatchMessages();
199199
void Write(int session_id, const String16& message);
200-
void AppendMessage(MessageQueue* vector, int session_id,
200+
bool AppendMessage(MessageQueue* vector, int session_id,
201201
const String16& message);
202202
void SwapBehindLock(MessageQueue* vector1, MessageQueue* vector2);
203203
void PostIncomingMessage(const String16& message);
@@ -666,10 +666,12 @@ void AgentImpl::WorkerRunIO() {
666666
CHECK_EQ(err, 0);
667667
}
668668

669-
void AgentImpl::AppendMessage(MessageQueue* queue, int session_id,
669+
bool AgentImpl::AppendMessage(MessageQueue* queue, int session_id,
670670
const String16& message) {
671671
Mutex::ScopedLock scoped_lock(queue_lock_);
672+
bool trigger_pumping = queue->empty();
672673
queue->push_back(std::make_pair(session_id, message));
674+
return trigger_pumping;
673675
}
674676

675677
void AgentImpl::SwapBehindLock(MessageQueue* vector1, MessageQueue* vector2) {
@@ -678,12 +680,13 @@ void AgentImpl::SwapBehindLock(MessageQueue* vector1, MessageQueue* vector2) {
678680
}
679681

680682
void AgentImpl::PostIncomingMessage(const String16& message) {
681-
AppendMessage(&incoming_message_queue_, frontend_session_id_, message);
682-
v8::Isolate* isolate = parent_env_->isolate();
683-
platform_->CallOnForegroundThread(isolate,
684-
new DispatchOnInspectorBackendTask(this));
685-
isolate->RequestInterrupt(InterruptCallback, this);
686-
uv_async_send(data_written_);
683+
if (AppendMessage(&incoming_message_queue_, frontend_session_id_, message)) {
684+
v8::Isolate* isolate = parent_env_->isolate();
685+
platform_->CallOnForegroundThread(isolate,
686+
new DispatchOnInspectorBackendTask(this));
687+
isolate->RequestInterrupt(InterruptCallback, this);
688+
uv_async_send(data_written_);
689+
}
687690
}
688691

689692
void AgentImpl::OnInspectorConnectionIO(inspector_socket_t* socket) {
@@ -698,33 +701,40 @@ void AgentImpl::OnInspectorConnectionIO(inspector_socket_t* socket) {
698701
}
699702

700703
void AgentImpl::DispatchMessages() {
704+
// This function can be reentered if there was an incoming message while
705+
// V8 was processing another inspector request (e.g. if the user is
706+
// evaluating a long-running JS code snippet). This can happen only at
707+
// specific points (e.g. the lines that call inspector_ methods)
701708
if (dispatching_messages_)
702709
return;
703710
dispatching_messages_ = true;
704711
MessageQueue tasks;
705-
SwapBehindLock(&incoming_message_queue_, &tasks);
706-
for (const MessageQueue::value_type& pair : tasks) {
707-
const String16& message = pair.second;
708-
if (message == TAG_CONNECT) {
709-
CHECK_EQ(State::kAccepting, state_);
710-
backend_session_id_++;
711-
state_ = State::kConnected;
712-
fprintf(stderr, "Debugger attached.\n");
713-
inspector_->connectFrontend();
714-
} else if (message == TAG_DISCONNECT) {
715-
CHECK_EQ(State::kConnected, state_);
716-
if (shutting_down_) {
717-
state_ = State::kDone;
712+
do {
713+
tasks.clear();
714+
SwapBehindLock(&incoming_message_queue_, &tasks);
715+
for (const MessageQueue::value_type& pair : tasks) {
716+
const String16& message = pair.second;
717+
if (message == TAG_CONNECT) {
718+
CHECK_EQ(State::kAccepting, state_);
719+
backend_session_id_++;
720+
state_ = State::kConnected;
721+
fprintf(stderr, "Debugger attached.\n");
722+
inspector_->connectFrontend();
723+
} else if (message == TAG_DISCONNECT) {
724+
CHECK_EQ(State::kConnected, state_);
725+
if (shutting_down_) {
726+
state_ = State::kDone;
727+
} else {
728+
PrintDebuggerReadyMessage(port_);
729+
state_ = State::kAccepting;
730+
}
731+
inspector_->quitMessageLoopOnPause();
732+
inspector_->disconnectFrontend();
718733
} else {
719-
PrintDebuggerReadyMessage(port_);
720-
state_ = State::kAccepting;
734+
inspector_->dispatchMessageFromFrontend(message);
721735
}
722-
inspector_->quitMessageLoopOnPause();
723-
inspector_->disconnectFrontend();
724-
} else {
725-
inspector_->dispatchMessageFromFrontend(message);
726736
}
727-
}
737+
} while (!tasks.empty());
728738
uv_async_send(data_written_);
729739
dispatching_messages_ = false;
730740
}

0 commit comments

Comments
 (0)