diff --git a/qode/integration/node_integration.cc b/qode/integration/node_integration.cc index 2bce33dc30d17a..f08b080d54dfbb 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 = 16; + NodeIntegration::~NodeIntegration() { // Quit the embed thread. embed_closed_ = true; @@ -63,9 +66,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 +79,19 @@ 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_); }); } @@ -91,8 +104,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 +124,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) {