From 3c70f056ed75bab3b0733545d31d28d54e3e9234 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 11 Mar 2020 22:09:36 -0400 Subject: [PATCH] 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. --- OSBindings/Mac/Clock Signal/Views/CSOpenGLView.m | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/OSBindings/Mac/Clock Signal/Views/CSOpenGLView.m b/OSBindings/Mac/Clock Signal/Views/CSOpenGLView.m index a974c05bb..562a5fdf3 100644 --- a/OSBindings/Mac/Clock Signal/Views/CSOpenGLView.m +++ b/OSBindings/Mac/Clock Signal/Views/CSOpenGLView.m @@ -41,12 +41,7 @@ - (void)setupDisplayLink { // Kill the existing link if there is one, then wait until its final shout is definitely done. if(_displayLink) { - const double duration = CVDisplayLinkGetActualOutputVideoRefreshPeriod(_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. - usleep((useconds_t)ceil(duration * 1000000.0)); + [self invalidate]; CVDisplayLinkRelease(_displayLink); } @@ -118,7 +113,13 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt } - (void)invalidate { + const double duration = CVDisplayLinkGetActualOutputVideoRefreshPeriod(_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 {