Skip to content

Commit 911c39d

Browse files
authored
Fixes to compile commands file watchers fallback logic (#12948)
* close file watchers before clearing the array * keep track of fallback time per file
1 parent c9cae0b commit 911c39d

File tree

1 file changed

+32
-5
lines changed

1 file changed

+32
-5
lines changed

Extension/src/LanguageServer/configurations.ts

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ export class CppProperties {
138138
private configFileWatcherFallbackTime: Date = new Date(); // Used when file watching fails.
139139
private compileCommandsFile: vscode.Uri | undefined | null = undefined;
140140
private compileCommandsFileWatchers: fs.FSWatcher[] = [];
141-
private compileCommandsFileWatcherFallbackTime: Date = new Date(); // Used when file watching fails.
141+
private compileCommandsFileWatcherFallbackTime: Map<string, Date> = new Map<string, Date>(); // Used when file watching fails.
142142
private defaultCompilerPath: string | null = null;
143143
private knownCompilers?: KnownCompiler[];
144144
private defaultCStandard: string | null = null;
@@ -1093,6 +1093,10 @@ export class CppProperties {
10931093

10941094
if (configuration.compileCommands) {
10951095
configuration.compileCommands = this.resolvePath(configuration.compileCommands);
1096+
if (!this.compileCommandsFileWatcherFallbackTime.has(configuration.compileCommands)) {
1097+
// Start tracking the fallback time for a new path.
1098+
this.compileCommandsFileWatcherFallbackTime.set(configuration.compileCommands, new Date());
1099+
}
10961100
}
10971101

10981102
if (configuration.forcedInclude) {
@@ -1104,12 +1108,31 @@ export class CppProperties {
11041108
}
11051109
}
11061110

1111+
this.clearStaleCompileCommandsFileWatcherFallbackTimes();
11071112
this.updateCompileCommandsFileWatchers();
11081113
if (!this.configurationIncomplete) {
11091114
this.onConfigurationsChanged();
11101115
}
11111116
}
11121117

1118+
private clearStaleCompileCommandsFileWatcherFallbackTimes(): void {
1119+
// We need to keep track of relevant timestamps, so we cannot simply clear all entries.
1120+
// Instead, we clear entries that are no longer relevant.
1121+
const trackedCompileCommandsPaths: Set<string> = new Set();
1122+
this.configurationJson?.configurations.forEach((config: Configuration) => {
1123+
const path = this.resolvePath(config.compileCommands);
1124+
if (path.length > 0) {
1125+
trackedCompileCommandsPaths.add(path);
1126+
}
1127+
});
1128+
1129+
for (const path of this.compileCommandsFileWatcherFallbackTime.keys()) {
1130+
if (!trackedCompileCommandsPaths.has(path)) {
1131+
this.compileCommandsFileWatcherFallbackTime.delete(path);
1132+
}
1133+
}
1134+
}
1135+
11131136
private compileCommandsFileWatcherTimer?: NodeJS.Timeout;
11141137
private compileCommandsFileWatcherFiles: Set<string> = new Set<string>();
11151138

@@ -2310,14 +2333,18 @@ export class CppProperties {
23102333
fs.stat(compileCommandsFile, (err, stats) => {
23112334
if (err) {
23122335
if (err.code === "ENOENT" && this.compileCommandsFile) {
2336+
this.compileCommandsFileWatchers.forEach((watcher: fs.FSWatcher) => watcher.close());
23132337
this.compileCommandsFileWatchers = []; // reset file watchers
23142338
this.onCompileCommandsChanged(compileCommandsFile);
23152339
this.compileCommandsFile = null; // File deleted
23162340
}
2317-
} else if (stats.mtime > this.compileCommandsFileWatcherFallbackTime) {
2318-
this.compileCommandsFileWatcherFallbackTime = new Date();
2319-
this.onCompileCommandsChanged(compileCommandsFile);
2320-
this.compileCommandsFile = vscode.Uri.file(compileCommandsFile); // File created.
2341+
} else {
2342+
const compileCommandsLastChanged: Date | undefined = this.compileCommandsFileWatcherFallbackTime.get(compileCommandsFile);
2343+
if (compileCommandsLastChanged !== undefined && stats.mtime > compileCommandsLastChanged) {
2344+
this.compileCommandsFileWatcherFallbackTime.set(compileCommandsFile, new Date());
2345+
this.onCompileCommandsChanged(compileCommandsFile);
2346+
this.compileCommandsFile = vscode.Uri.file(compileCommandsFile); // File created.
2347+
}
23212348
}
23222349
});
23232350
}

0 commit comments

Comments
 (0)