Browse Source

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.
v0.11.10-release
Vladimir Kurchatkin 11 years ago
committed by Trevor Norris
parent
commit
16a402c0b5
  1. 7
      src/node.js
  2. 45
      test/simple/test-asynclistener-remove-add-in-before.js
  3. 42
      test/simple/test-asynclistener-remove-in-before.js

7
src/node.js

@ -341,7 +341,7 @@
var item, before, i;
asyncStack.push(asyncQueue);
asyncQueue = queue;
asyncQueue = queue.slice();
// Since the async listener callback is required, the number of
// objects in the asyncQueue implies the number of async listeners
// there are to be processed.
@ -363,12 +363,13 @@
// Unload one level of the async stack. Returns true if there are
// still listeners somewhere in the stack.
function unloadAsyncQueue(context) {
var queue = context._asyncQueue;
var item, after, i;
// Run "after" callbacks.
inAsyncTick = true;
for (i = 0; i < asyncQueue.length; i++) {
item = asyncQueue[i];
for (i = 0; i < queue.length; i++) {
item = queue[i];
if (!item.callbacks)
continue;
after = item.callbacks.after;

45
test/simple/test-asynclistener-remove-add-in-before.js

@ -0,0 +1,45 @@
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
var common = require('../common');
var assert = require('assert');
var val;
var callbacks = {
before: function() {
process.removeAsyncListener(listener);
process.addAsyncListener(listener);
},
after: function(context, storage) {
val = storage;
}
};
var listener = process.addAsyncListener(function() {
return 66;
}, callbacks);
process.nextTick(function() {});
process.on('exit', function(status) {
process.removeAsyncListener(listener);
assert.equal(status, 0);
assert.equal(val, 66);
});

42
test/simple/test-asynclistener-remove-in-before.js

@ -0,0 +1,42 @@
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
var common = require('../common');
var assert = require('assert');
var done = false;
var callbacks = {
before: function() {
process.removeAsyncListener(listener);
},
after: function() {
done = true;
}
};
var listener = process.addAsyncListener(function() {}, callbacks);
process.nextTick(function() {});
process.on('exit', function(status) {
process.removeAsyncListener(listener);
assert.equal(status, 0);
assert.ok(done);
});
Loading…
Cancel
Save