From 7171bd6311f2511ed29de478a6788f739186e61b Mon Sep 17 00:00:00 2001 From: Brian White Date: Thu, 13 Oct 2016 18:02:52 -0400 Subject: [PATCH] timers: fix regression with clearImmediate() This commit fixes a regression introduced in 0ed8839a27 that caused additional queued immediate callbacks to be ignored if `clearImmediate(immediate)` was called within the callback for `immediate`. PR-URL: https://github.com/nodejs/node/pull/9086 Fixes: https://github.com/nodejs/node/issues/9084 Reviewed-By: Rich Trott Reviewed-By: Jeremiah Senkpiel Reviewed-By: James M Snell Reviewed-By: Evan Lucas --- lib/timers.js | 11 ++++++++++- test/parallel/test-timers-clearImmediate.js | 18 ++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 test/parallel/test-timers-clearImmediate.js diff --git a/lib/timers.js b/lib/timers.js index d247c4001c..78953f25d5 100644 --- a/lib/timers.js +++ b/lib/timers.js @@ -575,12 +575,21 @@ function processImmediate() { domain.enter(); immediate._callback = immediate._onImmediate; + + // Save next in case `clearImmediate(immediate)` is called from callback + var next = immediate._idleNext; + tryOnImmediate(immediate, tail); if (domain) domain.exit(); - immediate = immediate._idleNext; + // If `clearImmediate(immediate)` wasn't called from the callback, use the + // `immediate`'s next item + if (immediate._idleNext) + immediate = immediate._idleNext; + else + immediate = next; } // Only round-trip to C++ land if we have to. Calling clearImmediate() on an diff --git a/test/parallel/test-timers-clearImmediate.js b/test/parallel/test-timers-clearImmediate.js new file mode 100644 index 0000000000..ab65b7bf1c --- /dev/null +++ b/test/parallel/test-timers-clearImmediate.js @@ -0,0 +1,18 @@ +'use strict'; +require('../common'); +const assert = require('assert'); + +const N = 3; +var count = 0; +function next() { + const immediate = setImmediate(function() { + clearImmediate(immediate); + ++count; + }); +} +for (var i = 0; i < N; ++i) + next(); + +process.on('exit', () => { + assert.strictEqual(count, N, `Expected ${N} immediate callback executions`); +});