From 9e244ac7254cc0178046c95177909ed3c0b11171 Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Wed, 22 Jun 2022 21:07:31 +0200 Subject: [PATCH 1/3] Trigger the event loop semaphore at the right time This should prevent the hidden window on Windows from getting spammed, and also prevent qode from entering this weird "slow down" state. --- qode/integration/node_integration.cc | 10 +++++----- qode/integration/node_integration_win.cc | 7 ++++++- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/qode/integration/node_integration.cc b/qode/integration/node_integration.cc index 2bce33dc30d17a..75a021eedfbba8 100644 --- a/qode/integration/node_integration.cc +++ b/qode/integration/node_integration.cc @@ -63,9 +63,6 @@ void NodeIntegration::UvRunOnce() { // Deal with uv events. uv_run(uv_loop_, UV_RUN_NOWAIT); - - // Tell the worker thread to continue polling. - uv_sem_post(&embed_sem_); } void NodeIntegration::CallNextTick() { @@ -79,6 +76,8 @@ void NodeIntegration::ReleaseHandleRef() { void NodeIntegration::WakeupMainThread() { PostTask([this] { this->UvRunOnce(); + // Tell the worker thread to continue polling. + uv_sem_post(&this->embed_sem_); }); } @@ -91,8 +90,6 @@ void NodeIntegration::EmbedThreadRunner(void *arg) { NodeIntegration* self = static_cast(arg); while (true) { - // Wait for the main loop to deal with events. - uv_sem_wait(&self->embed_sem_); if (self->embed_closed_) break; @@ -113,6 +110,9 @@ void NodeIntegration::EmbedThreadRunner(void *arg) { // Deal with event in main thread. self->WakeupMainThread(); + + // Wait for the main loop to deal with events. + uv_sem_wait(&self->embed_sem_); } } diff --git a/qode/integration/node_integration_win.cc b/qode/integration/node_integration_win.cc index 9b05707c7efbfb..ad5c18748d6eeb 100644 --- a/qode/integration/node_integration_win.cc +++ b/qode/integration/node_integration_win.cc @@ -4,6 +4,7 @@ #include "qode/integration/node_integration_win.h" #include "uv/src/uv-common.h" +#include // http://blogs.msdn.com/oldnewthing/archive/2004/10/25/247180.aspx extern "C" IMAGE_DOS_HEADER __ImageBase; @@ -70,7 +71,11 @@ void NodeIntegrationWin::PostTask(const std::function& task) { ::EnterCriticalSection(&lock_); tasks_[++task_id_] = task; ::LeaveCriticalSection(&lock_); - ::PostMessage(message_window_, WM_USER, task_id_, 0L); + BOOL result = ::PostMessage(message_window_, WM_USER, task_id_, 0L); + if (result == 0) { + int lastError = ::GetLastError(); + fprintf(stderr, "Qode: PostMessage() failed! LastError=%d\n", lastError); + } } void NodeIntegrationWin::OnTask(int id) { From 2325dc3c36b3ea963745c3fc9ee798221d6a5fcf Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Fri, 24 Jun 2022 20:22:38 +0200 Subject: [PATCH 2/3] Speed up I/O processing by processing batches of events --- qode/integration/node_integration.cc | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/qode/integration/node_integration.cc b/qode/integration/node_integration.cc index 75a021eedfbba8..95f6bfaf83814c 100644 --- a/qode/integration/node_integration.cc +++ b/qode/integration/node_integration.cc @@ -19,6 +19,9 @@ NodeIntegration::NodeIntegration() embed_closed_(false) { } +constexpr uint64_t EVENT_BATCH_TIMEOUT_MS = 8; +constexpr int EVENT_BATCH_SIZE = 64; + NodeIntegration::~NodeIntegration() { // Quit the embed thread. embed_closed_ = true; @@ -76,6 +79,17 @@ void NodeIntegration::ReleaseHandleRef() { void NodeIntegration::WakeupMainThread() { PostTask([this] { this->UvRunOnce(); + // ^ This also updates the uv_now() timestamp. + uint64_t start_time_ms = uv_now(uv_loop_); + + int loop_count = EVENT_BATCH_SIZE; + uint64_t elapsed_ms = 0; + while (loop_count != 0 && (elapsed_ms < EVENT_BATCH_TIMEOUT_MS)) { + loop_count--; + this->UvRunOnce(); + elapsed_ms = uv_now(uv_loop_) - start_time_ms; + } + // Tell the worker thread to continue polling. uv_sem_post(&this->embed_sem_); }); From 41c633ce1e0c2ef60efc30eb9625140a6e5df9cd Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Fri, 24 Jun 2022 22:08:53 +0200 Subject: [PATCH 3/3] Tweak the size of a batch of uv_run() calls --- qode/integration/node_integration.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qode/integration/node_integration.cc b/qode/integration/node_integration.cc index 95f6bfaf83814c..f08b080d54dfbb 100644 --- a/qode/integration/node_integration.cc +++ b/qode/integration/node_integration.cc @@ -20,7 +20,7 @@ NodeIntegration::NodeIntegration() } constexpr uint64_t EVENT_BATCH_TIMEOUT_MS = 8; -constexpr int EVENT_BATCH_SIZE = 64; +constexpr int EVENT_BATCH_SIZE = 16; NodeIntegration::~NodeIntegration() { // Quit the embed thread.