Skip to content
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

n-api: fix win32 main thread detection #32823

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 <gabriel.schulhof@intel.com>
@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

src/node_api.cc Outdated Show resolved Hide resolved
src/node_api.cc Outdated Show resolved Hide resolved
Co-Authored-By: Anna Henningsen <github@addaleax.net>
@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.

@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