diff --git a/src/events/SDL_events.c b/src/events/SDL_events.c index 3dcd9a8f66..271e2504b9 100644 --- a/src/events/SDL_events.c +++ b/src/events/SDL_events.c @@ -738,21 +738,17 @@ static void SDL_CutEvent(SDL_EventEntry *entry) static int SDL_SendWakeupEvent(void) { + SDL_Window *wakeup_window; SDL_VideoDevice *_this = SDL_GetVideoDevice(); if (_this == NULL || !_this->SendWakeupEvent) { return 0; } - SDL_LockMutex(_this->wakeup_lock); - { - if (_this->wakeup_window) { - _this->SendWakeupEvent(_this, _this->wakeup_window); - - /* No more wakeup events needed until we enter a new wait */ - _this->wakeup_window = NULL; - } + /* We only want to do this once while waiting for an event, so set it to NULL atomically here */ + wakeup_window = (SDL_Window *)SDL_AtomicSetPtr(&_this->wakeup_window, NULL); + if (wakeup_window) { + _this->SendWakeupEvent(_this, wakeup_window); } - SDL_UnlockMutex(_this->wakeup_lock); return 0; } @@ -1009,18 +1005,7 @@ static int SDL_WaitEventTimeout_Device(_THIS, SDL_Window *wakeup_window, SDL_Eve int status; SDL_PumpEventsInternal(SDL_TRUE); - SDL_LockMutex(_this->wakeup_lock); - { - status = SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT); - /* If status == 0 we are going to block so wakeup will be needed. */ - if (status == 0) { - _this->wakeup_window = wakeup_window; - } else { - _this->wakeup_window = NULL; - } - } - SDL_UnlockMutex(_this->wakeup_lock); - + status = SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT); if (status < 0) { /* Got an error: return */ break; @@ -1033,8 +1018,6 @@ static int SDL_WaitEventTimeout_Device(_THIS, SDL_Window *wakeup_window, SDL_Eve if (timeout > 0) { Uint32 elapsed = SDL_GetTicks() - start; if (elapsed >= (Uint32)timeout) { - /* Set wakeup_window to NULL without holding the lock. */ - _this->wakeup_window = NULL; return 0; } loop_timeout = (int)((Uint32)timeout - elapsed); @@ -1049,9 +1032,9 @@ static int SDL_WaitEventTimeout_Device(_THIS, SDL_Window *wakeup_window, SDL_Eve } } + SDL_AtomicSetPtr(&_this->wakeup_window, wakeup_window); status = _this->WaitEventTimeout(_this, loop_timeout); - /* Set wakeup_window to NULL without holding the lock. */ - _this->wakeup_window = NULL; + SDL_AtomicSetPtr(&_this->wakeup_window, NULL); if (status == 0 && poll_interval != SDL_MAX_SINT16 && loop_timeout == poll_interval) { /* We may have woken up to poll. Try again */ continue; diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index 22bca8a222..faf598be38 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -355,8 +355,7 @@ struct SDL_VideoDevice SDL_bool checked_texture_framebuffer; SDL_bool is_dummy; SDL_bool suspend_screensaver; - SDL_Window *wakeup_window; - SDL_mutex *wakeup_lock; /* Initialized only if WaitEventTimeout/SendWakeupEvent are supported */ + void *wakeup_window; int num_displays; SDL_VideoDisplay *displays; SDL_Window *windows; diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 01023753c6..2f6c631d12 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -3368,9 +3368,7 @@ void SDL_DestroyWindow(SDL_Window *window) _this->current_glwin = NULL; } - if (_this->wakeup_window == window) { - _this->wakeup_window = NULL; - } + SDL_AtomicCASPtr(&_this->wakeup_window, window, NULL); /* Now invalidate magic */ window->magic = NULL; diff --git a/src/video/cocoa/SDL_cocoavideo.m b/src/video/cocoa/SDL_cocoavideo.m index 811e85dbb9..4ca68ba836 100644 --- a/src/video/cocoa/SDL_cocoavideo.m +++ b/src/video/cocoa/SDL_cocoavideo.m @@ -48,9 +48,6 @@ static void Cocoa_VideoQuit(_THIS); static void Cocoa_DeleteDevice(SDL_VideoDevice * device) { @autoreleasepool { - if (device->wakeup_lock) { - SDL_DestroyMutex(device->wakeup_lock); - } CFBridgingRelease(device->driverdata); SDL_free(device); }} @@ -76,7 +73,6 @@ static SDL_VideoDevice *Cocoa_CreateDevice(void) return NULL; } device->driverdata = (void *)CFBridgingRetain(data); - device->wakeup_lock = SDL_CreateMutex(); /* Set the function pointers */ device->VideoInit = Cocoa_VideoInit; diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c index 1d525be496..0549520d61 100644 --- a/src/video/wayland/SDL_waylandvideo.c +++ b/src/video/wayland/SDL_waylandvideo.c @@ -162,9 +162,6 @@ static void Wayland_DeleteDevice(SDL_VideoDevice *device) WAYLAND_wl_display_flush(data->display); WAYLAND_wl_display_disconnect(data->display); } - if (device->wakeup_lock) { - SDL_DestroyMutex(device->wakeup_lock); - } SDL_free(data); SDL_free(device); SDL_WAYLAND_UnloadSymbols(); @@ -233,7 +230,6 @@ static SDL_VideoDevice *Wayland_CreateDevice(void) } device->driverdata = data; - device->wakeup_lock = SDL_CreateMutex(); /* Set the function pointers */ device->VideoInit = Wayland_VideoInit; diff --git a/src/video/windows/SDL_windowsvideo.c b/src/video/windows/SDL_windowsvideo.c index 7c02658054..6c71bdcb60 100644 --- a/src/video/windows/SDL_windowsvideo.c +++ b/src/video/windows/SDL_windowsvideo.c @@ -93,9 +93,6 @@ static void WIN_DeleteDevice(SDL_VideoDevice *device) SDL_UnloadObject(data->shcoreDLL); } #endif - if (device->wakeup_lock) { - SDL_DestroyMutex(device->wakeup_lock); - } SDL_free(device->driverdata); SDL_free(device); } @@ -120,7 +117,6 @@ static SDL_VideoDevice *WIN_CreateDevice(void) return NULL; } device->driverdata = data; - device->wakeup_lock = SDL_CreateMutex(); #if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) data->userDLL = SDL_LoadObject("USER32.DLL"); diff --git a/src/video/x11/SDL_x11video.c b/src/video/x11/SDL_x11video.c index 9023add317..b43da51168 100644 --- a/src/video/x11/SDL_x11video.c +++ b/src/video/x11/SDL_x11video.c @@ -108,9 +108,6 @@ static void X11_DeleteDevice(SDL_VideoDevice *device) X11_XCloseDisplay(data->request_display); } SDL_free(data->windowlist); - if (device->wakeup_lock) { - SDL_DestroyMutex(device->wakeup_lock); - } SDL_free(device->driverdata); SDL_free(device); @@ -204,8 +201,6 @@ static SDL_VideoDevice *X11_CreateDevice(void) return NULL; } - device->wakeup_lock = SDL_CreateMutex(); - #ifdef X11_DEBUG X11_XSynchronize(data->display, True); #endif