Skip to content

Commit d272faa

Browse files
MoLowtargos
authored andcommitted
fs: fix nonNativeWatcher leak of StatWatchers
PR-URL: #45501 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
1 parent 1784768 commit d272faa

2 files changed

Lines changed: 30 additions & 6 deletions

File tree

‎lib/internal/fs/recursive_watch.js‎

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -154,14 +154,11 @@ class FSWatcher extends EventEmitter {
154154
this.#symbolicFiles.add(f);
155155
}
156156

157+
this.#files.set(f,file);
157158
if(file.isFile()){
158159
this.#watchFile(f);
159-
}else{
160-
this.#files.set(f,file);
161-
162-
if(file.isDirectory()&&!file.isSymbolicLink()){
163-
awaitthis.#watchFolder(f);
164-
}
160+
}elseif(file.isDirectory()&&!file.isSymbolicLink()){
161+
awaitthis.#watchFolder(f);
165162
}
166163
}
167164
}

‎test/parallel/test-fs-watch-recursive.js‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,33 @@ tmpdir.refresh();
213213
});
214214
})().then(common.mustCall());
215215

216+
217+
(async()=>{
218+
// Assert recursive watch does not leak handles
219+
constrootDirectory=fs.mkdtempSync(testDir+path.sep);
220+
consttestDirectory=path.join(rootDirectory,'test-7');
221+
constfilePath=path.join(testDirectory,'only-file.txt');
222+
fs.mkdirSync(testDirectory);
223+
224+
letwatcherClosed=false;
225+
constwatcher=fs.watch(testDirectory,{recursive: true});
226+
watcher.on('change',common.mustCallAtLeast(async(event,filename)=>{
227+
awaitsetTimeout(common.platformTimeout(100));
228+
if(filename===path.basename(filePath)){
229+
watcher.close();
230+
watcherClosed=true;
231+
}
232+
awaitsetTimeout(common.platformTimeout(100));
233+
assert(!process._getActiveHandles().some((handle)=>handle.constructor.name==='StatWatcher'));
234+
}));
235+
236+
process.on('exit',function(){
237+
assert(watcherClosed,'watcher Object was not closed');
238+
});
239+
awaitsetTimeout(common.platformTimeout(100));
240+
fs.writeFileSync(filePath,'content');
241+
})().then(common.mustCall());
242+
216243
(async()=>{
217244
// Handle non-boolean values for options.recursive
218245

0 commit comments

Comments
 (0)