diff options
author | Ben Noordhuis <info@bnoordhuis.nl> | 2017-04-11 20:46:02 +0200 |
---|---|---|
committer | Ben Noordhuis <info@bnoordhuis.nl> | 2017-04-19 11:11:41 +0200 |
commit | 5ef6000afdd16f1c3a1f56cf64502f1f02c57fb4 (patch) | |
tree | 0dd097ac583cdfebb75849eaae1b5431cdfeac67 /src | |
parent | 5d06e5c30d7350ffe697056bc9a712f8152cecc1 (diff) | |
download | android-node-v8-5ef6000afdd16f1c3a1f56cf64502f1f02c57fb4.tar.gz android-node-v8-5ef6000afdd16f1c3a1f56cf64502f1f02c57fb4.tar.bz2 android-node-v8-5ef6000afdd16f1c3a1f56cf64502f1f02c57fb4.zip |
src: don't call uv_run() after 'exit' event
It makes timers and other libuv handles fire intermittently after the
'exit' event, contrary to what the documentation states.
Regression introduced in commit aac79df ("src: use stack-allocated
Environment instances") from June last year that made the
`while (handle_cleanup_waiting_ != 0) uv_run(event_loop(), UV_RUN_ONCE)`
loop run unconditionally on exit because it merged CleanupHandles() into
the Environment destructor.
This change breaks parallel/test-async-wrap-throw-from-callback because
the async_wrap idle handle is no longer cleaned up, which I resolved
pragmatically by removing the test.
In all seriousness, it is being removed in the upcoming async_wrap
revamp - it doesn't make sense to sink a lot of time in it now.
Fixes: https://github.com/nodejs/node/issues/12322
PR-URL: https://github.com/nodejs/node/pull/12344
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/debug-agent.cc | 2 | ||||
-rw-r--r-- | src/env-inl.h | 22 | ||||
-rw-r--r-- | src/env.cc | 24 | ||||
-rw-r--r-- | src/env.h | 1 |
4 files changed, 27 insertions, 22 deletions
diff --git a/src/debug-agent.cc b/src/debug-agent.cc index 2ce8381fc5..aef1daa162 100644 --- a/src/debug-agent.cc +++ b/src/debug-agent.cc @@ -184,6 +184,8 @@ void Agent::WorkerRun() { // Clean-up persistent api_.Reset(); + + env.CleanupHandles(); } isolate->Dispose(); } diff --git a/src/env-inl.h b/src/env-inl.h index 978f8ca819..d4e70ca0d3 100644 --- a/src/env-inl.h +++ b/src/env-inl.h @@ -223,28 +223,6 @@ inline Environment::Environment(IsolateData* isolate_data, inline Environment::~Environment() { v8::HandleScope handle_scope(isolate()); - while (HandleCleanup* hc = handle_cleanup_queue_.PopFront()) { - handle_cleanup_waiting_++; - hc->cb_(this, hc->handle_, hc->arg_); - delete hc; - } - - while (handle_cleanup_waiting_ != 0) - uv_run(event_loop(), UV_RUN_ONCE); - - // Closing the destroy_ids_idle_handle_ within the handle cleanup queue - // prevents the async wrap destroy hook from being called. - uv_handle_t* handle = - reinterpret_cast<uv_handle_t*>(&destroy_ids_idle_handle_); - handle->data = this; - handle_cleanup_waiting_ = 1; - uv_close(handle, [](uv_handle_t* handle) { - static_cast<Environment*>(handle->data)->FinishHandleCleanup(handle); - }); - - while (handle_cleanup_waiting_ != 0) - uv_run(event_loop(), UV_RUN_ONCE); - context()->SetAlignedPointerInEmbedderData(kContextEmbedderDataIndex, nullptr); #define V(PropertyName, TypeName) PropertyName ## _.Reset(); diff --git a/src/env.cc b/src/env.cc index 56d7e28a03..b44b435d4e 100644 --- a/src/env.cc +++ b/src/env.cc @@ -92,6 +92,30 @@ void Environment::Start(int argc, LoadAsyncWrapperInfo(this); } +void Environment::CleanupHandles() { + while (HandleCleanup* hc = handle_cleanup_queue_.PopFront()) { + handle_cleanup_waiting_++; + hc->cb_(this, hc->handle_, hc->arg_); + delete hc; + } + + while (handle_cleanup_waiting_ != 0) + uv_run(event_loop(), UV_RUN_ONCE); + + // Closing the destroy_ids_idle_handle_ within the handle cleanup queue + // prevents the async wrap destroy hook from being called. + uv_handle_t* handle = + reinterpret_cast<uv_handle_t*>(&destroy_ids_idle_handle_); + handle->data = this; + handle_cleanup_waiting_ = 1; + uv_close(handle, [](uv_handle_t* handle) { + static_cast<Environment*>(handle->data)->FinishHandleCleanup(handle); + }); + + while (handle_cleanup_waiting_ != 0) + uv_run(event_loop(), UV_RUN_ONCE); +} + void Environment::StartProfilerIdleNotifier() { uv_prepare_start(&idle_prepare_handle_, [](uv_prepare_t* handle) { Environment* env = ContainerOf(&Environment::idle_prepare_handle_, handle); @@ -440,6 +440,7 @@ class Environment { const char* const* exec_argv, bool start_profiler_idle_notifier); void AssignToContext(v8::Local<v8::Context> context); + void CleanupHandles(); void StartProfilerIdleNotifier(); void StopProfilerIdleNotifier(); |