| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 28dbc46 commit 60883de
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 | ||
@@ -183,6 +184,38 @@ void AsyncWrap::Initialize(Local<Object> target, | |||
| 183 | 184 | } | |
| 184 | 185 | ||
| 185 | 186 | ||
| 187 | + void AsyncWrap::DestroyIdsCb(uv_idle_t* handle) { | ||
| 188 | + uv_idle_stop(handle); | ||
| 189 | + | ||
| 190 | + Environment* env = Environment::from_destroy_ids_idle_handle(handle); | ||
| 191 | + // None of the V8 calls done outside the HandleScope leak a handle. If this | ||
| 192 | + // changes in the future then the SealHandleScope wrapping the uv_run() | ||
| 193 | + // will catch this can cause the process to abort. | ||
| 194 | + HandleScope handle_scope(env->isolate()); | ||
| 195 | + Context::Scope context_scope(env->context()); | ||
| 196 | + Local<Function> fn = env->async_hooks_destroy_function(); | ||
| 197 | + | ||
| 198 | + if (fn.IsEmpty()) | ||
| 199 | + return env->destroy_ids_list()->clear(); | ||
| 200 | + | ||
| 201 | + TryCatch try_catch(env->isolate()); | ||
| 202 | + | ||
| 203 | + for (auto current_id : *env->destroy_ids_list()) { | ||
| 204 | + // Want each callback to be cleaned up after itself, instead of cleaning | ||
| 205 | + // them all up after the while() loop completes. | ||
| 206 | + HandleScope scope(env->isolate()); | ||
| 207 | + Local<Value> argv = Number::New(env->isolate(), current_id); | ||
| 208 | + MaybeLocal<Value> ret = fn->Call( | ||
| 209 | + env->context(), Undefined(env->isolate()), 1, &argv); | ||
| 210 | + | ||
| 211 | + if (ret.IsEmpty()) { | ||
| 212 | + ClearFatalExceptionHandlers(env); | ||
| 213 | + FatalException(env->isolate(), try_catch); | ||
| 214 | + } | ||
| 215 | + } | ||
| 216 | + } | ||
| 217 | + | ||
| 218 | + | ||
| 186 | 219 | void LoadAsyncWrapperInfo(Environment* env) { | |
| 187 | 220 | HeapProfiler* heap_profiler = env->isolate()->GetHeapProfiler(); | |
| 188 | 221 | #define V(PROVIDER) \ | |
@@ -249,18 +282,10 @@ AsyncWrap::~AsyncWrap() { | |||
| 249 | 282 | if (!ran_init_callback()) | |
| 250 | 283 | return; | |
| 251 | 284 | ||
| 252 | - Local<Function> fn = env()->async_hooks_destroy_function(); | ||
| 253 | - if (!fn.IsEmpty()) { | ||
| 254 | - HandleScope scope(env()->isolate()); | ||
| 255 | - Local<Value> uid = Number::New(env()->isolate(), get_uid()); | ||
| 256 | - TryCatch try_catch(env()->isolate()); | ||
| 257 | - MaybeLocal<Value> ret = | ||
| 258 | - fn->Call(env()->context(), Null(env()->isolate()), 1, &uid); | ||
| 259 | - if (ret.IsEmpty()) { | ||
| 260 | - ClearFatalExceptionHandlers(env()); | ||
| 261 | - FatalException(env()->isolate(), try_catch); | ||
| 262 | - } | ||
| 263 | - } | ||
| 285 | + if (env()->destroy_ids_list()->empty()) | ||
| 286 | + uv_idle_start(env()->destroy_ids_idle_handle(), DestroyIdsCb); | ||
| 287 | + | ||
| 288 | + env()->destroy_ids_list()->push_back(get_uid()); | ||
| 264 | 289 | } | |
| 265 | 290 | ||
| 266 | 291 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2,6 +2,7 @@ | |||
| 2 | 2 | #define SRC_ASYNC_WRAP_H_ | |
| 3 | 3 | ||
| 4 | 4 | #include "base-object.h" | |
| 5 | + #include "uv.h" | ||
| 5 | 6 | #include "v8.h" | |
| 6 | 7 | ||
| 7 | 8 | #include <stdint.h> | |
@@ -58,6 +59,8 @@ class AsyncWrap : public BaseObject { | |||
| 58 | 59 | v8::Local<v8::Value> unused, | |
| 59 | 60 | v8::Local<v8::Context> context); | |
| 60 | 61 | ||
| 62 | + static void DestroyIdsCb(uv_idle_t* handle); | ||
| 63 | + | ||
| 61 | 64 | inline ProviderType provider_type() const; | |
| 62 | 65 | ||
| 63 | 66 | inline int64_t get_uid() const; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -227,6 +227,8 @@ inline Environment::Environment(v8::Local<v8::Context> context, | |||
| 227 | 227 | ||
| 228 | 228 | RB_INIT(&cares_task_list_); | |
| 229 | 229 | handle_cleanup_waiting_ = 0; | |
| 230 | + | ||
| 231 | + destroy_ids_list_.reserve(512); | ||
| 230 | 232 | } | |
| 231 | 233 | ||
| 232 | 234 | inline Environment::~Environment() { | |
@@ -286,6 +288,15 @@ inline uv_idle_t* Environment::immediate_idle_handle() { | |||
| 286 | 288 | return &immediate_idle_handle_; | |
| 287 | 289 | } | |
| 288 | 290 | ||
| 291 | + inline Environment* Environment::from_destroy_ids_idle_handle( | ||
| 292 | + uv_idle_t* handle) { | ||
| 293 | + return ContainerOf(&Environment::destroy_ids_idle_handle_, handle); | ||
| 294 | + } | ||
| 295 | + | ||
| 296 | + inline uv_idle_t* Environment::destroy_ids_idle_handle() { | ||
| 297 | + return &destroy_ids_idle_handle_; | ||
| 298 | + } | ||
| 299 | + | ||
| 289 | 300 | inline Environment* Environment::from_idle_prepare_handle( | |
| 290 | 301 | uv_prepare_t* handle) { | |
| 291 | 302 | return ContainerOf(&Environment::idle_prepare_handle_, handle); | |
@@ -362,6 +373,10 @@ inline int64_t Environment::get_async_wrap_uid() { | |||
| 362 | 373 | return ++async_wrap_uid_; | |
| 363 | 374 | } | |
| 364 | 375 | ||
| 376 | + inline std::vector<int64_t>* Environment::destroy_ids_list() { | ||
| 377 | + return &destroy_ids_list_; | ||
| 378 | + } | ||
| 379 | + | ||
| 365 | 380 | inline uint32_t* Environment::heap_statistics_buffer() const { | |
| 366 | 381 | CHECK_NE(heap_statistics_buffer_, nullptr); | |
| 367 | 382 | return heap_statistics_buffer_; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -11,6 +11,7 @@ | |||
| 11 | 11 | #include "v8.h" | |
| 12 | 12 | ||
| 13 | 13 | #include <stdint.h> | |
| 14 | + #include <vector> | ||
| 14 | 15 | ||
| 15 | 16 | // Caveat emptor: we're going slightly crazy with macros here but the end | |
| 16 | 17 | // 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 | ||
@@ -531,6 +537,7 @@ class Environment { | |||
| 531 | 537 | IsolateData* const isolate_data_; | |
| 532 | 538 | uv_check_t immediate_check_handle_; | |
| 533 | 539 | uv_idle_t immediate_idle_handle_; | |
| 540 | + uv_idle_t destroy_ids_idle_handle_; | ||
| 534 | 541 | uv_prepare_t idle_prepare_handle_; | |
| 535 | 542 | uv_check_t idle_check_handle_; | |
| 536 | 543 | AsyncHooks async_hooks_; | |
@@ -546,6 +553,7 @@ class Environment { | |||
| 546 | 553 | bool trace_sync_io_; | |
| 547 | 554 | size_t makecallback_cntr_; | |
| 548 | 555 | int64_t async_wrap_uid_; | |
| 556 | + std::vector<int64_t> destroy_ids_list_; | ||
| 549 | 557 | debugger::Agent debugger_agent_; | |
| 550 | 558 | ||
| 551 | 559 | HandleWrapQueue handle_wrap_queue_; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -4202,6 +4202,9 @@ Environment* CreateEnvironment(Isolate* isolate, | |||
| 4202 | 4202 | uv_unref(reinterpret_cast<uv_handle_t*>(env->idle_prepare_handle())); | |
| 4203 | 4203 | uv_unref(reinterpret_cast<uv_handle_t*>(env->idle_check_handle())); | |
| 4204 | 4204 | ||
| 4205 | + uv_idle_init(env->event_loop(), env->destroy_ids_idle_handle()); | ||
| 4206 | + uv_unref(reinterpret_cast<uv_handle_t*>(env->destroy_ids_idle_handle())); | ||
| 4207 | + | ||
| 4205 | 4208 | // Register handle cleanups | |
| 4206 | 4209 | env->RegisterHandleCleanup( | |
| 4207 | 4210 | 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