| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 54fe0a6 commit bb5575a
5 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -57,11 +57,10 @@ const { | |||
| 57 | 57 | const { | |
| 58 | 58 | kTimeout, | |
| 59 | 59 | setUnrefTimeout, | |
| 60 | - validateTimerDuration | ||
| 60 | + validateTimerDuration, | ||
| 61 | + refreshFnSymbol | ||
| 61 | 62 | } = require('internal/timers'); | |
| 62 | 63 | ||
| 63 | - const { _unrefActive } = require('timers'); | ||
| 64 | - | ||
| 65 | 64 | const { ShutdownWrap, WriteWrap } = process.binding('stream_wrap'); | |
| 66 | 65 | const { constants } = binding; | |
| 67 | 66 | ||
@@ -912,7 +911,7 @@ class Http2Session extends EventEmitter { | |||
| 912 | 911 | [kUpdateTimer]() { | |
| 913 | 912 | if (this.destroyed) | |
| 914 | 913 | return; | |
| 915 | - if (this[kTimeout]) _unrefActive(this[kTimeout]); | ||
| 914 | + if (this[kTimeout]) this[kTimeout][refreshFnSymbol](); | ||
| 916 | 915 | } | |
| 917 | 916 | ||
| 918 | 917 | // Sets the id of the next stream to be created by this Http2Session. | |
@@ -1478,7 +1477,7 @@ class Http2Stream extends Duplex { | |||
| 1478 | 1477 | if (this.destroyed) | |
| 1479 | 1478 | return; | |
| 1480 | 1479 | if (this[kTimeout]) | |
| 1481 | - _unrefActive(this[kTimeout]); | ||
| 1480 | + this[kTimeout][refreshFnSymbol](); | ||
| 1482 | 1481 | if (this[kSession]) | |
| 1483 | 1482 | this[kSession][kUpdateTimer](); | |
| 1484 | 1483 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -19,12 +19,16 @@ const errors = require('internal/errors'); | |||
| 19 | 19 | // Timeout values > TIMEOUT_MAX are set to 1. | |
| 20 | 20 | const TIMEOUT_MAX = 2 ** 31 - 1; | |
| 21 | 21 | ||
| 22 | + const refreshFnSymbol = Symbol('refresh()'); | ||
| 23 | + const unrefedSymbol = Symbol('unrefed'); | ||
| 24 | + | ||
| 22 | 25 | module.exports = { | |
| 23 | 26 | TIMEOUT_MAX, | |
| 24 | 27 | kTimeout: Symbol('timeout'), // For hiding Timeouts on other internals. | |
| 25 | 28 | async_id_symbol, | |
| 26 | 29 | trigger_async_id_symbol, | |
| 27 | 30 | Timeout, | |
| 31 | + refreshFnSymbol, | ||
| 28 | 32 | setUnrefTimeout, | |
| 29 | 33 | validateTimerDuration | |
| 30 | 34 | }; | |
@@ -39,7 +43,7 @@ function getTimers() { | |||
| 39 | 43 | ||
| 40 | 44 | // Timer constructor function. | |
| 41 | 45 | // The entire prototype is defined in lib/timers.js | |
| 42 | - function Timeout(callback, after, args, isRepeat) { | ||
| 46 | + function Timeout(callback, after, args, isRepeat, isUnrefed) { | ||
| 43 | 47 | after *= 1; // coalesce to number or NaN | |
| 44 | 48 | if (!(after >= 1 && after <= TIMEOUT_MAX)) { | |
| 45 | 49 | if (after > TIMEOUT_MAX) { | |
@@ -64,6 +68,8 @@ function Timeout(callback, after, args, isRepeat) { | |||
| 64 | 68 | this._repeat = isRepeat ? after : null; | |
| 65 | 69 | this._destroyed = false; | |
| 66 | 70 | ||
| 71 | + this[unrefedSymbol] = isUnrefed; | ||
| 72 | + | ||
| 67 | 73 | this[async_id_symbol] = ++async_id_fields[kAsyncIdCounter]; | |
| 68 | 74 | this[trigger_async_id_symbol] = getDefaultTriggerAsyncId(); | |
| 69 | 75 | if (async_hook_fields[kInit] > 0) { | |
@@ -74,6 +80,19 @@ function Timeout(callback, after, args, isRepeat) { | |||
| 74 | 80 | } | |
| 75 | 81 | } | |
| 76 | 82 | ||
| 83 | + Timeout.prototype[refreshFnSymbol] = function refresh() { | ||
| 84 | + if (this._handle) { | ||
| 85 | + // Would be more ideal with uv_timer_again(), however that API does not | ||
| 86 | + // cause libuv's sorted timers data structure (a binary heap at the time | ||
| 87 | + // of writing) to re-sort itself. This causes ordering inconsistencies. | ||
| 88 | + this._handle.stop(); | ||
| 89 | + this._handle.start(this._idleTimeout); | ||
| 90 | + } else if (this[unrefedSymbol]) { | ||
| 91 | + getTimers()._unrefActive(this); | ||
| 92 | + } else { | ||
| 93 | + getTimers().active(this); | ||
| 94 | + } | ||
| 95 | + }; | ||
| 77 | 96 | ||
| 78 | 97 | function setUnrefTimeout(callback, after, arg1, arg2, arg3) { | |
| 79 | 98 | // Type checking identical to setTimeout() | |
@@ -102,7 +121,7 @@ function setUnrefTimeout(callback, after, arg1, arg2, arg3) { | |||
| 102 | 121 | break; | |
| 103 | 122 | } | |
| 104 | 123 | ||
| 105 | - const timer = new Timeout(callback, after, args, false); | ||
| 124 | + const timer = new Timeout(callback, after, args, false, true); | ||
| 106 | 125 | getTimers()._unrefActive(timer); | |
| 107 | 126 | ||
| 108 | 127 | return timer; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -23,7 +23,6 @@ | |||
| 23 | 23 | ||
| 24 | 24 | const EventEmitter = require('events'); | |
| 25 | 25 | const stream = require('stream'); | |
| 26 | - const timers = require('timers'); | ||
| 27 | 26 | const util = require('util'); | |
| 28 | 27 | const internalUtil = require('internal/util'); | |
| 29 | 28 | const { | |
@@ -64,7 +63,8 @@ const exceptionWithHostPort = util._exceptionWithHostPort; | |||
| 64 | 63 | const { | |
| 65 | 64 | kTimeout, | |
| 66 | 65 | setUnrefTimeout, | |
| 67 | - validateTimerDuration | ||
| 66 | + validateTimerDuration, | ||
| 67 | + refreshFnSymbol | ||
| 68 | 68 | } = require('internal/timers'); | |
| 69 | 69 | ||
| 70 | 70 | function noop() {} | |
@@ -291,7 +291,7 @@ util.inherits(Socket, stream.Duplex); | |||
| 291 | 291 | Socket.prototype._unrefTimer = function _unrefTimer() { | |
| 292 | 292 | for (var s = this; s !== null; s = s._parent) { | |
| 293 | 293 | if (s[kTimeout]) | |
| 294 | - timers._unrefActive(s[kTimeout]); | ||
| 294 | + s[kTimeout][refreshFnSymbol](); | ||
| 295 | 295 | } | |
| 296 | 296 | }; | |
| 297 | 297 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -432,15 +432,15 @@ function setTimeout(callback, after, arg1, arg2, arg3) { | |||
| 432 | 432 | break; | |
| 433 | 433 | } | |
| 434 | 434 | ||
| 435 | - const timeout = new Timeout(callback, after, args, false); | ||
| 435 | + const timeout = new Timeout(callback, after, args, false, false); | ||
| 436 | 436 | active(timeout); | |
| 437 | 437 | ||
| 438 | 438 | return timeout; | |
| 439 | 439 | } | |
| 440 | 440 | ||
| 441 | 441 | setTimeout[internalUtil.promisify.custom] = function(after, value) { | |
| 442 | 442 | const promise = createPromise(); | |
| 443 | - const timeout = new Timeout(promise, after, [value], false); | ||
| 443 | + const timeout = new Timeout(promise, after, [value], false, false); | ||
| 444 | 444 | active(timeout); | |
| 445 | 445 | ||
| 446 | 446 | return promise; | |
@@ -523,7 +523,7 @@ exports.setInterval = function(callback, repeat, arg1, arg2, arg3) { | |||
| 523 | 523 | break; | |
| 524 | 524 | } | |
| 525 | 525 | ||
| 526 | - const timeout = new Timeout(callback, repeat, args, true); | ||
| 526 | + const timeout = new Timeout(callback, repeat, args, true, false); | ||
| 527 | 527 | active(timeout); | |
| 528 | 528 | ||
| 529 | 529 | return timeout; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,59 @@ | |||
| 1 | + // Flags: --expose-internals | ||
| 2 | + | ||
| 3 | + 'use strict'; | ||
| 4 | + | ||
| 5 | + const common = require('../common'); | ||
| 6 | + | ||
| 7 | + const { strictEqual } = require('assert'); | ||
| 8 | + const { setUnrefTimeout, refreshFnSymbol } = require('internal/timers'); | ||
| 9 | + | ||
| 10 | + // Schedule the unrefed cases first so that the later case keeps the event loop | ||
| 11 | + // active. | ||
| 12 | + | ||
| 13 | + // Every case in this test relies on implicit sorting within either Node's or | ||
| 14 | + // libuv's timers storage data structures. | ||
| 15 | + | ||
| 16 | + // unref()'d timer | ||
| 17 | + { | ||
| 18 | + let called = false; | ||
| 19 | + const timer = setTimeout(common.mustCall(() => { | ||
| 20 | + called = true; | ||
| 21 | + }), 1); | ||
| 22 | + timer.unref(); | ||
| 23 | + | ||
| 24 | + // This relies on implicit timers handle sorting withing libuv. | ||
| 25 | + | ||
| 26 | + setTimeout(common.mustCall(() => { | ||
| 27 | + strictEqual(called, false, 'unref()\'d timer returned before check'); | ||
| 28 | + }), 1); | ||
| 29 | + | ||
| 30 | + timer[refreshFnSymbol](); | ||
| 31 | + } | ||
| 32 | + | ||
| 33 | + // unref pooled timer | ||
| 34 | + { | ||
| 35 | + let called = false; | ||
| 36 | + const timer = setUnrefTimeout(common.mustCall(() => { | ||
| 37 | + called = true; | ||
| 38 | + }), 1); | ||
| 39 | + | ||
| 40 | + setUnrefTimeout(common.mustCall(() => { | ||
| 41 | + strictEqual(called, false, 'unref pooled timer returned before check'); | ||
| 42 | + }), 1); | ||
| 43 | + | ||
| 44 | + timer[refreshFnSymbol](); | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + // regular timer | ||
| 48 | + { | ||
| 49 | + let called = false; | ||
| 50 | + const timer = setTimeout(common.mustCall(() => { | ||
| 51 | + called = true; | ||
| 52 | + }), 1); | ||
| 53 | + | ||
| 54 | + setTimeout(common.mustCall(() => { | ||
| 55 | + strictEqual(called, false, 'pooled timer returned before check'); | ||
| 56 | + }), 1); | ||
| 57 | + | ||
| 58 | + timer[refreshFnSymbol](); | ||
| 59 | + } | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments