@@ -223,4 +223,56 @@ void Environment::EnvPromiseHook(v8::PromiseHookType type,
223
223
}
224
224
}
225
225
226
+ void Environment::RunAndClearNativeImmediates () {
227
+ size_t count = native_immediate_callbacks_.size ();
228
+ if (count > 0 ) {
229
+ std::vector<NativeImmediateCallback> list;
230
+ native_immediate_callbacks_.swap (list);
231
+ for (const auto & cb : list) {
232
+ cb.cb_ (this , cb.data_ );
233
+ }
234
+
235
+ #ifdef DEBUG
236
+ CHECK_GE (scheduled_immediate_count_[0 ], count);
237
+ #endif
238
+ scheduled_immediate_count_[0 ] = scheduled_immediate_count_[0 ] - count;
239
+ }
240
+ }
241
+
242
+ static bool MaybeStopImmediate (Environment* env) {
243
+ if (env->scheduled_immediate_count ()[0 ] == 0 ) {
244
+ uv_check_stop (env->immediate_check_handle ());
245
+ uv_idle_stop (env->immediate_idle_handle ());
246
+ return true ;
247
+ }
248
+ return false ;
249
+ }
250
+
251
+
252
+ void Environment::CheckImmediate (uv_check_t * handle) {
253
+ Environment* env = Environment::from_immediate_check_handle (handle);
254
+ HandleScope scope (env->isolate ());
255
+ Context::Scope context_scope (env->context ());
256
+
257
+ if (MaybeStopImmediate (env))
258
+ return ;
259
+
260
+ env->RunAndClearNativeImmediates ();
261
+
262
+ MakeCallback (env->isolate (),
263
+ env->process_object (),
264
+ env->immediate_callback_string (),
265
+ 0 ,
266
+ nullptr ,
267
+ {0 , 0 }).ToLocalChecked ();
268
+
269
+ MaybeStopImmediate (env);
270
+ }
271
+
272
+ void Environment::ActivateImmediateCheck () {
273
+ uv_check_start (&immediate_check_handle_, CheckImmediate);
274
+ // Idle handle is needed only to stop the event loop from blocking in poll.
275
+ uv_idle_start (&immediate_idle_handle_, [](uv_idle_t *){ });
276
+ }
277
+
226
278
} // namespace node
0 commit comments