|
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 | +voidAsyncWrap::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 | voidLoadAsyncWrapperInfo(Environment* env){ |
187 | 220 | HeapProfiler* heap_profiler = env->isolate()->GetHeapProfiler(); |
188 | 221 | #defineV(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 |
|
|
0 commit comments