Skip to content

Commit b2a80a8

Browse files
authored
Merge pull request microsoft#250730 from microsoft/copilot/fix-229157
Fix race condition in terminal quick fix provider registration
2 parents 4ebad70 + c6aca76 commit b2a80a8

File tree

1 file changed

+19
-9
lines changed

1 file changed

+19
-9
lines changed

src/vs/workbench/contrib/terminalContrib/quickFix/browser/terminalQuickFixService.ts

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import { Emitter } from '../../../../../base/common/event.js';
77
import { IDisposable, toDisposable } from '../../../../../base/common/lifecycle.js';
88
import { localize } from '../../../../../nls.js';
9-
import { ILogService } from '../../../../../platform/log/common/log.js';
109
import { ITerminalCommandSelector } from '../../../../../platform/terminal/common/terminal.js';
1110
import { ITerminalQuickFixService, ITerminalQuickFixProvider, ITerminalQuickFixProviderSelector } from './quickFix.js';
1211
import { isProposedApiEnabled } from '../../../../services/extensions/common/extensions.js';
@@ -20,6 +19,8 @@ export class TerminalQuickFixService implements ITerminalQuickFixService {
2019
private _providers: Map<string, ITerminalQuickFixProvider> = new Map();
2120
get providers(): Map<string, ITerminalQuickFixProvider> { return this._providers; }
2221

22+
private _pendingProviders: Map<string, ITerminalQuickFixProvider> = new Map();
23+
2324
private readonly _onDidRegisterProvider = new Emitter<ITerminalQuickFixProviderSelector>();
2425
readonly onDidRegisterProvider = this._onDidRegisterProvider.event;
2526
private readonly _onDidRegisterCommandSelector = new Emitter<ITerminalCommandSelector>();
@@ -29,9 +30,7 @@ export class TerminalQuickFixService implements ITerminalQuickFixService {
2930

3031
readonly extensionQuickFixes: Promise<Array<ITerminalCommandSelector>>;
3132

32-
constructor(
33-
@ILogService private readonly _logService: ILogService,
34-
) {
33+
constructor() {
3534
this.extensionQuickFixes = new Promise((r) => quickFixExtensionPoint.setHandler(fixes => {
3635
r(fixes.filter(c => isProposedApiEnabled(c.description, 'terminalQuickFixProvider')).map(c => {
3736
if (!c.value) {
@@ -50,6 +49,14 @@ export class TerminalQuickFixService implements ITerminalQuickFixService {
5049
registerCommandSelector(selector: ITerminalCommandSelector): void {
5150
this._selectors.set(selector.id, selector);
5251
this._onDidRegisterCommandSelector.fire(selector);
52+
53+
// Check if there's a pending provider for this selector
54+
const pendingProvider = this._pendingProviders.get(selector.id);
55+
if (pendingProvider) {
56+
this._pendingProviders.delete(selector.id);
57+
this._providers.set(selector.id, pendingProvider);
58+
this._onDidRegisterProvider.fire({ selector, provider: pendingProvider });
59+
}
5360
}
5461

5562
registerQuickFixProvider(id: string, provider: ITerminalQuickFixProvider): IDisposable {
@@ -61,17 +68,20 @@ export class TerminalQuickFixService implements ITerminalQuickFixService {
6168
if (disposed) {
6269
return;
6370
}
64-
this._providers.set(id, provider);
6571
const selector = this._selectors.get(id);
66-
if (!selector) {
67-
this._logService.error(`No registered selector for ID: ${id}`);
68-
return;
72+
if (selector) {
73+
// Selector is already available, register immediately
74+
this._providers.set(id, provider);
75+
this._onDidRegisterProvider.fire({ selector, provider });
76+
} else {
77+
// Selector not yet available, store provider as pending
78+
this._pendingProviders.set(id, provider);
6979
}
70-
this._onDidRegisterProvider.fire({ selector, provider });
7180
});
7281
return toDisposable(() => {
7382
disposed = true;
7483
this._providers.delete(id);
84+
this._pendingProviders.delete(id);
7585
const selector = this._selectors.get(id);
7686
if (selector) {
7787
this._selectors.delete(id);

0 commit comments

Comments
 (0)