diff --git a/src/node_messaging.cc b/src/node_messaging.cc index 2dcfb4736d7c3f..19065fdb7d1be5 100644 --- a/src/node_messaging.cc +++ b/src/node_messaging.cc @@ -604,10 +604,11 @@ void MessagePort::OnMessage() { HandleScope handle_scope(env()->isolate()); Local context = object(env()->isolate())->CreationContext(); - ssize_t processing_limit; + size_t processing_limit; { Mutex::ScopedLock(data_->mutex_); - processing_limit = data_->incoming_messages_.size(); + processing_limit = std::max(data_->incoming_messages_.size(), + static_cast(1000)); } // data_ can only ever be modified by the owner thread, so no need to lock. @@ -615,10 +616,14 @@ void MessagePort::OnMessage() { // messages, so we need to check that this handle still owns its `data_` field // on every iteration. while (data_) { - if (--processing_limit < 0) { + if (processing_limit-- == 0) { // Prevent event loop starvation by only processing those messages without // interruption that were already present when the OnMessage() call was - // first triggered. + // first triggered, but at least 1000 messages because otherwise the + // overhead of repeatedly triggering the uv_async_t instance becomes + // noticable, at least on Windows. + // (That might require more investigation by somebody more familiar with + // Windows.) TriggerAsync(); return; } diff --git a/test/parallel/test-worker-message-port-infinite-message-loop.js b/test/parallel/test-worker-message-port-infinite-message-loop.js index 972f91ab1586d0..640b3383ca62c3 100644 --- a/test/parallel/test-worker-message-port-infinite-message-loop.js +++ b/test/parallel/test-worker-message-port-infinite-message-loop.js @@ -24,4 +24,6 @@ port1.on('message', () => { port2.postMessage(0); +// This is part of the test -- the event loop should be available and not stall +// out due to the recursive .postMessage() calls. setTimeout(common.mustCall(), 0);