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