Skip to content

Commit

Permalink
Fixes to compile commands file watchers fallback logic (#12948)
Browse files Browse the repository at this point in the history
* close file watchers before clearing the array
* keep track of fallback time per file
  • Loading branch information
yiftahw authored Nov 13, 2024
1 parent c9cae0b commit 911c39d
Showing 1 changed file with 32 additions and 5 deletions.
37 changes: 32 additions & 5 deletions Extension/src/LanguageServer/configurations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<string, Date> = new Map<string, Date>(); // Used when file watching fails.
private defaultCompilerPath: string | null = null;
private knownCompilers?: KnownCompiler[];
private defaultCStandard: string | null = null;
Expand Down Expand Up @@ -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) {
Expand All @@ -1104,12 +1108,31 @@ export class CppProperties {
}
}

this.clearStaleCompileCommandsFileWatcherFallbackTimes();
this.updateCompileCommandsFileWatchers();
if (!this.configurationIncomplete) {
this.onConfigurationsChanged();
}
}

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<string> = 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<string> = new Set<string>();

Expand Down Expand Up @@ -2310,14 +2333,18 @@ 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
}
} else if (stats.mtime > this.compileCommandsFileWatcherFallbackTime) {
this.compileCommandsFileWatcherFallbackTime = 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.
}
}
});
}
Expand Down

0 comments on commit 911c39d

Please sign in to comment.