提交 0ecb7735 编写于 作者: B Benjamin Pasero

shared process - more cleanup

上级 75ea87a2
......@@ -11,17 +11,20 @@ import { Barrier } from 'vs/base/common/async';
import { ILogService } from 'vs/platform/log/common/log';
import { ILifecycleMainService } from 'vs/platform/lifecycle/electron-main/lifecycleMainService';
import { IThemeMainService } from 'vs/platform/theme/electron-main/themeMainService';
import { toDisposable, DisposableStore } from 'vs/base/common/lifecycle';
import { FileAccess } from 'vs/base/common/network';
import { browserCodeLoadingCacheStrategy } from 'vs/base/common/platform';
import { ISharedProcessConfiguration } from 'vs/platform/sharedProcess/node/sharedProcess';
import { Disposable } from 'vs/base/common/lifecycle';
export class SharedProcess implements ISharedProcess {
export class SharedProcess extends Disposable implements ISharedProcess {
private readonly barrier = new Barrier();
private readonly _whenReady: Promise<void>;
private readonly whenSpawnedBarrier = new Barrier();
private window: BrowserWindow | null = null;
// overall ready promise when shared process signals initialization is done
private readonly _whenReady = new Promise<void>(resolve => ipcMain.once('vscode:shared-process->electron-main=init-done', () => resolve()));
private window: BrowserWindow | undefined = undefined;
private windowCloseListener: ((event: Event) => void) | undefined = undefined;
constructor(
private readonly machineId: string,
......@@ -31,12 +34,59 @@ export class SharedProcess implements ISharedProcess {
@ILogService private readonly logService: ILogService,
@IThemeMainService private readonly themeMainService: IThemeMainService
) {
// overall ready promise when shared process signals initialization is done
this._whenReady = new Promise<void>(c => ipcMain.once('vscode:shared-process->electron-main=init-done', () => c(undefined)));
super();
this.registerListeners();
}
private registerListeners(): void {
this._register(this.lifecycleMainService.onWillShutdown(() => this.onWillShutdown()));
}
private onWillShutdown(): void {
const window = this.window;
if (!window) {
return; // possibly too early before created
}
// Signal exit to shared process when shutting down
window.webContents.send('vscode:electron-main->shared-process=exit');
// Shut the shared process down when we are quitting
//
// Note: because we veto the window close, we must first remove our veto.
// Otherwise the application would never quit because the shared process
// window is refusing to close!
//
if (this.windowCloseListener) {
window.removeListener('close', this.windowCloseListener);
}
// Electron seems to crash on Windows without this setTimeout :|
setTimeout(() => {
try {
window.close();
} catch (err) {
// ignore, as electron is already shutting down
}
this.window = undefined;
}, 0);
}
@memoize
private get _whenIpcReady(): Promise<void> {
// Create window for shared process
this.createWindow();
// complete IPC-ready promise when shared process signals this to us
return new Promise<void>(resolve => ipcMain.once('vscode:shared-process->electron-main=ipc-ready', () => resolve(undefined)));
}
private createWindow(): void {
// shared process is a hidden window by default
this.window = new BrowserWindow({
show: false,
backgroundColor: this.themeMainService.getBackgroundColor(),
......@@ -72,72 +122,42 @@ export class SharedProcess implements ISharedProcess {
.toString(true)
);
// Prevent the window from dying
const onClose = (e: Event) => {
// Prevent the window from closing
this.windowCloseListener = (e: Event) => {
this.logService.trace('SharedProcess#close prevented');
// We never allow to close the shared process unless we get explicitly disposed()
e.preventDefault();
// Still hide the window though if visible
if (this.window && this.window.isVisible()) {
if (this.window?.isVisible()) {
this.window.hide();
}
};
this.window.on('close', onClose);
const disposables = new DisposableStore();
this.lifecycleMainService.onWillShutdown(() => {
disposables.dispose();
// Shut the shared process down when we are quitting
//
// Note: because we veto the window close, we must first remove our veto.
// Otherwise the application would never quit because the shared process
// window is refusing to close!
//
if (this.window) {
this.window.removeListener('close', onClose);
}
// Electron seems to crash on Windows without this setTimeout :|
setTimeout(() => {
try {
if (this.window) {
this.window.close();
}
} catch (err) {
// ignore, as electron is already shutting down
}
this.window = null;
}, 0);
});
return new Promise<void>(resolve => {
// signal exit to shared process when we get disposed
disposables.add(toDisposable(() => this.window?.webContents.send('vscode:electron-main->shared-process=exit')));
// complete IPC-ready promise when shared process signals this to us
ipcMain.once('vscode:shared-process->electron-main=ipc-ready', () => resolve(undefined));
});
this.window.on('close', this.windowCloseListener);
}
spawn(userEnv: NodeJS.ProcessEnv): void {
this.userEnv = { ...this.userEnv, ...userEnv };
this.barrier.open();
// Release barrier
this.whenSpawnedBarrier.open();
}
async whenReady(): Promise<void> {
await this.barrier.wait();
// Always wait for `spawn()`
await this.whenSpawnedBarrier.wait();
await this._whenReady;
}
async whenIpcReady(): Promise<void> {
await this.barrier.wait();
// Always wait for `spawn()`
await this.whenSpawnedBarrier.wait();
await this._whenIpcReady;
}
......
......@@ -102,22 +102,22 @@ export class CodeWindow extends Disposable implements ICodeWindow {
private hiddenTitleBarStyle: boolean | undefined;
private showTimeoutHandle: NodeJS.Timeout | undefined;
private _lastFocusTime: number;
private _readyState: ReadyState;
private _lastFocusTime = -1;
private _readyState = ReadyState.NONE;
private windowState: IWindowState;
private currentMenuBarVisibility: MenuBarVisibility | undefined;
private representedFilename: string | undefined;
private documentEdited: boolean | undefined;
private readonly whenReadyCallbacks: { (window: ICodeWindow): void }[];
private readonly whenReadyCallbacks: { (window: ICodeWindow): void }[] = [];
private marketplaceHeadersPromise: Promise<object>;
private readonly touchBarGroups: TouchBarSegmentedControl[];
private readonly touchBarGroups: TouchBarSegmentedControl[] = [];
private currentHttpProxy?: string;
private currentNoProxy?: string;
private currentHttpProxy: string | undefined = undefined;
private currentNoProxy: string | undefined = undefined;
constructor(
config: IWindowCreationOptions,
......@@ -135,11 +135,6 @@ export class CodeWindow extends Disposable implements ICodeWindow {
) {
super();
this.touchBarGroups = [];
this._lastFocusTime = -1;
this._readyState = ReadyState.NONE;
this.whenReadyCallbacks = [];
//#region create browser window
{
// Load window state
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册