1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-23 03:32:32 +00:00

Ensure race condition workaround is applied for all CVDisplayLinkStops.

This also centralises the workaround, the better for replacing it when I discover a safer alternative.
This commit is contained in:
Thomas Harte 2020-03-11 22:09:36 -04:00
parent 9668ec789a
commit 3c70f056ed

View File

@ -41,12 +41,7 @@
- (void)setupDisplayLink { - (void)setupDisplayLink {
// Kill the existing link if there is one, then wait until its final shout is definitely done. // Kill the existing link if there is one, then wait until its final shout is definitely done.
if(_displayLink) { if(_displayLink) {
const double duration = CVDisplayLinkGetActualOutputVideoRefreshPeriod(_displayLink); [self invalidate];
CVDisplayLinkStop(_displayLink);
// This is a workaround; I could find no way to ensure that a callback from the display
// link is not currently ongoing.
usleep((useconds_t)ceil(duration * 1000000.0));
CVDisplayLinkRelease(_displayLink); CVDisplayLinkRelease(_displayLink);
} }
@ -118,7 +113,13 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt
} }
- (void)invalidate { - (void)invalidate {
const double duration = CVDisplayLinkGetActualOutputVideoRefreshPeriod(_displayLink);
CVDisplayLinkStop(_displayLink); CVDisplayLinkStop(_displayLink);
// This is a workaround; I could find no way to ensure that a callback from the display
// link is not currently ongoing. In short: call stop, wait for an entire refresh period,
// then assume (/hope) the coast is clear.
usleep((useconds_t)ceil(duration * 1000000.0));
} }
- (void)dealloc { - (void)dealloc {