Skip to content

Commit

Permalink
fs: fix nonNativeWatcher leak of StatWatchers
Browse files Browse the repository at this point in the history
PR-URL: #45501
Reviewed-By: Yagiz Nizipli <[email protected]>
  • Loading branch information
MoLow authored and targos committed Dec 12, 2022
1 parent 1784768 commit d272faa
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 6 deletions.
9 changes: 3 additions & 6 deletions lib/internal/fs/recursive_watch.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,14 +154,11 @@ class FSWatcher extends EventEmitter {
this.#symbolicFiles.add(f);
}

this.#files.set(f, file);
if (file.isFile()) {
this.#watchFile(f);
} else {
this.#files.set(f, file);

if (file.isDirectory() && !file.isSymbolicLink()) {
await this.#watchFolder(f);
}
} else if (file.isDirectory() && !file.isSymbolicLink()) {
await this.#watchFolder(f);
}
}
}
Expand Down
27 changes: 27 additions & 0 deletions test/parallel/test-fs-watch-recursive.js
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,33 @@ tmpdir.refresh();
});
})().then(common.mustCall());


(async () => {
// Assert recursive watch does not leak handles
const rootDirectory = fs.mkdtempSync(testDir + path.sep);
const testDirectory = path.join(rootDirectory, 'test-7');
const filePath = path.join(testDirectory, 'only-file.txt');
fs.mkdirSync(testDirectory);

let watcherClosed = false;
const watcher = fs.watch(testDirectory, { recursive: true });
watcher.on('change', common.mustCallAtLeast(async (event, filename) => {
await setTimeout(common.platformTimeout(100));
if (filename === path.basename(filePath)) {
watcher.close();
watcherClosed = true;
}
await setTimeout(common.platformTimeout(100));
assert(!process._getActiveHandles().some((handle) => handle.constructor.name === 'StatWatcher'));
}));

process.on('exit', function() {
assert(watcherClosed, 'watcher Object was not closed');
});
await setTimeout(common.platformTimeout(100));
fs.writeFileSync(filePath, 'content');
})().then(common.mustCall());

(async () => {
// Handle non-boolean values for options.recursive

Expand Down

0 comments on commit d272faa

Please sign in to comment.