Browse Source

fs: do not emit 'stop' watch event synchronously

Emits 'stop' event for fs.watchFile on process.nextTick
to fix 'maximum call stack size exceeded' error when
`stop` is called synchronously after listener is attached.

PR-URL: https://github.com/nodejs/node/pull/8524
Fixes: https://github.com/nodejs/node/issues/8421
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Ilkka Myller <ilkka.myller@nodefield.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Yorkie Liu <yorkiefixer@gmail.com>
v7.x
Claudio Rodriguez 8 years ago
committed by James M Snell
parent
commit
21124ba23a
  1. 6
      lib/fs.js
  2. 19
      test/parallel/test-fs-watch-stop-async.js
  3. 9
      test/parallel/test-fs-watch-stop-sync.js

6
lib/fs.js

@ -1443,6 +1443,10 @@ fs.watch = function(filename, options, listener) {
// Stat Change Watchers
function emitStop(self) {
self.emit('stop');
}
function StatWatcher() {
EventEmitter.call(this);
@ -1463,7 +1467,7 @@ function StatWatcher() {
};
this._handle.onstop = function() {
self.emit('stop');
process.nextTick(emitStop, self);
};
}
util.inherits(StatWatcher, EventEmitter);

19
test/parallel/test-fs-watch-stop-async.js

@ -0,0 +1,19 @@
'use strict';
const common = require('../common');
const assert = require('assert');
const fs = require('fs');
const watch = fs.watchFile(__filename, () => {});
let triggered;
const listener = common.mustCall(() => {
triggered = true;
});
triggered = false;
watch.once('stop', listener); // Should trigger.
watch.stop();
assert.equal(triggered, false);
setImmediate(() => {
assert.equal(triggered, true);
watch.removeListener('stop', listener);
});

9
test/parallel/test-fs-watch-stop-sync.js

@ -0,0 +1,9 @@
'use strict';
require('../common');
const assert = require('assert');
const fs = require('fs');
const watch = fs.watchFile(__filename, () => {});
watch.once('stop', assert.fail); // Should not trigger.
watch.stop();
watch.removeListener('stop', assert.fail);
Loading…
Cancel
Save