diff options
author | Anatoli Papirovski <apapirovski@mac.com> | 2018-01-08 21:05:14 -0500 |
---|---|---|
committer | James M Snell <jasnell@gmail.com> | 2018-01-09 08:25:37 -0800 |
commit | ececdd316766998ca3309ccb01f5618d44d0d91e (patch) | |
tree | a9bc0820b76d69b99dbb9f91496edd7c7be26c9c /src/node_perf.cc | |
parent | f3f3f8890c2e2364ca88f043e1ab675d72c370e6 (diff) | |
download | android-node-v8-ececdd316766998ca3309ccb01f5618d44d0d91e.tar.gz android-node-v8-ececdd316766998ca3309ccb01f5618d44d0d91e.tar.bz2 android-node-v8-ececdd316766998ca3309ccb01f5618d44d0d91e.zip |
perf_hooks: fix scheduling regression
Scheduling a PerformanceGCCallback should not keep the
loop alive but due to the recent switch to using the
native SetImmediate method, it does. Go back to using
uv_async_t and add a regression test.
PR-URL: https://github.com/nodejs/node/pull/18051
Fixes: https://github.com/nodejs/node/issues/18047
Refs: https://github.com/nodejs/node/pull/18020
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Diffstat (limited to 'src/node_perf.cc')
-rw-r--r-- | src/node_perf.cc | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/src/node_perf.cc b/src/node_perf.cc index 6a59d50fb6..97d3a2d995 100644 --- a/src/node_perf.cc +++ b/src/node_perf.cc @@ -182,8 +182,9 @@ void SetupPerformanceObservers(const FunctionCallbackInfo<Value>& args) { } // Creates a GC Performance Entry and passes it to observers -void PerformanceGCCallback(Environment* env, void* ptr) { - GCPerformanceEntry* entry = static_cast<GCPerformanceEntry*>(ptr); +void PerformanceGCCallback(uv_async_t* handle) { + GCPerformanceEntry* entry = static_cast<GCPerformanceEntry*>(handle->data); + Environment* env = entry->env(); HandleScope scope(env->isolate()); Local<Context> context = env->context(); @@ -200,6 +201,10 @@ void PerformanceGCCallback(Environment* env, void* ptr) { } delete entry; + auto closeCB = [](uv_handle_t* handle) { + delete reinterpret_cast<uv_async_t*>(handle); + }; + uv_close(reinterpret_cast<uv_handle_t*>(handle), closeCB); } // Marks the start of a GC cycle @@ -216,11 +221,16 @@ void MarkGarbageCollectionEnd(Isolate* isolate, v8::GCCallbackFlags flags, void* data) { Environment* env = static_cast<Environment*>(data); - env->SetImmediate(PerformanceGCCallback, - new GCPerformanceEntry(env, - static_cast<PerformanceGCKind>(type), - performance_last_gc_start_mark_, - PERFORMANCE_NOW())); + uv_async_t* async = new uv_async_t(); + if (uv_async_init(env->event_loop(), async, PerformanceGCCallback)) + return delete async; + uv_unref(reinterpret_cast<uv_handle_t*>(async)); + async->data = + new GCPerformanceEntry(env, + static_cast<PerformanceGCKind>(type), + performance_last_gc_start_mark_, + PERFORMANCE_NOW()); + CHECK_EQ(0, uv_async_send(async)); } |