From 07cc950d62de866501eeb9946b67cbd66815d38f Mon Sep 17 00:00:00 2001 From: yiftahw <63462505+yiftahw@users.noreply.github.com> Date: Sat, 9 Nov 2024 22:03:23 +0200 Subject: [PATCH 1/5] close file watchers before clearing the array --- Extension/src/LanguageServer/configurations.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Extension/src/LanguageServer/configurations.ts b/Extension/src/LanguageServer/configurations.ts index 3339514cc2..23ab40f6f3 100644 --- a/Extension/src/LanguageServer/configurations.ts +++ b/Extension/src/LanguageServer/configurations.ts @@ -1116,6 +1116,7 @@ export class CppProperties { // Dispose existing and loop through cpp and populate with each file (exists or not) as you go. // paths are expected to have variables resolved already public updateCompileCommandsFileWatchers(): void { + console.log("updating file watchers"); if (this.configurationJson) { this.compileCommandsFileWatchers.forEach((watcher: fs.FSWatcher) => watcher.close()); this.compileCommandsFileWatchers = []; // reset it @@ -2310,6 +2311,7 @@ export class CppProperties { fs.stat(compileCommandsFile, (err, stats) => { if (err) { if (err.code === "ENOENT" && this.compileCommandsFile) { + this.compileCommandsFileWatchers.forEach((watcher: fs.FSWatcher) => watcher.close()); this.compileCommandsFileWatchers = []; // reset file watchers this.onCompileCommandsChanged(compileCommandsFile); this.compileCommandsFile = null; // File deleted From e79c6b24391022d5a82a25a94f5351d30400ac3d Mon Sep 17 00:00:00 2001 From: yiftahw <63462505+yiftahw@users.noreply.github.com> Date: Sat, 9 Nov 2024 22:27:50 +0200 Subject: [PATCH 2/5] keep track of fallback time per file --- .../src/LanguageServer/configurations.ts | 28 +++++++++++++++++-- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/Extension/src/LanguageServer/configurations.ts b/Extension/src/LanguageServer/configurations.ts index 23ab40f6f3..953fdcd8cb 100644 --- a/Extension/src/LanguageServer/configurations.ts +++ b/Extension/src/LanguageServer/configurations.ts @@ -138,7 +138,7 @@ export class CppProperties { private configFileWatcherFallbackTime: Date = new Date(); // Used when file watching fails. private compileCommandsFile: vscode.Uri | undefined | null = undefined; private compileCommandsFileWatchers: fs.FSWatcher[] = []; - private compileCommandsFileWatcherFallbackTime: Date = new Date(); // Used when file watching fails. + private compileCommandsFileWatcherFallbackTime: Map = new Map(); // Used when file watching fails. private defaultCompilerPath: string | null = null; private knownCompilers?: KnownCompiler[]; private defaultCStandard: string | null = null; @@ -1093,6 +1093,10 @@ export class CppProperties { if (configuration.compileCommands) { configuration.compileCommands = this.resolvePath(configuration.compileCommands); + if (!this.compileCommandsFileWatcherFallbackTime.has(configuration.compileCommands)) { + // Start tracking the fallback time for a new path. + this.compileCommandsFileWatcherFallbackTime.set(configuration.compileCommands, new Date()); + } } if (configuration.forcedInclude) { @@ -1104,12 +1108,29 @@ export class CppProperties { } } + this.clearStaleCompileCommandsFileWatcherFallbackTimes(); this.updateCompileCommandsFileWatchers(); if (!this.configurationIncomplete) { this.onConfigurationsChanged(); } } + private clearStaleCompileCommandsFileWatcherFallbackTimes(): void { + const trackedCompileCommandsPaths: Set = new Set(); + this.configurationJson?.configurations.forEach((config: Configuration) => { + const path = this.resolvePath(config.compileCommands); + if (path.length > 0) { + trackedCompileCommandsPaths.add(path); + } + }); + + for (const path of this.compileCommandsFileWatcherFallbackTime.keys()) { + if (!trackedCompileCommandsPaths.has(path)) { + this.compileCommandsFileWatcherFallbackTime.delete(path); + } + } + } + private compileCommandsFileWatcherTimer?: NodeJS.Timeout; private compileCommandsFileWatcherFiles: Set = new Set(); @@ -2308,6 +2329,7 @@ export class CppProperties { return; } const compileCommandsFile: string | undefined = this.resolvePath(compileCommands); + const compileCommandsLastChanged: Date | undefined = this.compileCommandsFileWatcherFallbackTime.get(compileCommandsFile); fs.stat(compileCommandsFile, (err, stats) => { if (err) { if (err.code === "ENOENT" && this.compileCommandsFile) { @@ -2316,8 +2338,8 @@ export class CppProperties { this.onCompileCommandsChanged(compileCommandsFile); this.compileCommandsFile = null; // File deleted } - } else if (stats.mtime > this.compileCommandsFileWatcherFallbackTime) { - this.compileCommandsFileWatcherFallbackTime = new Date(); + } else if (compileCommandsLastChanged !== undefined && stats.mtime > compileCommandsLastChanged) { + this.compileCommandsFileWatcherFallbackTime.set(compileCommandsFile, new Date()); this.onCompileCommandsChanged(compileCommandsFile); this.compileCommandsFile = vscode.Uri.file(compileCommandsFile); // File created. } From f95689355a814ad15cabbdfc89a4ad267b935c4e Mon Sep 17 00:00:00 2001 From: yiftahw <63462505+yiftahw@users.noreply.github.com> Date: Sat, 9 Nov 2024 22:51:00 +0200 Subject: [PATCH 3/5] remove print --- Extension/src/LanguageServer/configurations.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/Extension/src/LanguageServer/configurations.ts b/Extension/src/LanguageServer/configurations.ts index 953fdcd8cb..86580e1fba 100644 --- a/Extension/src/LanguageServer/configurations.ts +++ b/Extension/src/LanguageServer/configurations.ts @@ -1137,7 +1137,6 @@ export class CppProperties { // Dispose existing and loop through cpp and populate with each file (exists or not) as you go. // paths are expected to have variables resolved already public updateCompileCommandsFileWatchers(): void { - console.log("updating file watchers"); if (this.configurationJson) { this.compileCommandsFileWatchers.forEach((watcher: fs.FSWatcher) => watcher.close()); this.compileCommandsFileWatchers = []; // reset it From 3ea800970f0d8d58565a011f8ddb45e8f7834990 Mon Sep 17 00:00:00 2001 From: yiftahw <63462505+yiftahw@users.noreply.github.com> Date: Sat, 9 Nov 2024 23:59:59 +0200 Subject: [PATCH 4/5] add comment --- Extension/src/LanguageServer/configurations.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Extension/src/LanguageServer/configurations.ts b/Extension/src/LanguageServer/configurations.ts index 86580e1fba..fac1b5e056 100644 --- a/Extension/src/LanguageServer/configurations.ts +++ b/Extension/src/LanguageServer/configurations.ts @@ -1116,6 +1116,8 @@ export class CppProperties { } private clearStaleCompileCommandsFileWatcherFallbackTimes(): void { + // We need to keep track of relevant timestamps, so we cannot simply clear all entries. + // Instead, we clear entries that are no longer relevant. const trackedCompileCommandsPaths: Set = new Set(); this.configurationJson?.configurations.forEach((config: Configuration) => { const path = this.resolvePath(config.compileCommands); From 5ffcb8001a3e920dde94270807df9dd495eb7592 Mon Sep 17 00:00:00 2001 From: yiftahw <63462505+yiftahw@users.noreply.github.com> Date: Tue, 12 Nov 2024 04:56:55 +0200 Subject: [PATCH 5/5] move call to get fallback time --- Extension/src/LanguageServer/configurations.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Extension/src/LanguageServer/configurations.ts b/Extension/src/LanguageServer/configurations.ts index fac1b5e056..6f23eb3479 100644 --- a/Extension/src/LanguageServer/configurations.ts +++ b/Extension/src/LanguageServer/configurations.ts @@ -2330,7 +2330,6 @@ export class CppProperties { return; } const compileCommandsFile: string | undefined = this.resolvePath(compileCommands); - const compileCommandsLastChanged: Date | undefined = this.compileCommandsFileWatcherFallbackTime.get(compileCommandsFile); fs.stat(compileCommandsFile, (err, stats) => { if (err) { if (err.code === "ENOENT" && this.compileCommandsFile) { @@ -2339,10 +2338,13 @@ export class CppProperties { this.onCompileCommandsChanged(compileCommandsFile); this.compileCommandsFile = null; // File deleted } - } else if (compileCommandsLastChanged !== undefined && stats.mtime > compileCommandsLastChanged) { - this.compileCommandsFileWatcherFallbackTime.set(compileCommandsFile, new Date()); - this.onCompileCommandsChanged(compileCommandsFile); - this.compileCommandsFile = vscode.Uri.file(compileCommandsFile); // File created. + } else { + const compileCommandsLastChanged: Date | undefined = this.compileCommandsFileWatcherFallbackTime.get(compileCommandsFile); + if (compileCommandsLastChanged !== undefined && stats.mtime > compileCommandsLastChanged) { + this.compileCommandsFileWatcherFallbackTime.set(compileCommandsFile, new Date()); + this.onCompileCommandsChanged(compileCommandsFile); + this.compileCommandsFile = vscode.Uri.file(compileCommandsFile); // File created. + } } }); }