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

worker: correct (de)initialization order #22773

Closed
wants to merge 1 commit into from

Conversation

addaleax
Copy link
Member

@addaleax addaleax commented Sep 9, 2018

  • Initialize thread_exit_async_ only once the thread has been
    started. This is done since it is only triggered from the
    thread when it is exiting.
  • Move the final uv_run to the Worker destructor.
    This makes sure that it is always run, regardless of whether
    the thread is actually started or not.
  • Always dispose the Isolate before cleaning up the libuv event
    loop. This now matches the reverse order of initialization.

Fixes: #22736

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • commit message follows commit guidelines

/cc @nodejs/workers

- Initialize `thread_exit_async_` only once the thread has been
  started. This is done since it is only triggered from the
  thread when it is exiting.
- Move the final `uv_run` to the `Worker` destructor.
  This makes sure that it is always run, regardless of whether
  the thread is actually started or not.
- Always dispose the `Isolate` before cleaning up the libuv event
  loop. This now matches the reverse order of initialization.

Fixes: nodejs#22736
@addaleax addaleax added c++ Issues and PRs that require attention from people who are familiar with C++. worker Issues and PRs related to Worker support. labels Sep 9, 2018
@nodejs-github-bot nodejs-github-bot added the c++ Issues and PRs that require attention from people who are familiar with C++. label Sep 9, 2018
@@ -361,10 +361,19 @@ void Worker::StartThread(const FunctionCallbackInfo<Value>& args) {

w->env()->add_sub_worker_context(w);
w->stopped_ = false;
w->thread_joined_ = false;

w->thread_exit_async_.reset(new uv_async_t);
Copy link
Contributor

Choose a reason for hiding this comment

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

Question: why is this before the uv_thread_create? Maybe it's just a non intuitive name OnThreadStopped?
AFAICT uv_async_send(thread_exit_async_.get()) can only run iff the thread was created.

Copy link
Member Author

Choose a reason for hiding this comment

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

Question: why is this before the uv_thread_create?

Switching these would create a race condition – the worker thread might finish (and try to call uv_async_send() on this) before we have initialized the async

Maybe it's just a non intuitive name OnThreadStopped?

Can you expand on this? It’s an event handler that’s called when the worker thread finishes.

AFAICT uv_async_send(thread_exit_async_.get()) can only run iff the thread was created.

That is correct, yes.

@addaleax
Copy link
Member Author

@addaleax
Copy link
Member Author

@addaleax addaleax added the author ready PRs that have at least one approval, no pending requests for changes, and a CI started. label Sep 13, 2018
@addaleax
Copy link
Member Author

Landed in df7ebfa

@addaleax addaleax closed this Sep 14, 2018
@addaleax addaleax deleted the worker-fix-uninitialized branch September 14, 2018 16:56
addaleax added a commit that referenced this pull request Sep 14, 2018
- Initialize `thread_exit_async_` only once the thread has been
  started. This is done since it is only triggered from the
  thread when it is exiting.
- Move the final `uv_run` to the `Worker` destructor.
  This makes sure that it is always run, regardless of whether
  the thread is actually started or not.
- Always dispose the `Isolate` before cleaning up the libuv event
  loop. This now matches the reverse order of initialization.

Fixes: #22736
PR-URL: #22773
Reviewed-By: James M Snell <jasnell@gmail.com>
targos pushed a commit that referenced this pull request Sep 15, 2018
- Initialize `thread_exit_async_` only once the thread has been
  started. This is done since it is only triggered from the
  thread when it is exiting.
- Move the final `uv_run` to the `Worker` destructor.
  This makes sure that it is always run, regardless of whether
  the thread is actually started or not.
- Always dispose the `Isolate` before cleaning up the libuv event
  loop. This now matches the reverse order of initialization.

Fixes: #22736
PR-URL: #22773
Reviewed-By: James M Snell <jasnell@gmail.com>
targos pushed a commit that referenced this pull request Sep 19, 2018
- Initialize `thread_exit_async_` only once the thread has been
  started. This is done since it is only triggered from the
  thread when it is exiting.
- Move the final `uv_run` to the `Worker` destructor.
  This makes sure that it is always run, regardless of whether
  the thread is actually started or not.
- Always dispose the `Isolate` before cleaning up the libuv event
  loop. This now matches the reverse order of initialization.

Fixes: #22736
PR-URL: #22773
Reviewed-By: James M Snell <jasnell@gmail.com>
targos pushed a commit that referenced this pull request Sep 20, 2018
- Initialize `thread_exit_async_` only once the thread has been
  started. This is done since it is only triggered from the
  thread when it is exiting.
- Move the final `uv_run` to the `Worker` destructor.
  This makes sure that it is always run, regardless of whether
  the thread is actually started or not.
- Always dispose the `Isolate` before cleaning up the libuv event
  loop. This now matches the reverse order of initialization.

Fixes: #22736
PR-URL: #22773
Reviewed-By: James M Snell <jasnell@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
author ready PRs that have at least one approval, no pending requests for changes, and a CI started. c++ Issues and PRs that require attention from people who are familiar with C++. worker Issues and PRs related to Worker support.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Worker threads: the process keeps living on exception
4 participants