diff --git a/src/vs/base/node/config.ts b/src/vs/base/node/config.ts index d08120cfbfcd07925068d17c07fa17f06cfed4cb..31eea31a6bd65aff85e87f57e400da29a4bd10fc 100644 --- a/src/vs/base/node/config.ts +++ b/src/vs/base/node/config.ts @@ -8,7 +8,7 @@ import * as fs from 'fs'; import { dirname, basename } from 'path'; import * as objects from 'vs/base/common/objects'; -import { IDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle'; +import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { Event, Emitter } from 'vs/base/common/event'; import * as json from 'vs/base/common/json'; import * as extfs from 'vs/base/node/extfs'; @@ -152,17 +152,10 @@ export class ConfigWatcher implements IConfigWatcher, IDisposable { return; // avoid watchers that will never get disposed by checking for being disposed } - const watcher = extfs.watch(path, + this.disposables.push(extfs.watch(path, (type, file) => this.onConfigFileChange(type, file, isParentFolder), (error: string) => this.options.onError(error) - ); - - if (watcher) { - this.disposables.push(toDisposable(() => { - watcher.removeAllListeners(); - watcher.close(); - })); - } + )); } private onConfigFileChange(eventType: string, filename: string, isParentFolder: boolean): void { diff --git a/src/vs/base/node/extfs.ts b/src/vs/base/node/extfs.ts index 9462bacf025ae0bf9e52b81e8165f87445853193..11f190c54dff0e7486ca3140adbc3d385025cd75 100644 --- a/src/vs/base/node/extfs.ts +++ b/src/vs/base/node/extfs.ts @@ -16,6 +16,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { encode, encodeStream } from 'vs/base/node/encoding'; import * as flow from 'vs/base/node/flow'; import { CancellationToken } from 'vs/base/common/cancellation'; +import { IDisposable, toDisposable, Disposable } from 'vs/base/common/lifecycle'; const loop = flow.loop; @@ -640,7 +641,7 @@ function normalizePath(path: string): string { return strings.rtrim(paths.normalize(path), paths.sep); } -export function watch(path: string, onChange: (type: string, path?: string) => void, onError: (error: string) => void): fs.FSWatcher { +export function watch(path: string, onChange: (type: string, path?: string) => void, onError: (error: string) => void): IDisposable { try { const watcher = fs.watch(path); @@ -660,7 +661,10 @@ export function watch(path: string, onChange: (type: string, path?: string) => v watcher.on('error', (code: number, signal: string) => onError(`Failed to watch ${path} for changes (${code}, ${signal})`)); - return watcher; + return toDisposable(() => { + watcher.removeAllListeners(); + watcher.close(); + }); } catch (error) { fs.exists(path, exists => { if (exists) { @@ -669,7 +673,7 @@ export function watch(path: string, onChange: (type: string, path?: string) => v }); } - return void 0; + return Disposable.None; } export function sanitizeFilePath(candidate: string, cwd: string): string { diff --git a/src/vs/workbench/parts/output/electron-browser/outputServices.ts b/src/vs/workbench/parts/output/electron-browser/outputServices.ts index 88c54a9002ecbbf500216c0ae75fef0a44b2b77f..4cc69a0e4423f8ae37a933e620cc3df0dcd9d8b9 100644 --- a/src/vs/workbench/parts/output/electron-browser/outputServices.ts +++ b/src/vs/workbench/parts/output/electron-browser/outputServices.ts @@ -49,7 +49,7 @@ let callbacks: ((eventType: string, fileName: string) => void)[] = []; function watchOutputDirectory(outputDir: string, logService: ILogService, onChange: (eventType: string, fileName: string) => void): IDisposable { callbacks.push(onChange); if (!watchingOutputDir) { - const watcher = extfs.watch(outputDir, (eventType, fileName) => { + const watcherDisposable = extfs.watch(outputDir, (eventType, fileName) => { for (const callback of callbacks) { callback(eventType, fileName); } @@ -59,10 +59,7 @@ function watchOutputDirectory(outputDir: string, logService: ILogService, onChan watchingOutputDir = true; return toDisposable(() => { callbacks = []; - if (watcher) { - watcher.removeAllListeners(); - watcher.close(); - } + watcherDisposable.dispose(); }); } return toDisposable(() => { }); diff --git a/src/vs/workbench/parts/snippets/electron-browser/snippetsService.ts b/src/vs/workbench/parts/snippets/electron-browser/snippetsService.ts index c0ea1ded30a2512c5d65e5f49869b50dd8964a1c..d7e52f8df9bd46c27f4c6a13579cddabe0c75b6c 100644 --- a/src/vs/workbench/parts/snippets/electron-browser/snippetsService.ts +++ b/src/vs/workbench/parts/snippets/electron-browser/snippetsService.ts @@ -7,7 +7,7 @@ import { basename, extname, join } from 'path'; import { MarkdownString } from 'vs/base/common/htmlContent'; import { IJSONSchema } from 'vs/base/common/jsonSchema'; -import { dispose, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; +import { dispose, IDisposable } from 'vs/base/common/lifecycle'; import { values } from 'vs/base/common/map'; import * as resources from 'vs/base/common/resources'; import { compare, endsWith, isFalsyOrWhitespace } from 'vs/base/common/strings'; @@ -234,7 +234,7 @@ class SnippetsService implements ISnippetsService { } }).then(() => { // watch - const watcher = watch(userSnippetsFolder, (type, filename) => { + this._disposables.push(watch(userSnippetsFolder, (type, filename) => { if (typeof filename !== 'string') { return; } @@ -252,13 +252,7 @@ class SnippetsService implements ISnippetsService { this._files.delete(filepath); } }); - }, (error: string) => this._logService.error(error)); - this._disposables.push(toDisposable(() => { - if (watcher) { - watcher.removeAllListeners(); - watcher.close(); - } - })); + }, (error: string) => this._logService.error(error))); }).then(undefined, err => { this._logService.error('Failed to load user snippets', err); diff --git a/src/vs/workbench/services/files/electron-browser/fileService.ts b/src/vs/workbench/services/files/electron-browser/fileService.ts index d1147b11b01709151ffe7ec4ee371529beedf3c5..2c834e3e1ac992e4fb719ef2db0a24ee36d3b503 100644 --- a/src/vs/workbench/services/files/electron-browser/fileService.ts +++ b/src/vs/workbench/services/files/electron-browser/fileService.ts @@ -1003,7 +1003,7 @@ export class FileService extends Disposable implements IFileService { const fsPath = resource.fsPath; const fsName = paths.basename(resource.fsPath); - const watcher = extfs.watch(fsPath, (eventType: string, filename: string) => { + const watcherDisposable = extfs.watch(fsPath, (eventType: string, filename: string) => { const renamedOrDeleted = ((filename && filename !== fsName) || eventType === 'rename'); // The file was either deleted or renamed. Many tools apply changes to files in an @@ -1017,7 +1017,7 @@ export class FileService extends Disposable implements IFileService { if (renamedOrDeleted) { // Very important to dispose the watcher which now points to a stale inode - watcher.close(); + watcherDisposable.dispose(); this.activeFileChangesWatchers.delete(resource); // Wait a bit and try to install watcher again, assuming that the file was renamed quickly ("Atomic Save") @@ -1048,12 +1048,10 @@ export class FileService extends Disposable implements IFileService { }, (error: string) => this.handleError(error)); // Remember in map - if (watcher) { - this.activeFileChangesWatchers.set(resource, { - count: 1, - unwatch: () => watcher.close() - }); - } + this.activeFileChangesWatchers.set(resource, { + count: 1, + unwatch: () => watcherDisposable.dispose() + }); } private onRawFileChange(event: IRawFileChange): void {