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.
This commit is contained in:
Ryan C. Gordon 2018-10-18 23:38:27 -04:00
parent 84e7832018
commit 1fb20f0ab9
3 changed files with 15 additions and 1 deletions

View File

@ -410,8 +410,14 @@ Cocoa_GL_SwapWindow(_THIS, SDL_Window * window)
{ @autoreleasepool { @autoreleasepool
{ {
SDLOpenGLContext* nscontext = (SDLOpenGLContext*)SDL_GL_GetCurrentContext(); SDLOpenGLContext* nscontext = (SDLOpenGLContext*)SDL_GL_GetCurrentContext();
SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
/* on 10.14 ("Mojave") and later, this deadlocks if two contexts in two
threads try to swap at the same time, so put a mutex around it. */
SDL_LockMutex(videodata->swaplock);
[nscontext flushBuffer]; [nscontext flushBuffer];
[nscontext updateIfNeeded]; [nscontext updateIfNeeded];
SDL_UnlockMutex(videodata->swaplock);
return 0; return 0;
}} }}

View File

@ -107,7 +107,7 @@ typedef struct SDL_VideoData
Uint32 screensaver_activity; Uint32 screensaver_activity;
BOOL screensaver_use_iopm; BOOL screensaver_use_iopm;
IOPMAssertionID screensaver_assertion; IOPMAssertionID screensaver_assertion;
SDL_mutex *swaplock;
} SDL_VideoData; } SDL_VideoData;
/* Utility functions */ /* Utility functions */

View File

@ -175,15 +175,23 @@ Cocoa_VideoInit(_THIS)
/* The IOPM assertion API can disable the screensaver as of 10.7. */ /* The IOPM assertion API can disable the screensaver as of 10.7. */
data->screensaver_use_iopm = floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6; data->screensaver_use_iopm = floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6;
data->swaplock = SDL_CreateMutex();
if (!data->swaplock) {
return -1;
}
return 0; return 0;
} }
void void
Cocoa_VideoQuit(_THIS) Cocoa_VideoQuit(_THIS)
{ {
SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
Cocoa_QuitModes(_this); Cocoa_QuitModes(_this);
Cocoa_QuitKeyboard(_this); Cocoa_QuitKeyboard(_this);
Cocoa_QuitMouse(_this); Cocoa_QuitMouse(_this);
SDL_DestroyMutex(data->swaplock);
data->swaplock = NULL;
} }
/* This function assumes that it's called from within an autorelease pool */ /* This function assumes that it's called from within an autorelease pool */