| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 9f282dd commit fd501b3
4 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -47,6 +47,13 @@ const { kInit, kDestroy, kAsyncIdCounter } = async_wrap.constants; | |||
| 47 | 47 | const async_id_symbol = Symbol('asyncId'); | |
| 48 | 48 | const trigger_async_id_symbol = Symbol('triggerAsyncId'); | |
| 49 | 49 | ||
| 50 | + /* This is an Uint32Array for easier sharing with C++ land. */ | ||
| 51 | + const scheduledImmediateCount = process._scheduledImmediateCount; | ||
| 52 | + delete process._scheduledImmediateCount; | ||
| 53 | + /* Kick off setImmediate processing */ | ||
| 54 | + const activateImmediateCheck = process._activateImmediateCheck; | ||
| 55 | + delete process._activateImmediateCheck; | ||
| 56 | + | ||
| 50 | 57 | // Timeout values > TIMEOUT_MAX are set to 1. | |
| 51 | 58 | const TIMEOUT_MAX = 2147483647; // 2^31-1 | |
| 52 | 59 | ||
@@ -742,15 +749,9 @@ function processImmediate() { | |||
| 742 | 749 | else | |
| 743 | 750 | immediate = next; | |
| 744 | 751 | } | |
| 745 | - | ||
| 746 | - // Only round-trip to C++ land if we have to. Calling clearImmediate() on an | ||
| 747 | - // immediate that's in |queue| is okay. Worst case is we make a superfluous | ||
| 748 | - // call to NeedImmediateCallbackSetter(). | ||
| 749 | - if (!immediateQueue.head) { | ||
| 750 | - process._needImmediateCallback = false; | ||
| 751 | - } | ||
| 752 | 752 | } | |
| 753 | 753 | ||
| 754 | + process._immediateCallback = processImmediate; | ||
| 754 | 755 | ||
| 755 | 756 | // An optimization so that the try/finally only de-optimizes (since at least v8 | |
| 756 | 757 | // 4.7) what is in this smaller function. | |
@@ -762,13 +763,17 @@ function tryOnImmediate(immediate, oldTail) { | |||
| 762 | 763 | runCallback(immediate); | |
| 763 | 764 | threw = false; | |
| 764 | 765 | } finally { | |
| 765 | - // clearImmediate checks _onImmediate === null for kDestroy hooks. | ||
| 766 | 766 | immediate._onImmediate = null; | |
| 767 | 767 | if (!threw) | |
| 768 | 768 | emitAfter(immediate[async_id_symbol]); | |
| 769 | - if (async_hook_fields[kDestroy] > 0 && !immediate._destroyed) { | ||
| 770 | - emitDestroy(immediate[async_id_symbol]); | ||
| 769 | + | ||
| 770 | + if (!immediate._destroyed) { | ||
| 771 | 771 | immediate._destroyed = true; | |
| 772 | + scheduledImmediateCount[0]--; | ||
| 773 | + | ||
| 774 | + if (async_hook_fields[kDestroy] > 0) { | ||
| 775 | + emitDestroy(immediate[async_id_symbol]); | ||
| 776 | + } | ||
| 772 | 777 | } | |
| 773 | 778 | ||
| 774 | 779 | if (threw && immediate._idleNext) { | |
@@ -870,10 +875,9 @@ function createImmediate(args, callback) { | |||
| 870 | 875 | immediate._argv = args; | |
| 871 | 876 | immediate._onImmediate = callback; | |
| 872 | 877 | ||
| 873 | - if (!process._needImmediateCallback) { | ||
| 874 | - process._needImmediateCallback = true; | ||
| 875 | - process._immediateCallback = processImmediate; | ||
| 876 | - } | ||
| 878 | + if (scheduledImmediateCount[0] === 0) | ||
| 879 | + activateImmediateCheck(); | ||
| 880 | + scheduledImmediateCount[0]++; | ||
| 877 | 881 | ||
| 878 | 882 | immediateQueue.append(immediate); | |
| 879 | 883 | ||
@@ -884,18 +888,16 @@ function createImmediate(args, callback) { | |||
| 884 | 888 | exports.clearImmediate = function(immediate) { | |
| 885 | 889 | if (!immediate) return; | |
| 886 | 890 | ||
| 887 | - if (async_hook_fields[kDestroy] > 0 && | ||
| 888 | - immediate._onImmediate !== null && | ||
| 889 | - !immediate._destroyed) { | ||
| 890 | - emitDestroy(immediate[async_id_symbol]); | ||
| 891 | + if (!immediate._destroyed) { | ||
| 892 | + scheduledImmediateCount[0]--; | ||
| 891 | 893 | immediate._destroyed = true; | |
| 894 | + | ||
| 895 | + if (async_hook_fields[kDestroy] > 0) { | ||
| 896 | + emitDestroy(immediate[async_id_symbol]); | ||
| 897 | + } | ||
| 892 | 898 | } | |
| 893 | 899 | ||
| 894 | 900 | immediate._onImmediate = null; | |
| 895 | 901 | ||
| 896 | 902 | immediateQueue.remove(immediate); | |
| 897 | - | ||
| 898 | - if (!immediateQueue.head) { | ||
| 899 | - process._needImmediateCallback = false; | ||
| 900 | - } | ||
| 901 | 903 | }; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -267,6 +267,7 @@ inline Environment::Environment(IsolateData* isolate_data, | |||
| 267 | 267 | abort_on_uncaught_exception_(false), | |
| 268 | 268 | emit_napi_warning_(true), | |
| 269 | 269 | makecallback_cntr_(0), | |
| 270 | + scheduled_immediate_count_(isolate_, 1), | ||
| 270 | 271 | #if HAVE_INSPECTOR | |
| 271 | 272 | inspector_agent_(new inspector::Agent(this)), | |
| 272 | 273 | #endif | |
@@ -486,6 +487,11 @@ inline void Environment::set_fs_stats_field_array(double* fields) { | |||
| 486 | 487 | fs_stats_field_array_ = fields; | |
| 487 | 488 | } | |
| 488 | 489 | ||
| 490 | + inline AliasedBuffer<uint32_t, v8::Uint32Array>& | ||
| 491 | + Environment::scheduled_immediate_count() { | ||
| 492 | + return scheduled_immediate_count_; | ||
| 493 | + } | ||
| 494 | + | ||
| 489 | 495 | inline performance::performance_state* Environment::performance_state() { | |
| 490 | 496 | return performance_state_; | |
| 491 | 497 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -601,6 +601,8 @@ class Environment { | |||
| 601 | 601 | inline double* fs_stats_field_array() const; | |
| 602 | 602 | inline void set_fs_stats_field_array(double* fields); | |
| 603 | 603 | ||
| 604 | + inline AliasedBuffer<uint32_t, v8::Uint32Array>& scheduled_immediate_count(); | ||
| 605 | + | ||
| 604 | 606 | inline performance::performance_state* performance_state(); | |
| 605 | 607 | inline std::map<std::string, uint64_t>* performance_marks(); | |
| 606 | 608 | ||
@@ -696,6 +698,8 @@ class Environment { | |||
| 696 | 698 | size_t makecallback_cntr_; | |
| 697 | 699 | std::vector<double> destroy_async_id_list_; | |
| 698 | 700 | ||
| 701 | + AliasedBuffer<uint32_t, v8::Uint32Array> scheduled_immediate_count_; | ||
| 702 | + | ||
| 699 | 703 | performance::performance_state* performance_state_ = nullptr; | |
| 700 | 704 | std::map<std::string, uint64_t> performance_marks_; | |
| 701 | 705 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -399,25 +399,6 @@ static void PrintErrorString(const char* format, ...) { | |||
| 399 | 399 | } | |
| 400 | 400 | ||
| 401 | 401 | ||
| 402 | - static void CheckImmediate(uv_check_t* handle) { | ||
| 403 | - Environment* env = Environment::from_immediate_check_handle(handle); | ||
| 404 | - HandleScope scope(env->isolate()); | ||
| 405 | - Context::Scope context_scope(env->context()); | ||
| 406 | - MakeCallback(env->isolate(), | ||
| 407 | - env->process_object(), | ||
| 408 | - env->immediate_callback_string(), | ||
| 409 | - 0, | ||
| 410 | - nullptr, | ||
| 411 | - {0, 0}).ToLocalChecked(); | ||
| 412 | - } | ||
| 413 | - | ||
| 414 | - | ||
| 415 | - static void IdleImmediateDummy(uv_idle_t* handle) { | ||
| 416 | - // Do nothing. Only for maintaining event loop. | ||
| 417 | - // TODO(bnoordhuis) Maybe make libuv accept nullptr idle callbacks. | ||
| 418 | - } | ||
| 419 | - | ||
| 420 | - | ||
| 421 | 402 | static inline const char *errno_string(int errorno) { | |
| 422 | 403 | #define ERRNO_CASE(e) case e: return #e; | |
| 423 | 404 | switch (errorno) { | |
@@ -3274,39 +3255,40 @@ static void DebugEnd(const FunctionCallbackInfo<Value>& args); | |||
| 3274 | 3255 | ||
| 3275 | 3256 | namespace { | |
| 3276 | 3257 | ||
| 3277 | - void NeedImmediateCallbackGetter(Local<Name> property, | ||
| 3278 | - const PropertyCallbackInfo<Value>& info) { | ||
| 3279 | - Environment* env = Environment::GetCurrent(info); | ||
| 3280 | - const uv_check_t* immediate_check_handle = env->immediate_check_handle(); | ||
| 3281 | - bool active = uv_is_active( | ||
| 3282 | - reinterpret_cast<const uv_handle_t*>(immediate_check_handle)); | ||
| 3283 | - info.GetReturnValue().Set(active); | ||
| 3258 | + bool MaybeStopImmediate(Environment* env) { | ||
| 3259 | + if (env->scheduled_immediate_count()[0] == 0) { | ||
| 3260 | + uv_check_stop(env->immediate_check_handle()); | ||
| 3261 | + uv_idle_stop(env->immediate_idle_handle()); | ||
| 3262 | + return true; | ||
| 3263 | + } | ||
| 3264 | + return false; | ||
| 3284 | 3265 | } | |
| 3285 | 3266 | ||
| 3267 | + void CheckImmediate(uv_check_t* handle) { | ||
| 3268 | + Environment* env = Environment::from_immediate_check_handle(handle); | ||
| 3269 | + HandleScope scope(env->isolate()); | ||
| 3270 | + Context::Scope context_scope(env->context()); | ||
| 3286 | 3271 | ||
| 3287 | - void NeedImmediateCallbackSetter( | ||
| 3288 | - Local<Name> property, | ||
| 3289 | - Local<Value> value, | ||
| 3290 | - const PropertyCallbackInfo<void>& info) { | ||
| 3291 | - Environment* env = Environment::GetCurrent(info); | ||
| 3272 | + if (MaybeStopImmediate(env)) | ||
| 3273 | + return; | ||
| 3292 | 3274 | ||
| 3293 | - uv_check_t* immediate_check_handle = env->immediate_check_handle(); | ||
| 3294 | - bool active = uv_is_active( | ||
| 3295 | - reinterpret_cast<const uv_handle_t*>(immediate_check_handle)); | ||
| 3275 | + MakeCallback(env->isolate(), | ||
| 3276 | + env->process_object(), | ||
| 3277 | + env->immediate_callback_string(), | ||
| 3278 | + 0, | ||
| 3279 | + nullptr, | ||
| 3280 | + {0, 0}).ToLocalChecked(); | ||
| 3296 | 3281 | ||
| 3297 | - if (active == value->BooleanValue()) | ||
| 3298 | - return; | ||
| 3282 | + MaybeStopImmediate(env); | ||
| 3283 | + } | ||
| 3299 | 3284 | ||
| 3300 | - uv_idle_t* immediate_idle_handle = env->immediate_idle_handle(); | ||
| 3301 | 3285 | ||
| 3302 | - if (active) { | ||
| 3303 | - uv_check_stop(immediate_check_handle); | ||
| 3304 | - uv_idle_stop(immediate_idle_handle); | ||
| 3305 | - } else { | ||
| 3306 | - uv_check_start(immediate_check_handle, CheckImmediate); | ||
| 3307 | - // Idle handle is needed only to stop the event loop from blocking in poll. | ||
| 3308 | - uv_idle_start(immediate_idle_handle, IdleImmediateDummy); | ||
| 3309 | - } | ||
| 3286 | + void ActivateImmediateCheck(const FunctionCallbackInfo<Value>& args) { | ||
| 3287 | + Environment* env = Environment::GetCurrent(args); | ||
| 3288 | + uv_check_start(env->immediate_check_handle(), CheckImmediate); | ||
| 3289 | + // Idle handle is needed only to stop the event loop from blocking in poll. | ||
| 3290 | + uv_idle_start(env->immediate_idle_handle(), | ||
| 3291 | + [](uv_idle_t*){ /* do nothing, just keep the loop running */ }); | ||
| 3310 | 3292 | } | |
| 3311 | 3293 | ||
| 3312 | 3294 | ||
@@ -3533,12 +3515,11 @@ void SetupProcessObject(Environment* env, | |||
| 3533 | 3515 | FIXED_ONE_BYTE_STRING(env->isolate(), "ppid"), | |
| 3534 | 3516 | GetParentProcessId).FromJust()); | |
| 3535 | 3517 | ||
| 3536 | - auto need_immediate_callback_string = | ||
| 3537 | - FIXED_ONE_BYTE_STRING(env->isolate(), "_needImmediateCallback"); | ||
| 3538 | - CHECK(process->SetAccessor(env->context(), need_immediate_callback_string, | ||
| 3539 | - NeedImmediateCallbackGetter, | ||
| 3540 | - NeedImmediateCallbackSetter, | ||
| 3541 | - env->as_external()).FromJust()); | ||
| 3518 | + auto scheduled_immediate_count = | ||
| 3519 | + FIXED_ONE_BYTE_STRING(env->isolate(), "_scheduledImmediateCount"); | ||
| 3520 | + CHECK(process->Set(env->context(), | ||
| 3521 | + scheduled_immediate_count, | ||
| 3522 | + env->scheduled_immediate_count().GetJSArray()).FromJust()); | ||
| 3542 | 3523 | ||
| 3543 | 3524 | // -e, --eval | |
| 3544 | 3525 | if (eval_string) { | |
@@ -3664,6 +3645,9 @@ void SetupProcessObject(Environment* env, | |||
| 3664 | 3645 | env->as_external()).FromJust()); | |
| 3665 | 3646 | ||
| 3666 | 3647 | // define various internal methods | |
| 3648 | + env->SetMethod(process, | ||
| 3649 | + "_activateImmediateCheck", | ||
| 3650 | + ActivateImmediateCheck); | ||
| 3667 | 3651 | env->SetMethod(process, | |
| 3668 | 3652 | "_startProfilerIdleNotifier", | |
| 3669 | 3653 | StartProfilerIdleNotifier); | |
| Back | FazBrowse Home | New Git URL |
0 commit comments