@@ -275,4 +275,56 @@ void Environment::EnvPromiseHook(v8::PromiseHookType type,
275275 }
276276}
277277
278+ void Environment::RunAndClearNativeImmediates () {
279+ size_t count = native_immediate_callbacks_.size ();
280+ if (count > 0 ) {
281+ std::vector<NativeImmediateCallback> list;
282+ native_immediate_callbacks_.swap (list);
283+ for (const auto & cb : list) {
284+ cb.cb_ (this , cb.data_ );
285+ }
286+
287+ #ifdef DEBUG
288+ CHECK_GE (scheduled_immediate_count_[0 ], count);
289+ #endif
290+ scheduled_immediate_count_[0 ] = scheduled_immediate_count_[0 ] - count;
291+ }
292+ }
293+
294+ static bool MaybeStopImmediate (Environment* env) {
295+ if (env->scheduled_immediate_count ()[0 ] == 0 ) {
296+ uv_check_stop (env->immediate_check_handle ());
297+ uv_idle_stop (env->immediate_idle_handle ());
298+ return true ;
299+ }
300+ return false ;
301+ }
302+
303+
304+ void Environment::CheckImmediate (uv_check_t * handle) {
305+ Environment* env = Environment::from_immediate_check_handle (handle);
306+ HandleScope scope (env->isolate ());
307+ Context::Scope context_scope (env->context ());
308+
309+ if (MaybeStopImmediate (env))
310+ return ;
311+
312+ env->RunAndClearNativeImmediates ();
313+
314+ MakeCallback (env->isolate (),
315+ env->process_object (),
316+ env->immediate_callback_string (),
317+ 0 ,
318+ nullptr ,
319+ {0 , 0 }).ToLocalChecked ();
320+
321+ MaybeStopImmediate (env);
322+ }
323+
324+ void Environment::ActivateImmediateCheck () {
325+ uv_check_start (&immediate_check_handle_, CheckImmediate);
326+ // Idle handle is needed only to stop the event loop from blocking in poll.
327+ uv_idle_start (&immediate_idle_handle_, [](uv_idle_t *){ });
328+ }
329+
278330} // namespace node
0 commit comments