diff --git a/src/events/SDL_events.c b/src/events/SDL_events.c index 802c794e91..c04d52b282 100644 --- a/src/events/SDL_events.c +++ b/src/events/SDL_events.c @@ -1102,16 +1102,11 @@ static void SDL_SendWakeupEvent(void) return; } - 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 + SDL_Window *wakeup_window = (SDL_Window *)SDL_SetAtomicPointer(&_this->wakeup_window, NULL); + if (wakeup_window) { + _this->SendWakeupEvent(_this, wakeup_window); } - SDL_UnlockMutex(_this->wakeup_lock); #endif } @@ -1549,18 +1544,7 @@ static int SDL_WaitEventTimeout_Device(SDL_VideoDevice *_this, SDL_Window *wakeu */ SDL_PumpEventsInternal(true); - SDL_LockMutex(_this->wakeup_lock); - { - status = SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_EVENT_FIRST, SDL_EVENT_LAST); - // 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_EVENT_FIRST, SDL_EVENT_LAST); if (status < 0) { // Got an error: return break; @@ -1573,8 +1557,6 @@ static int SDL_WaitEventTimeout_Device(SDL_VideoDevice *_this, SDL_Window *wakeu if (timeoutNS > 0) { Sint64 elapsed = SDL_GetTicksNS() - start; if (elapsed >= timeoutNS) { - // Set wakeup_window to NULL without holding the lock. - _this->wakeup_window = NULL; return 0; } loop_timeoutNS = (timeoutNS - elapsed); @@ -1587,9 +1569,9 @@ static int SDL_WaitEventTimeout_Device(SDL_VideoDevice *_this, SDL_Window *wakeu loop_timeoutNS = poll_intervalNS; } } + SDL_SetAtomicPointer(&_this->wakeup_window, wakeup_window); status = _this->WaitEventTimeout(_this, loop_timeoutNS); - // Set wakeup_window to NULL without holding the lock. - _this->wakeup_window = NULL; + SDL_SetAtomicPointer(&_this->wakeup_window, NULL); if (status == 0 && poll_intervalNS != SDL_MAX_SINT64 && loop_timeoutNS == poll_intervalNS) { // 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 f04c91436a..4f50e2a680 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -405,8 +405,7 @@ struct SDL_VideoDevice bool checked_texture_framebuffer; bool is_dummy; 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_Rect desktop_bounds; diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 294fad5d10..069fec4df4 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -4393,9 +4393,7 @@ void SDL_DestroyWindow(SDL_Window *window) _this->current_glwin = NULL; } - if (_this->wakeup_window == window) { - _this->wakeup_window = NULL; - } + SDL_CompareAndSwapAtomicPointer(&_this->wakeup_window, window, NULL); // Now invalidate magic SDL_SetObjectValid(window, SDL_OBJECT_TYPE_WINDOW, false); diff --git a/src/video/cocoa/SDL_cocoavideo.m b/src/video/cocoa/SDL_cocoavideo.m index 81baf7825f..aed193df44 100644 --- a/src/video/cocoa/SDL_cocoavideo.m +++ b/src/video/cocoa/SDL_cocoavideo.m @@ -49,9 +49,6 @@ static void Cocoa_VideoQuit(SDL_VideoDevice *_this); static void Cocoa_DeleteDevice(SDL_VideoDevice *device) { @autoreleasepool { - if (device->wakeup_lock) { - SDL_DestroyMutex(device->wakeup_lock); - } CFBridgingRelease(device->internal); SDL_free(device); } @@ -81,7 +78,6 @@ static SDL_VideoDevice *Cocoa_CreateDevice(void) return NULL; } device->internal = (SDL_VideoData *)CFBridgingRetain(data); - device->wakeup_lock = SDL_CreateMutex(); device->system_theme = Cocoa_GetSystemTheme(); // Set the function pointers diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c index 1713d493ab..8514a903d6 100644 --- a/src/video/wayland/SDL_waylandvideo.c +++ b/src/video/wayland/SDL_waylandvideo.c @@ -447,9 +447,6 @@ static void Wayland_DeleteDevice(SDL_VideoDevice *device) WAYLAND_wl_display_disconnect(data->display); SDL_ClearProperty(SDL_GetGlobalProperties(), SDL_PROP_GLOBAL_VIDEO_WAYLAND_WL_DISPLAY_POINTER); } - if (device->wakeup_lock) { - SDL_DestroyMutex(device->wakeup_lock); - } SDL_free(data); SDL_free(device); SDL_WAYLAND_UnloadSymbols(); @@ -576,7 +573,6 @@ static SDL_VideoDevice *Wayland_CreateDevice(bool require_preferred_protocols) } device->internal = 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 25dea1f3b5..0c73febd0d 100644 --- a/src/video/windows/SDL_windowsvideo.c +++ b/src/video/windows/SDL_windowsvideo.c @@ -124,9 +124,6 @@ static void WIN_DeleteDevice(SDL_VideoDevice *device) SDL_UnloadObject(data->dxgiDLL); } #endif - if (device->wakeup_lock) { - SDL_DestroyMutex(device->wakeup_lock); - } SDL_free(device->internal->rawinput); SDL_free(device->internal); SDL_free(device); @@ -152,7 +149,6 @@ static SDL_VideoDevice *WIN_CreateDevice(void) return NULL; } device->internal = data; - device->wakeup_lock = SDL_CreateMutex(); device->system_theme = WIN_GetSystemTheme(); #if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES) diff --git a/src/video/x11/SDL_x11video.c b/src/video/x11/SDL_x11video.c index b5dab99b5f..c3adc9413a 100644 --- a/src/video/x11/SDL_x11video.c +++ b/src/video/x11/SDL_x11video.c @@ -65,9 +65,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->internal); SDL_free(device); @@ -148,8 +145,6 @@ static SDL_VideoDevice *X11_CreateDevice(void) return NULL; } - device->wakeup_lock = SDL_CreateMutex(); - #ifdef X11_DEBUG X11_XSynchronize(data->display, True); #endif