diff options
Diffstat (limited to 'src/env.cc')
-rw-r--r-- | src/env.cc | 66 |
1 files changed, 31 insertions, 35 deletions
diff --git a/src/env.cc b/src/env.cc index f0ac855e3d..ca5e11ac55 100644 --- a/src/env.cc +++ b/src/env.cc @@ -339,7 +339,7 @@ Environment::Environment(IsolateData* isolate_data, [](void* arg) { Environment* env = static_cast<Environment*>(arg); if (!env->destroy_async_id_list()->empty()) - AsyncWrap::DestroyAsyncIdsCallback(env, nullptr); + AsyncWrap::DestroyAsyncIdsCallback(env); }, this); @@ -642,42 +642,38 @@ void Environment::AtExit(void (*cb)(void* arg), void* arg) { void Environment::RunAndClearNativeImmediates() { TraceEventScope trace_scope(TRACING_CATEGORY_NODE1(environment), "RunAndClearNativeImmediates", this); - size_t count = native_immediate_callbacks_.size(); - if (count > 0) { - size_t ref_count = 0; - std::vector<NativeImmediateCallback> list; - native_immediate_callbacks_.swap(list); - auto drain_list = [&]() { - TryCatchScope try_catch(this); - for (auto it = list.begin(); it != list.end(); ++it) { - DebugSealHandleScope seal_handle_scope(isolate()); - it->cb_(this, it->data_); - if (it->refed_) - ref_count++; - if (UNLIKELY(try_catch.HasCaught())) { - if (!try_catch.HasTerminated()) - errors::TriggerUncaughtException(isolate(), try_catch); - - // We are done with the current callback. Increase the counter so that - // the steps below make everything *after* the current item part of - // the new list. - it++; - - // Bail out, remove the already executed callbacks from list - // and set up a new TryCatch for the other pending callbacks. - std::move_backward(it, list.end(), list.begin() + (list.end() - it)); - list.resize(list.end() - it); - return true; - } + size_t ref_count = 0; + size_t count = 0; + std::unique_ptr<NativeImmediateCallback> head; + head.swap(native_immediate_callbacks_head_); + native_immediate_callbacks_tail_ = nullptr; + + auto drain_list = [&]() { + TryCatchScope try_catch(this); + for (; head; head = head->get_next()) { + DebugSealHandleScope seal_handle_scope(isolate()); + count++; + if (head->is_refed()) + ref_count++; + + head->Call(this); + if (UNLIKELY(try_catch.HasCaught())) { + if (!try_catch.HasTerminated()) + errors::TriggerUncaughtException(isolate(), try_catch); + + // We are done with the current callback. Move one iteration along, + // as if we had completed successfully. + head = head->get_next(); + return true; } - return false; - }; - while (drain_list()) {} + } + return false; + }; + while (head && drain_list()) {} - DCHECK_GE(immediate_info()->count(), count); - immediate_info()->count_dec(count); - immediate_info()->ref_count_dec(ref_count); - } + DCHECK_GE(immediate_info()->count(), count); + immediate_info()->count_dec(count); + immediate_info()->ref_count_dec(ref_count); } |