提交 cc59bf8e 编写于 作者: J Joao Moreno

kill shared process when last window goes away

上级 60ba1dc9
...@@ -27,7 +27,7 @@ import { Server, serve, connect } from 'vs/base/parts/ipc/node/ipc.net'; ...@@ -27,7 +27,7 @@ import { Server, serve, connect } from 'vs/base/parts/ipc/node/ipc.net';
import { TPromise } from 'vs/base/common/winjs.base'; import { TPromise } from 'vs/base/common/winjs.base';
import { AskpassChannel } from 'vs/workbench/parts/git/common/gitIpc'; import { AskpassChannel } from 'vs/workbench/parts/git/common/gitIpc';
import { GitAskpassService } from 'vs/workbench/parts/git/electron-main/askpassService'; import { GitAskpassService } from 'vs/workbench/parts/git/electron-main/askpassService';
import { spawnSharedProcess } from 'vs/code/electron-main/sharedProcess'; import { SharedProcess } from 'vs/code/electron-main/sharedProcess';
import { Mutex } from 'windows-mutex'; import { Mutex } from 'windows-mutex';
import { LaunchService, ILaunchChannel, LaunchChannel, LaunchChannelClient, ILaunchService } from './launch'; import { LaunchService, ILaunchChannel, LaunchChannel, LaunchChannelClient, ILaunchService } from './launch';
import { ServicesAccessor, IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ServicesAccessor, IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
...@@ -144,8 +144,9 @@ function main(accessor: ServicesAccessor, mainIpcServer: Server, userEnv: platfo ...@@ -144,8 +144,9 @@ function main(accessor: ServicesAccessor, mainIpcServer: Server, userEnv: platfo
// Spawn shared process // Spawn shared process
const initData = { args: environmentService.args }; const initData = { args: environmentService.args };
const sharedProcess = spawnSharedProcess(initData, environmentService.appRoot, environmentService.nodeCachedDataDir) const sharedProcess = new SharedProcess(initData, environmentService.appRoot, environmentService.nodeCachedDataDir);
.then(disposable => connect(environmentService.sharedIPCHandle, 'main')); const sharedProcessClient = sharedProcess.onReady
.then(() => connect(environmentService.sharedIPCHandle, 'main'));
// Create a new service collection, because the telemetry service // Create a new service collection, because the telemetry service
// requires a connection to shared process, which was only established // requires a connection to shared process, which was only established
...@@ -158,7 +159,7 @@ function main(accessor: ServicesAccessor, mainIpcServer: Server, userEnv: platfo ...@@ -158,7 +159,7 @@ function main(accessor: ServicesAccessor, mainIpcServer: Server, userEnv: platfo
services.set(ILaunchService, new SyncDescriptor(LaunchService)); services.set(ILaunchService, new SyncDescriptor(LaunchService));
if (environmentService.isBuilt && !environmentService.isExtensionDevelopment && !!product.enableTelemetry) { if (environmentService.isBuilt && !environmentService.isExtensionDevelopment && !!product.enableTelemetry) {
const channel = getDelayedChannel<ITelemetryAppenderChannel>(sharedProcess.then(c => c.getChannel('telemetryAppender'))); const channel = getDelayedChannel<ITelemetryAppenderChannel>(sharedProcessClient.then(c => c.getChannel('telemetryAppender')));
const appender = new TelemetryAppenderClient(channel); const appender = new TelemetryAppenderClient(channel);
const commonProperties = resolveCommonProperties(product.commit, pkg.version); const commonProperties = resolveCommonProperties(product.commit, pkg.version);
const piiPaths = [environmentService.appRoot, environmentService.extensionsPath]; const piiPaths = [environmentService.appRoot, environmentService.extensionsPath];
...@@ -174,6 +175,12 @@ function main(accessor: ServicesAccessor, mainIpcServer: Server, userEnv: platfo ...@@ -174,6 +175,12 @@ function main(accessor: ServicesAccessor, mainIpcServer: Server, userEnv: platfo
// TODO@Joao: unfold this // TODO@Joao: unfold this
windowsMainService = accessor.get(IWindowsMainService); windowsMainService = accessor.get(IWindowsMainService);
windowsMainService.onWindowClose(() => {
if (windowsMainService.getWindowCount() === 0) {
sharedProcess.dispose();
}
});
// Register more Main IPC services // Register more Main IPC services
const launchService = accessor.get(ILaunchService); const launchService = accessor.get(ILaunchService);
const launchChannel = new LaunchChannel(launchService); const launchChannel = new LaunchChannel(launchService);
...@@ -195,7 +202,7 @@ function main(accessor: ServicesAccessor, mainIpcServer: Server, userEnv: platfo ...@@ -195,7 +202,7 @@ function main(accessor: ServicesAccessor, mainIpcServer: Server, userEnv: platfo
const windowsService = accessor.get(IWindowsService); const windowsService = accessor.get(IWindowsService);
const windowsChannel = new WindowsChannel(windowsService); const windowsChannel = new WindowsChannel(windowsService);
electronIpcServer.registerChannel('windows', windowsChannel); electronIpcServer.registerChannel('windows', windowsChannel);
sharedProcess.done(client => client.registerChannel('windows', windowsChannel)); sharedProcessClient.done(client => client.registerChannel('windows', windowsChannel));
// Make sure we associate the program with the app user model id // Make sure we associate the program with the app user model id
// This will help Windows to associate the running program with // This will help Windows to associate the running program with
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import { assign } from 'vs/base/common/objects'; import { assign } from 'vs/base/common/objects';
import { memoize } from 'vs/base/common/decorators';
import { ParsedArgs } from 'vs/platform/environment/common/environment'; import { ParsedArgs } from 'vs/platform/environment/common/environment';
import { TPromise } from 'vs/base/common/winjs.base'; import { TPromise } from 'vs/base/common/winjs.base';
import { BrowserWindow, ipcMain } from 'electron'; import { BrowserWindow, ipcMain } from 'electron';
...@@ -12,27 +13,46 @@ export interface ISharedProcessInitData { ...@@ -12,27 +13,46 @@ export interface ISharedProcessInitData {
args: ParsedArgs; args: ParsedArgs;
} }
export function spawnSharedProcess(initData: ISharedProcessInitData, appRoot: string, nodeCachedDataDir: string): TPromise<void> { export class SharedProcess {
const window = new BrowserWindow();
const config = assign({ appRoot, nodeCachedDataDir });
const url = `${require.toUrl('vs/code/electron-browser/sharedProcess.html')}?config=${encodeURIComponent(JSON.stringify(config))}`; private window: Electron.BrowserWindow;
window.loadURL(url);
// window.webContents.openDevTools();
window.hide();
// Prevent the window from dying @memoize
window.on('close', e => { get onReady(): TPromise<void> {
if (window.isVisible()) { this.window = new BrowserWindow();
e.preventDefault(); const config = assign({ appRoot: this.appRoot, nodeCachedDataDir: this.nodeCachedDataDir });
window.hide();
} const url = `${require.toUrl('vs/code/electron-browser/sharedProcess.html')}?config=${encodeURIComponent(JSON.stringify(config))}`;
}); this.window.loadURL(url);
this.window.webContents.openDevTools();
// this.window.hide();
// Prevent the window from dying
this.window.on('close', e => {
if (this.window.isVisible()) {
e.preventDefault();
this.window.hide();
}
});
return new TPromise<void>((c, e) => { return new TPromise<void>((c, e) => {
ipcMain.once('handshake', ({ sender }) => { ipcMain.once('handshake', ({ sender }) => {
sender.send('handshake', initData); sender.send('handshake', this.initData);
c(null); c(null);
});
}); });
}); }
}
\ No newline at end of file constructor(
private initData: ISharedProcessInitData,
private appRoot: string,
private nodeCachedDataDir: string
) { }
dispose(): void {
if (this.window) {
this.window.close();
this.window = null;
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册