Wait for a removal to be observable: WaitGone - #2
Merged
Merged
Conversation
Open does not return until the display is active. Close had no matching wait, and the gap is not small. Measured on macOS 26.6.2, M4 Max: closing four displays, CloseAll returned in 33 microseconds and macOS kept listing them for 716 ms; six 1920x1080 displays took 1.9 s. A caller that closes and immediately reads ActiveDisplays therefore sees displays that are already dead and reads them as a leak. That misreading happened here before the timing was measured, which is what prompted this. WaitGone(timeout, ids...) polls the active list until none of the ids is there, returning ErrStillPresent naming the ones that stayed -- which is a real state, not just a timeout: a display whose mode was changed after creation cannot be released at all, as Close already documents. The package's own integration tests slept a fixed 1.5 s before asserting a removal, which is SHORTER than a batch takes; they now wait, including the cleanup guard whose "something was left behind" message could fire on displays that were merely still retiring. The new integration test states both numbers and carries the negative control: a wait for the MAIN display must fail, or none of the passes mean anything.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Opendoes not return until the display is active.Closehad no matching wait, and the gap is not small.Measured on macOS 26.6.2, M4 Max — closing four displays:
Six 1920x1080 displays took 1.9 s. So a caller that closes and immediately reads
ActiveDisplayssees displays that are already dead and reads them as a leak — which is what happened here, before the timing was measured, while answering a plain question about why virtual screens were not in the macOS display list.What this adds
It polls the active list until none of
idsis there, and returnsErrStillPresentnaming the ones that stayed — a real state, not merely a timeout: a display whose mode was changed after creation cannot be released at all, asClosealready documents. A zero timeout checks once without sleeping.What it fixes here
This package's own integration tests slept a fixed
settleof 1.5 s before asserting a removal — shorter than a batch actually takes. Three sites now wait instead, including the cleanup guard whosesomething was left behindmessage could fire on displays that were only still retiring.The new integration test prints both numbers and carries the negative control: a wait for the main display must fail with
ErrStillPresent, or none of the passes above it prove anything.Portable code stays fully covered;
WaitGoneand its helper are tested on every platform through the existing seams, with the vacuous-wait control asserted there too (a zero timeout must not sleep, a wait that returns must have polled).