cocoa: Put a mutex around GL_SwapBuffers.
authorRyan C. Gordon <icculus@icculus.org>
Thu, 18 Oct 2018 23:38:27 -0400
changeset 1234384eaa0636bac
parent 12342 7cec5c0510ae
child 12344 9dd351b26dcb
cocoa: Put a mutex around GL_SwapBuffers.

Prevents deadlock when swapping two different GL contexts on two different
threads at the same time on macOS 10.14 ("Mojave").

Fixes Bugzilla #4278.
src/video/cocoa/SDL_cocoaopengl.m
src/video/cocoa/SDL_cocoavideo.h
src/video/cocoa/SDL_cocoavideo.m
     1.1 --- a/src/video/cocoa/SDL_cocoaopengl.m	Thu Aug 23 14:47:38 2018 +0200
     1.2 +++ b/src/video/cocoa/SDL_cocoaopengl.m	Thu Oct 18 23:38:27 2018 -0400
     1.3 @@ -410,8 +410,14 @@
     1.4  { @autoreleasepool
     1.5  {
     1.6      SDLOpenGLContext* nscontext = (SDLOpenGLContext*)SDL_GL_GetCurrentContext();
     1.7 +    SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
     1.8 +
     1.9 +    /* on 10.14 ("Mojave") and later, this deadlocks if two contexts in two
    1.10 +       threads try to swap at the same time, so put a mutex around it. */
    1.11 +    SDL_LockMutex(videodata->swaplock);
    1.12      [nscontext flushBuffer];
    1.13      [nscontext updateIfNeeded];
    1.14 +    SDL_UnlockMutex(videodata->swaplock);
    1.15      return 0;
    1.16  }}
    1.17  
     2.1 --- a/src/video/cocoa/SDL_cocoavideo.h	Thu Aug 23 14:47:38 2018 +0200
     2.2 +++ b/src/video/cocoa/SDL_cocoavideo.h	Thu Oct 18 23:38:27 2018 -0400
     2.3 @@ -107,7 +107,7 @@
     2.4      Uint32 screensaver_activity;
     2.5      BOOL screensaver_use_iopm;
     2.6      IOPMAssertionID screensaver_assertion;
     2.7 -
     2.8 +    SDL_mutex *swaplock;
     2.9  } SDL_VideoData;
    2.10  
    2.11  /* Utility functions */
     3.1 --- a/src/video/cocoa/SDL_cocoavideo.m	Thu Aug 23 14:47:38 2018 +0200
     3.2 +++ b/src/video/cocoa/SDL_cocoavideo.m	Thu Oct 18 23:38:27 2018 -0400
     3.3 @@ -175,15 +175,23 @@
     3.4      /* The IOPM assertion API can disable the screensaver as of 10.7. */
     3.5      data->screensaver_use_iopm = floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6;
     3.6  
     3.7 +    data->swaplock = SDL_CreateMutex();
     3.8 +    if (!data->swaplock) {
     3.9 +        return -1;
    3.10 +    }
    3.11 +
    3.12      return 0;
    3.13  }
    3.14  
    3.15  void
    3.16  Cocoa_VideoQuit(_THIS)
    3.17  {
    3.18 +    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
    3.19      Cocoa_QuitModes(_this);
    3.20      Cocoa_QuitKeyboard(_this);
    3.21      Cocoa_QuitMouse(_this);
    3.22 +    SDL_DestroyMutex(data->swaplock);
    3.23 +    data->swaplock = NULL;
    3.24  }
    3.25  
    3.26  /* This function assumes that it's called from within an autorelease pool */