Skip to content

Conversation

gabrielschulhof
Copy link
Contributor

uv_thread_self() works on Windows only for threads created using
uv_thread_start() because libuv does not use GetCurrentThreadId()
for threads that were created otherwise. uv_thread_equal() works
correctly.

Thus, on Windows we use GetCurrentThreadId() to compare the main
thread with the current thread.

Signed-off-by: @gabrielschulhof

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • commit message follows commit guidelines

@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. node-api Issues and PRs related to the Node-API. labels Apr 13, 2020
`uv_thread_self()` works on Windows only for threads created using
`uv_thread_start()` because libuv does not use `GetCurrentThreadId()`
for threads that were created otherwise. `uv_thread_equal()` works
correctly.

Thus, on Windows we use `GetCurrentThreadId()` to compare the main
thread with the current thread.

Signed-off-by: Gabriel Schulhof <[email protected]>
@gabrielschulhof gabrielschulhof force-pushed the tsfn-fix-win32-thread-self branch from 1d5c7f8 to 55e9481 Compare April 13, 2020 19:09
@nodejs-github-bot
Copy link
Collaborator

@nodejs-github-bot
Copy link
Collaborator

@bnoordhuis
Copy link
Member

I don't think this is a sound change, it turns main_thread into something that is unsafe to use with the uv_thread_*() functions on Windows.

Alternative solution: use a uv_key_t (or a thread_local bool is_main_thread if you can get that past the CI) and only set it to true on the main thread.

With a uv_key_t, you can uv_key_set(&key, &key) and check uv_key_get(&key) != NULL.

@gabrielschulhof
Copy link
Contributor Author

@bnoordhuis I'll try the thread_local approach, though I have no experience marking instance variables as thread-local. Alternatively, I can extend the #ifdef to the thread ID data type and to the comparison function, and then we'd be using pure win32 on Windows, and pure uv elsewhere.

@gabrielschulhof
Copy link
Contributor Author

... aaaand you can't make instance variables thread-local (at least AFAICT), so I'll go with the full API separation approach.

@gabrielschulhof
Copy link
Contributor Author

@addaleax @bnoordhuis I changed the implementation to not abuse the libuv API.

@nodejs-github-bot
Copy link
Collaborator

@nodejs-github-bot
Copy link
Collaborator


while (queue.size() >= max_queue_size &&
max_queue_size > 0 &&
!is_closing) {
if (mode == napi_tsfn_nonblocking) {
return napi_queue_full;
} else if (uv_thread_equal(&current_thread, &main_thread)) {
} else if (current_thread == main_thread) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to do something like env_->is_main_thread() (worker thread's approach)? in which case we can potentially remove the ThreadID class as well as the main_thread instance variable?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gireeshpunathil No, because this function may be called from a thread that does not have access to an instance of node::Environment.

himself65
himself65 previously approved these changes Apr 14, 2020
@nodejs-github-bot
Copy link
Collaborator

@nodejs-github-bot
Copy link
Collaborator

nodejs-github-bot commented Apr 14, 2020

Co-Authored-By: Anna Henningsen <[email protected]>
@gabrielschulhof
Copy link
Contributor Author

@addaleax suggestions applied 👍

@nodejs-github-bot
Copy link
Collaborator

@nodejs-github-bot
Copy link
Collaborator

@nodejs-github-bot
Copy link
Collaborator

nodejs-github-bot commented Apr 14, 2020

@bnoordhuis
Copy link
Member

aaaand you can't make instance variables thread-local

Yes, I was talking about a static class member because the main_thread name threw me off.

There's only one main thread in a process; it looks like what is meant here is more accurately called the home thread.

Just wondering, didn't the uv_key_t approach work? That should need no platform-specific code.

@gabrielschulhof
Copy link
Contributor Author

@bnoordhuis the problem is that I would need one key per instance of a thread-safe function, whereas by my understanding uv_key_* is designed to render global static variables thread-local.

@gabrielschulhof
Copy link
Contributor Author

@bnoordhuis I'll rename main_thread to js_thread.

@gabrielschulhof
Copy link
Contributor Author

@bnoordhuis I think I grok what you're saying 🙂 Testing locally now.

@gabrielschulhof
Copy link
Contributor Author

@bnoordhuis I have created #32860 as an alternative. I'll keep it in draft until I've had a chance to look at the CI results.

@himself65 himself65 dismissed their stale review April 15, 2020 07:06

I prefer to approve another PR

@nodejs-github-bot
Copy link
Collaborator

@gabrielschulhof
Copy link
Contributor Author

Closing in favour of #32860.

@gabrielschulhof gabrielschulhof deleted the tsfn-fix-win32-thread-self branch April 21, 2020 02:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c++ Issues and PRs that require attention from people who are familiar with C++. node-api Issues and PRs related to the Node-API.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants