Skip to content

Commit 16a402c

Browse files
vkurchatkintrevnorris
authored andcommitted
node: fix removing AsyncListener in callback
context._asyncQueue shouldn't be exposed as asyncQueue, as it allows modification of queues already attached to an event. Which is not supposed to happend. Instead context._asyncQueue should be copied.
1 parent 5757642 commit 16a402c

File tree

3 files changed

+91
-3
lines changed

3 files changed

+91
-3
lines changed

src/node.js

+4-3
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@
341341
var item, before, i;
342342

343343
asyncStack.push(asyncQueue);
344-
asyncQueue = queue;
344+
asyncQueue = queue.slice();
345345
// Since the async listener callback is required, the number of
346346
// objects in the asyncQueue implies the number of async listeners
347347
// there are to be processed.
@@ -363,12 +363,13 @@
363363
// Unload one level of the async stack. Returns true if there are
364364
// still listeners somewhere in the stack.
365365
function unloadAsyncQueue(context) {
366+
var queue = context._asyncQueue;
366367
var item, after, i;
367368

368369
// Run "after" callbacks.
369370
inAsyncTick = true;
370-
for (i = 0; i < asyncQueue.length; i++) {
371-
item = asyncQueue[i];
371+
for (i = 0; i < queue.length; i++) {
372+
item = queue[i];
372373
if (!item.callbacks)
373374
continue;
374375
after = item.callbacks.after;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Copyright Joyent, Inc. and other Node contributors.
2+
//
3+
// Permission is hereby granted, free of charge, to any person obtaining a
4+
// copy of this software and associated documentation files (the
5+
// "Software"), to deal in the Software without restriction, including
6+
// without limitation the rights to use, copy, modify, merge, publish,
7+
// distribute, sublicense, and/or sell copies of the Software, and to permit
8+
// persons to whom the Software is furnished to do so, subject to the
9+
// following conditions:
10+
//
11+
// The above copyright notice and this permission notice shall be included
12+
// in all copies or substantial portions of the Software.
13+
//
14+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15+
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16+
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17+
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18+
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19+
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20+
// USE OR OTHER DEALINGS IN THE SOFTWARE.
21+
22+
var common = require('../common');
23+
var assert = require('assert');
24+
var val;
25+
var callbacks = {
26+
before: function() {
27+
process.removeAsyncListener(listener);
28+
process.addAsyncListener(listener);
29+
},
30+
after: function(context, storage) {
31+
val = storage;
32+
}
33+
};
34+
35+
var listener = process.addAsyncListener(function() {
36+
return 66;
37+
}, callbacks);
38+
39+
process.nextTick(function() {});
40+
41+
process.on('exit', function(status) {
42+
process.removeAsyncListener(listener);
43+
assert.equal(status, 0);
44+
assert.equal(val, 66);
45+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright Joyent, Inc. and other Node contributors.
2+
//
3+
// Permission is hereby granted, free of charge, to any person obtaining a
4+
// copy of this software and associated documentation files (the
5+
// "Software"), to deal in the Software without restriction, including
6+
// without limitation the rights to use, copy, modify, merge, publish,
7+
// distribute, sublicense, and/or sell copies of the Software, and to permit
8+
// persons to whom the Software is furnished to do so, subject to the
9+
// following conditions:
10+
//
11+
// The above copyright notice and this permission notice shall be included
12+
// in all copies or substantial portions of the Software.
13+
//
14+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15+
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16+
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17+
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18+
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19+
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20+
// USE OR OTHER DEALINGS IN THE SOFTWARE.
21+
22+
var common = require('../common');
23+
var assert = require('assert');
24+
var done = false;
25+
var callbacks = {
26+
before: function() {
27+
process.removeAsyncListener(listener);
28+
},
29+
after: function() {
30+
done = true;
31+
}
32+
};
33+
34+
var listener = process.addAsyncListener(function() {}, callbacks);
35+
36+
process.nextTick(function() {});
37+
38+
process.on('exit', function(status) {
39+
process.removeAsyncListener(listener);
40+
assert.equal(status, 0);
41+
assert.ok(done);
42+
});

0 commit comments

Comments
 (0)