From d23cf6c73de55218c83cf309900a982501a93988 Mon Sep 17 00:00:00 2001 From: Russell Davis <551404+russelldavis@users.noreply.github.com> Date: Mon, 22 May 2023 17:10:26 -0700 Subject: [PATCH] Fix race condition with restoration of problems when closing a file Fixes #47386 This sets the `flushOnListenerRemove` option to true for the call to Event.debounce. Without this, some `onMarkerChanged` events can get dropped -- specifically, when an event gets fired more than 100ms after first listening, in which case the 600ms cleanup setTimeout fires while the 500ms debounce timeout is still pending. --- src/vs/workbench/contrib/tasks/common/problemCollectors.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/tasks/common/problemCollectors.ts b/src/vs/workbench/contrib/tasks/common/problemCollectors.ts index 0087529e25f88a..a1667257f46283 100644 --- a/src/vs/workbench/contrib/tasks/common/problemCollectors.ts +++ b/src/vs/workbench/contrib/tasks/common/problemCollectors.ts @@ -436,7 +436,7 @@ export class WatchingProblemCollector extends AbstractProblemCollector implement let markerChanged: IDisposable | undefined = Event.debounce(this.markerService.onMarkerChanged, (last: readonly URI[] | undefined, e: readonly URI[]) => { return (last ?? []).concat(e); - }, 500)(async (markerEvent) => { + }, 500, false, true)(async (markerEvent) => { markerChanged?.dispose(); markerChanged = undefined; if (!markerEvent.includes(modelEvent.uri) || (this.markerService.read({ resource: modelEvent.uri }).length !== 0)) { @@ -448,8 +448,11 @@ export class WatchingProblemCollector extends AbstractProblemCollector implement } }); setTimeout(async () => { - markerChanged?.dispose(); + // Calling dispose below can trigger the debounce event (via flushOnListenerRemove), so we + // have to unset markerChanged first to make sure the handler above doesn't dispose it again. + const _markerChanged = markerChanged; markerChanged = undefined; + _markerChanged?.dispose(); }, 600); })); }