| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 3e5b2eb commit f3b0cf5
7 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -5,6 +5,7 @@ | |||
| 5 | 5 | #include "util.h" | |
| 6 | 6 | #include "util-inl.h" | |
| 7 | 7 | ||
| 8 | + #include "uv.h" | ||
| 8 | 9 | #include "v8.h" | |
| 9 | 10 | #include "v8-profiler.h" | |
| 10 | 11 | ||
@@ -182,6 +183,38 @@ void AsyncWrap::Initialize(Local<Object> target, | |||
| 182 | 183 | } | |
| 183 | 184 | ||
| 184 | 185 | ||
| 186 | + void AsyncWrap::DestroyIdsCb(uv_idle_t* handle) { | ||
| 187 | + uv_idle_stop(handle); | ||
| 188 | + | ||
| 189 | + Environment* env = Environment::from_destroy_ids_idle_handle(handle); | ||
| 190 | + // None of the V8 calls done outside the HandleScope leak a handle. If this | ||
| 191 | + // changes in the future then the SealHandleScope wrapping the uv_run() | ||
| 192 | + // will catch this can cause the process to abort. | ||
| 193 | + HandleScope handle_scope(env->isolate()); | ||
| 194 | + Context::Scope context_scope(env->context()); | ||
| 195 | + Local<Function> fn = env->async_hooks_destroy_function(); | ||
| 196 | + | ||
| 197 | + if (fn.IsEmpty()) | ||
| 198 | + return env->destroy_ids_list()->clear(); | ||
| 199 | + | ||
| 200 | + TryCatch try_catch(env->isolate()); | ||
| 201 | + | ||
| 202 | + for (auto current_id : *env->destroy_ids_list()) { | ||
| 203 | + // Want each callback to be cleaned up after itself, instead of cleaning | ||
| 204 | + // them all up after the while() loop completes. | ||
| 205 | + HandleScope scope(env->isolate()); | ||
| 206 | + Local<Value> argv = Number::New(env->isolate(), current_id); | ||
| 207 | + MaybeLocal<Value> ret = fn->Call( | ||
| 208 | + env->context(), Undefined(env->isolate()), 1, &argv); | ||
| 209 | + | ||
| 210 | + if (ret.IsEmpty()) { | ||
| 211 | + ClearFatalExceptionHandlers(env); | ||
| 212 | + FatalException(env->isolate(), try_catch); | ||
| 213 | + } | ||
| 214 | + } | ||
| 215 | + } | ||
| 216 | + | ||
| 217 | + | ||
| 185 | 218 | void LoadAsyncWrapperInfo(Environment* env) { | |
| 186 | 219 | HeapProfiler* heap_profiler = env->isolate()->GetHeapProfiler(); | |
| 187 | 220 | #define V(PROVIDER) \ | |
@@ -248,18 +281,10 @@ AsyncWrap::~AsyncWrap() { | |||
| 248 | 281 | if (!ran_init_callback()) | |
| 249 | 282 | return; | |
| 250 | 283 | ||
| 251 | - Local<Function> fn = env()->async_hooks_destroy_function(); | ||
| 252 | - if (!fn.IsEmpty()) { | ||
| 253 | - HandleScope scope(env()->isolate()); | ||
| 254 | - Local<Value> uid = Number::New(env()->isolate(), get_uid()); | ||
| 255 | - TryCatch try_catch(env()->isolate()); | ||
| 256 | - MaybeLocal<Value> ret = | ||
| 257 | - fn->Call(env()->context(), Null(env()->isolate()), 1, &uid); | ||
| 258 | - if (ret.IsEmpty()) { | ||
| 259 | - ClearFatalExceptionHandlers(env()); | ||
| 260 | - FatalException(env()->isolate(), try_catch); | ||
| 261 | - } | ||
| 262 | - } | ||
| 284 | + if (env()->destroy_ids_list()->empty()) | ||
| 285 | + uv_idle_start(env()->destroy_ids_idle_handle(), DestroyIdsCb); | ||
| 286 | + | ||
| 287 | + env()->destroy_ids_list()->push_back(get_uid()); | ||
| 263 | 288 | } | |
| 264 | 289 | ||
| 265 | 290 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -4,6 +4,7 @@ | |||
| 4 | 4 | #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS | |
| 5 | 5 | ||
| 6 | 6 | #include "base-object.h" | |
| 7 | + #include "uv.h" | ||
| 7 | 8 | #include "v8.h" | |
| 8 | 9 | ||
| 9 | 10 | #include <stdint.h> | |
@@ -60,6 +61,8 @@ class AsyncWrap : public BaseObject { | |||
| 60 | 61 | v8::Local<v8::Value> unused, | |
| 61 | 62 | v8::Local<v8::Context> context); | |
| 62 | 63 | ||
| 64 | + static void DestroyIdsCb(uv_idle_t* handle); | ||
| 65 | + | ||
| 63 | 66 | inline ProviderType provider_type() const; | |
| 64 | 67 | ||
| 65 | 68 | inline int64_t get_uid() const; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -245,6 +245,8 @@ inline Environment::Environment(v8::Local<v8::Context> context, | |||
| 245 | 245 | ||
| 246 | 246 | RB_INIT(&cares_task_list_); | |
| 247 | 247 | handle_cleanup_waiting_ = 0; | |
| 248 | + | ||
| 249 | + destroy_ids_list_.reserve(512); | ||
| 248 | 250 | } | |
| 249 | 251 | ||
| 250 | 252 | inline Environment::~Environment() { | |
@@ -305,6 +307,15 @@ inline uv_idle_t* Environment::immediate_idle_handle() { | |||
| 305 | 307 | return &immediate_idle_handle_; | |
| 306 | 308 | } | |
| 307 | 309 | ||
| 310 | + inline Environment* Environment::from_destroy_ids_idle_handle( | ||
| 311 | + uv_idle_t* handle) { | ||
| 312 | + return ContainerOf(&Environment::destroy_ids_idle_handle_, handle); | ||
| 313 | + } | ||
| 314 | + | ||
| 315 | + inline uv_idle_t* Environment::destroy_ids_idle_handle() { | ||
| 316 | + return &destroy_ids_idle_handle_; | ||
| 317 | + } | ||
| 318 | + | ||
| 308 | 319 | inline Environment* Environment::from_idle_prepare_handle( | |
| 309 | 320 | uv_prepare_t* handle) { | |
| 310 | 321 | return ContainerOf(&Environment::idle_prepare_handle_, handle); | |
@@ -381,6 +392,10 @@ inline int64_t Environment::get_async_wrap_uid() { | |||
| 381 | 392 | return ++async_wrap_uid_; | |
| 382 | 393 | } | |
| 383 | 394 | ||
| 395 | + inline std::vector<int64_t>* Environment::destroy_ids_list() { | ||
| 396 | + return &destroy_ids_list_; | ||
| 397 | + } | ||
| 398 | + | ||
| 384 | 399 | inline uint32_t* Environment::heap_statistics_buffer() const { | |
| 385 | 400 | CHECK_NE(heap_statistics_buffer_, nullptr); | |
| 386 | 401 | return heap_statistics_buffer_; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -16,6 +16,7 @@ | |||
| 16 | 16 | #include "v8.h" | |
| 17 | 17 | ||
| 18 | 18 | #include <stdint.h> | |
| 19 | + #include <vector> | ||
| 19 | 20 | ||
| 20 | 21 | // Caveat emptor: we're going slightly crazy with macros here but the end | |
| 21 | 22 | // hopefully justifies the means. We have a lot of per-context properties | |
@@ -413,8 +414,10 @@ class Environment { | |||
| 413 | 414 | inline uint32_t watched_providers() const; | |
| 414 | 415 | ||
| 415 | 416 | static inline Environment* from_immediate_check_handle(uv_check_t* handle); | |
| 417 | + static inline Environment* from_destroy_ids_idle_handle(uv_idle_t* handle); | ||
| 416 | 418 | inline uv_check_t* immediate_check_handle(); | |
| 417 | 419 | inline uv_idle_t* immediate_idle_handle(); | |
| 420 | + inline uv_idle_t* destroy_ids_idle_handle(); | ||
| 418 | 421 | ||
| 419 | 422 | static inline Environment* from_idle_prepare_handle(uv_prepare_t* handle); | |
| 420 | 423 | inline uv_prepare_t* idle_prepare_handle(); | |
@@ -451,6 +454,9 @@ class Environment { | |||
| 451 | 454 | ||
| 452 | 455 | inline int64_t get_async_wrap_uid(); | |
| 453 | 456 | ||
| 457 | + // List of id's that have been destroyed and need the destroy() cb called. | ||
| 458 | + inline std::vector<int64_t>* destroy_ids_list(); | ||
| 459 | + | ||
| 454 | 460 | inline uint32_t* heap_statistics_buffer() const; | |
| 455 | 461 | inline void set_heap_statistics_buffer(uint32_t* pointer); | |
| 456 | 462 | ||
@@ -543,6 +549,7 @@ class Environment { | |||
| 543 | 549 | IsolateData* const isolate_data_; | |
| 544 | 550 | uv_check_t immediate_check_handle_; | |
| 545 | 551 | uv_idle_t immediate_idle_handle_; | |
| 552 | + uv_idle_t destroy_ids_idle_handle_; | ||
| 546 | 553 | uv_prepare_t idle_prepare_handle_; | |
| 547 | 554 | uv_check_t idle_check_handle_; | |
| 548 | 555 | AsyncHooks async_hooks_; | |
@@ -558,6 +565,7 @@ class Environment { | |||
| 558 | 565 | bool trace_sync_io_; | |
| 559 | 566 | size_t makecallback_cntr_; | |
| 560 | 567 | int64_t async_wrap_uid_; | |
| 568 | + std::vector<int64_t> destroy_ids_list_; | ||
| 561 | 569 | debugger::Agent debugger_agent_; | |
| 562 | 570 | #if HAVE_INSPECTOR | |
| 563 | 571 | inspector::Agent inspector_agent_; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -4511,6 +4511,9 @@ Environment* CreateEnvironment(Isolate* isolate, | |||
| 4511 | 4511 | uv_unref(reinterpret_cast<uv_handle_t*>(env->idle_prepare_handle())); | |
| 4512 | 4512 | uv_unref(reinterpret_cast<uv_handle_t*>(env->idle_check_handle())); | |
| 4513 | 4513 | ||
| 4514 | + uv_idle_init(env->event_loop(), env->destroy_ids_idle_handle()); | ||
| 4515 | + uv_unref(reinterpret_cast<uv_handle_t*>(env->destroy_ids_idle_handle())); | ||
| 4516 | + | ||
| 4514 | 4517 | // Register handle cleanups | |
| 4515 | 4518 | env->RegisterHandleCleanup( | |
| 4516 | 4519 | reinterpret_cast<uv_handle_t*>(env->immediate_check_handle()), | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -6,7 +6,7 @@ const assert = require('assert'); | |||
| 6 | 6 | const crypto = require('crypto'); | |
| 7 | 7 | const domain = require('domain'); | |
| 8 | 8 | const spawn = require('child_process').spawn; | |
| 9 | - const callbacks = [ 'init', 'pre', 'post', 'destroy' ]; | ||
| 9 | + const callbacks = [ 'init', 'pre', 'post' ]; | ||
| 10 | 10 | const toCall = process.argv[2]; | |
| 11 | 11 | var msgCalled = 0; | |
| 12 | 12 | var msgReceived = 0; | |
@@ -23,13 +23,9 @@ function post() { | |||
| 23 | 23 | if (toCall === 'post') | |
| 24 | 24 | throw new Error('post'); | |
| 25 | 25 | } | |
| 26 | - function destroy() { | ||
| 27 | - if (toCall === 'destroy') | ||
| 28 | - throw new Error('destroy'); | ||
| 29 | - } | ||
| 30 | 26 | ||
| 31 | 27 | if (typeof process.argv[2] === 'string') { | |
| 32 | - async_wrap.setupHooks({ init, pre, post, destroy }); | ||
| 28 | + async_wrap.setupHooks({ init, pre, post }); | ||
| 33 | 29 | async_wrap.enable(); | |
| 34 | 30 | ||
| 35 | 31 | process.on('uncaughtException', () => assert.ok(0, 'UNREACHABLE')); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -6,15 +6,14 @@ const assert = require('assert'); | |||
| 6 | 6 | const async_wrap = process.binding('async_wrap'); | |
| 7 | 7 | ||
| 8 | 8 | const storage = new Map(); | |
| 9 | - async_wrap.setupHooks({ init, pre, post, destroy }); | ||
| 9 | + async_wrap.setupHooks({ init, pre, post }); | ||
| 10 | 10 | async_wrap.enable(); | |
| 11 | 11 | ||
| 12 | 12 | function init(uid) { | |
| 13 | 13 | storage.set(uid, { | |
| 14 | 14 | init: true, | |
| 15 | 15 | pre: false, | |
| 16 | 16 | post: false, | |
| 17 | - destroy: false | ||
| 18 | 17 | }); | |
| 19 | 18 | } | |
| 20 | 19 | ||
@@ -26,10 +25,6 @@ function post(uid) { | |||
| 26 | 25 | storage.get(uid).post = true; | |
| 27 | 26 | } | |
| 28 | 27 | ||
| 29 | - function destroy(uid) { | ||
| 30 | - storage.get(uid).destroy = true; | ||
| 31 | - } | ||
| 32 | - | ||
| 33 | 28 | fs.access(__filename, function(err) { | |
| 34 | 29 | assert.ifError(err); | |
| 35 | 30 | }); | |
@@ -51,7 +46,6 @@ process.once('exit', function() { | |||
| 51 | 46 | init: true, | |
| 52 | 47 | pre: true, | |
| 53 | 48 | post: true, | |
| 54 | - destroy: true | ||
| 55 | 49 | }); | |
| 56 | 50 | } | |
| 57 | 51 | }); | |
| Back | FazBrowse Home | New Git URL |
0 commit comments