提交 428d4768 编写于 作者: D Dirk Baeumer

Run extension host detached under Windows to ensure correct extension shutdown

上级 d90ca30f
......@@ -148,16 +148,21 @@ export class ExtHostExtensionService extends AbstractExtensionService<ExtHostExt
return this._activatedExtensions[extensionId].exports;
}
public deactivate(extensionId: string): void {
public deactivate(extensionId: string): TPromise<void> {
let result:TPromise<void> = TPromise.as(void 0);
let extension = this._activatedExtensions[extensionId];
if (!extension) {
return;
return result;
}
// call deactivate if available
try {
if (typeof extension.module.deactivate === 'function') {
extension.module.deactivate();
result = TPromise.wrap(extension.module.deactivate()).then(null, (err) => {
// TODO: Do something with err if this is not the shutdown case
return TPromise.as(void 0);
});
}
} catch (err) {
// TODO: Do something with err if this is not the shutdown case
......@@ -169,6 +174,8 @@ export class ExtHostExtensionService extends AbstractExtensionService<ExtHostExt
} catch (err) {
// TODO: Do something with err if this is not the shutdown case
}
return result;
}
public registrationDone(messages: IMessage[]): void {
......
......@@ -23,6 +23,7 @@ import {ExtHostThreadService} from 'vs/workbench/services/thread/common/extHostT
import {RemoteTelemetryService} from 'vs/workbench/api/node/extHostTelemetry';
import {ExtensionScanner, MessagesCollector} from 'vs/workbench/node/extensionPoints';
import {IWorkspaceContextService, WorkspaceContextService} from 'vs/platform/workspace/common/workspace';
import * as errors from 'vs/base/common/errors';
const DIRNAME = URI.parse(require.toUrl('./')).fsPath;
const BASE_PATH = paths.normalize(paths.join(DIRNAME, '../../../..'));
......@@ -151,21 +152,28 @@ export class ExtensionHostMain {
}
this._isTerminating = true;
errors.setUnexpectedErrorHandler((err) => {
// TODO: write to log once we have one
});
let allPromises: TPromise<void>[] = [];
try {
let allExtensions = ExtensionsRegistry.getAllExtensionDescriptions();
let allExtensionsIds = allExtensions.map(ext => ext.id);
let activatedExtensions = allExtensionsIds.filter(id => this._extensionService.isActivated(id));
activatedExtensions.forEach((extensionId) => {
this._extensionService.deactivate(extensionId);
allPromises = activatedExtensions.map((extensionId) => {
return this._extensionService.deactivate(extensionId);
});
} catch (err) {
// TODO: write to log once we have one
}
let extensionsDeactivated = TPromise.join(allPromises).then<void>(() => void 0);
// Give extensions 1 second to wrap up any async dispose, then exit
setTimeout(() => {
exit();
TPromise.any<void>([TPromise.timeout(4000), extensionsDeactivated]).then(() => exit(), () => exit());
}, 1000);
}
......
......@@ -12,6 +12,7 @@ import * as objects from 'vs/base/common/objects';
import * as strings from 'vs/base/common/strings';
import URI from 'vs/base/common/uri';
import {TPromise} from 'vs/base/common/winjs.base';
import {isWindows} from 'vs/base/common/platform';
import {findFreePort} from 'vs/base/node/ports';
import {IMainProcessExtHostIPC, create} from 'vs/platform/extensions/common/ipcRemoteCom';
import {IMessageService, Severity} from 'vs/platform/message/common/message';
......@@ -151,6 +152,13 @@ class ExtensionHostProcessManager {
if (port) {
opts.execArgv = ['--nolazy', (this.isExtensionDevelopmentDebugging ? '--debug-brk=' : '--debug=') + port];
}
// We only detach the extension host on windows. Linux and Mac orphan by default
// and detach under Linux and Mac create another process group.
if (isWindows) {
// We detach because we have noticed that when the renderer exits, its child processes
// (i.e. extension host) is taken down in a brutal fashion by the OS
opts.detached = true;
}
// Run Extension Host as fork of current process
this.extensionHostProcessHandle = fork(URI.parse(require.toUrl('bootstrap')).fsPath, ['--type=extensionHost'], opts);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册