Skip to content

Commit 21124ba

Browse files
claudiorodriguezjasnell
authored andcommitted
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: #8524 Fixes: #8421 Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Ilkka Myller <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Yorkie Liu <[email protected]>
1 parent 9dc9074 commit 21124ba

File tree

3 files changed

+33
-1
lines changed

3 files changed

+33
-1
lines changed

lib/fs.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -1443,6 +1443,10 @@ fs.watch = function(filename, options, listener) {
14431443

14441444
// Stat Change Watchers
14451445

1446+
function emitStop(self) {
1447+
self.emit('stop');
1448+
}
1449+
14461450
function StatWatcher() {
14471451
EventEmitter.call(this);
14481452

@@ -1463,7 +1467,7 @@ function StatWatcher() {
14631467
};
14641468

14651469
this._handle.onstop = function() {
1466-
self.emit('stop');
1470+
process.nextTick(emitStop, self);
14671471
};
14681472
}
14691473
util.inherits(StatWatcher, EventEmitter);
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
'use strict';
2+
const common = require('../common');
3+
const assert = require('assert');
4+
const fs = require('fs');
5+
6+
const watch = fs.watchFile(__filename, () => {});
7+
let triggered;
8+
const listener = common.mustCall(() => {
9+
triggered = true;
10+
});
11+
12+
triggered = false;
13+
watch.once('stop', listener); // Should trigger.
14+
watch.stop();
15+
assert.equal(triggered, false);
16+
setImmediate(() => {
17+
assert.equal(triggered, true);
18+
watch.removeListener('stop', listener);
19+
});
+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
'use strict';
2+
require('../common');
3+
const assert = require('assert');
4+
const fs = require('fs');
5+
6+
const watch = fs.watchFile(__filename, () => {});
7+
watch.once('stop', assert.fail); // Should not trigger.
8+
watch.stop();
9+
watch.removeListener('stop', assert.fail);

0 commit comments

Comments
 (0)