Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,14 @@ export class ExtensionHostStarter extends Disposable implements IDisposable, IEx
throw canceled();
}
const extHost = this._getExtHost(id);
const args = ['--skipWorkspaceStorageLock'];
// --- Coderm start: Phase 7-A isolated EH storage lock ---
// The isolated EH runs with a separated workspaceStorageHome (set by the
// workbench side), so it can acquire the workspace storage lock normally
// instead of skipping it — giving it proper storage consistency on crash
// recovery. The LocalProcess EH keeps the skip flag to preserve upstream
// behavior, where multiple LocalProcess EHs may share one storage home.
const args = opts.kind === 'isolatedExtensionHost' ? [] : ['--skipWorkspaceStorageLock'];
// --- Coderm end ---
if (this._configurationService.getValue<boolean>('extensions.supportNodeGlobalNavigator')) {
args.push('--supportGlobalNavigator');
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,16 @@ export abstract class AbstractExtensionService extends Disposable implements IEx
const localProcessExtensions = (this._hasLocalProcess ? this._runningLocations.filterByExtensionHostKind(localExtensions, ExtensionHostKind.LocalProcess) : []);
const localWebWorkerExtensions = this._runningLocations.filterByExtensionHostKind(localExtensions, ExtensionHostKind.LocalWebWorker);
remoteExtensions = this._runningLocations.filterByExtensionHostKind(remoteExtensions, ExtensionHostKind.Remote);
// --- Coderm start: isolated language EH kind ---
// VS Code's _resolveAndProcessExtensions builds the registry from per-kind buckets.
// Upstream covers LocalProcess / LocalWebWorker / Remote only — without the isolated
// bucket here, isolated-routed extensions (e.g. typescript-language-features) are
// dropped from the registry. That makes ExtensionHostManager.start() receive empty
// myExtensions for the isolated EH, which overwrites the correct init data and breaks
// activation (Phase 6 / Phase 7-A root cause). Add the isolated bucket so isolated
// extensions are registered symmetrically with the other kinds.
const localIsolatedProcessExtensions = this._runningLocations.filterByExtensionHostKind(localExtensions, ExtensionHostKind.LocalIsolatedProcess);
// --- Coderm end ---

// Add locally the remote extensions that need to run locally in the web worker
for (const ext of remoteExtensionsThatNeedToRunLocally) {
Expand All @@ -553,7 +563,10 @@ export abstract class AbstractExtensionService extends Disposable implements IEx
}
}

const allExtensions = remoteExtensions.concat(localProcessExtensions).concat(localWebWorkerExtensions);
const allExtensions = remoteExtensions.concat(localProcessExtensions).concat(localWebWorkerExtensions)
// --- Coderm start: isolated language EH kind ---
.concat(localIsolatedProcessExtensions);
// --- Coderm end ---
let toAdd = allExtensions;

if (resolverExtensions.length) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -532,7 +532,21 @@ export class NativeLocalIsolatedProcessExtensionHost extends Disposable implemen
extensionDevelopmentLocationURI: this._environmentService.extensionDevelopmentLocationURI,
extensionTestsLocationURI: this._environmentService.extensionTestsLocationURI,
globalStorageHome: this._userDataProfilesService.defaultProfile.globalStorageHome,
workspaceStorageHome: this._environmentService.workspaceStorageHome,
// --- Coderm start: Phase 7-A isolated EH resource isolation ---
// Separate workspaceStorageHome so the isolated EH never contends with the
// LocalProcess EH for the same <workspaceStorageHome>/<workspace.id>/ lock
// and meta.json. Sharing that path was the strong candidate for Phase 6's
// silent activate failure (exthost.log showed 3 EHs "Skipping acquiring lock"
// on the same storage).
//
// IMPORTANT: must be a SIBLING of workspaceStorage/, not a child. VS Code's
// storage cleanup (storageDataCleaner) reclaims workspace storage directories
// it no longer considers in-use (matched by workspace.id). A child like
// workspaceStorage/isolated/ is not a recognized workspace entry and gets
// reclaimed, dropping the storage lock mid-session (lock-lost) and breaking
// activation. workspaceStorage-isolated/ sits outside that scan.
workspaceStorageHome: this._environmentService.workspaceStorageHome.with({ path: this._environmentService.workspaceStorageHome.path + '-isolated' }),
// --- Coderm end ---
extensionLogLevel: this._defaultLogLevelsService.defaultLogLevels.extensions,
isSessionsWindow: this._environmentService.isSessionsWindow
},
Expand Down Expand Up @@ -565,7 +579,12 @@ export class NativeLocalIsolatedProcessExtensionHost extends Disposable implemen
virtualWorkspaceExtensionTips: this._productService.virtualWorkspaceExtensionTips,
logLevel: this._logService.getLevel(),
loggers: [...this._loggerService.getRegisteredLoggers()],
logsLocation: this._environmentService.extHostLogsPath,
// --- Coderm start: Phase 7-A isolated EH resource isolation ---
// Separate logsLocation so the isolated EH writes logs under a dedicated
// subtree (<extHostLogsPath>/isolated/<extensionId>/), mirroring the
// workspaceStorageHome split. Avoids log path races with the LocalProcess EH.
logsLocation: URI.joinPath(this._environmentService.extHostLogsPath, 'isolated'),
// --- Coderm end ---
autoStart: (this.startup === ExtensionHostStartup.EagerAutoStart),
uiKind: UIKind.Desktop,
handle: this._environmentService.window.handle ? encodeBase64(this._environmentService.window.handle) : undefined
Expand Down
Loading