mirror of https://github.com/libsdl-org/SDL.git
Fixed rare crash trying to interrupt SDL_WaitEvent()
Fixes https://github.com/libsdl-org/SDL/issues/12797
This commit is contained in:
parent
4db8fe2f9b
commit
992e4c59bd
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue