-
Notifications
You must be signed in to change notification settings - Fork 13
Trigger the event loop semaphore at the right time #6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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<NodeIntegration*>(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_); | ||
| } | ||
|
Comment on lines
+127
to
130
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we skip the batch processing and only do this change where we wait for main loop to deal with events after main thread has woken up does it achive similar results?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are two mostly separate things in this PR:
The batch is optional, but the impact on performance is quite great if you are doing I/O. I remember someone complaining in an issue somewhere that NodeGui's I/O is much much slower than plain nodejs. (Yes, I probably should've made 2 PRs. my bad) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice! that make sense. |
||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this change intentional? 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it has moved down to
WakeupMainThread().This is the most important part of the bug fix which affected Windows.
UvRunOnce()gets called from two different places/cases. In one case, you want the semaphore to be touched (Qt event loop is running), and in the other case you don't (no Qt event loop). Hitting the semaphore without the Qt event loop was screwing its counter up.