mirror of https://github.com/encounter/SDL.git
x11/wayland: Fix signal handling while blocking in WaitEventTimeout()
Add a new flag to avoid suppressing EINTR in SDL_IOReady(). Pass the flag in WaitEventTimeout() to ensure that a SIGINT will wake up SDL_WaitEvent() without another event coming in.
This commit is contained in:
parent
c97c46877f
commit
a559864968
|
@ -83,7 +83,7 @@ SDL_IOReady(int fd, int flags, int timeoutMS)
|
||||||
result = select(fd + 1, rfdp, wfdp, NULL, tvp);
|
result = select(fd + 1, rfdp, wfdp, NULL, tvp);
|
||||||
#endif /* HAVE_POLL */
|
#endif /* HAVE_POLL */
|
||||||
|
|
||||||
} while ( result < 0 && errno == EINTR );
|
} while ( result < 0 && errno == EINTR && !(flags & SDL_IOR_NO_RETRY));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
#define SDL_IOR_READ 0x1
|
#define SDL_IOR_READ 0x1
|
||||||
#define SDL_IOR_WRITE 0x2
|
#define SDL_IOR_WRITE 0x2
|
||||||
|
#define SDL_IOR_NO_RETRY 0x4
|
||||||
|
|
||||||
extern int SDL_IOReady(int fd, int flags, int timeoutMS);
|
extern int SDL_IOReady(int fd, int flags, int timeoutMS);
|
||||||
|
|
||||||
|
|
|
@ -827,6 +827,7 @@ SDL_WaitEventTimeout_Device(_THIS, SDL_Window *wakeup_window, SDL_Event * event,
|
||||||
a) All pending events are batch processed after waking up from a wait
|
a) All pending events are batch processed after waking up from a wait
|
||||||
b) Waiting can be completely skipped if events are already available to be pumped
|
b) Waiting can be completely skipped if events are already available to be pumped
|
||||||
c) Periodic processing that takes place in some platform PumpEvents() functions happens
|
c) Periodic processing that takes place in some platform PumpEvents() functions happens
|
||||||
|
d) Signals received in WaitEventTimeout() are turned into SDL events
|
||||||
*/
|
*/
|
||||||
SDL_PumpEvents();
|
SDL_PumpEvents();
|
||||||
|
|
||||||
|
@ -847,7 +848,6 @@ SDL_WaitEventTimeout_Device(_THIS, SDL_Window *wakeup_window, SDL_Event * event,
|
||||||
}
|
}
|
||||||
if (status > 0) {
|
if (status > 0) {
|
||||||
/* There is an event, we can return. */
|
/* There is an event, we can return. */
|
||||||
SDL_SendPendingSignalEvents(); /* in case we had a signal handler fire, etc. */
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/* No events found in the queue, call WaitEventTimeout to wait for an event. */
|
/* No events found in the queue, call WaitEventTimeout to wait for an event. */
|
||||||
|
|
|
@ -58,6 +58,7 @@
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <xkbcommon/xkbcommon.h>
|
#include <xkbcommon/xkbcommon.h>
|
||||||
#include <xkbcommon/xkbcommon-compose.h>
|
#include <xkbcommon/xkbcommon-compose.h>
|
||||||
#include "../../events/imKStoUCS.h"
|
#include "../../events/imKStoUCS.h"
|
||||||
|
@ -259,12 +260,14 @@ Wayland_WaitEventTimeout(_THIS, int timeout)
|
||||||
/* wl_display_prepare_read() will return -1 if the default queue is not empty.
|
/* wl_display_prepare_read() will return -1 if the default queue is not empty.
|
||||||
* If the default queue is empty, it will prepare us for our SDL_IOReady() call. */
|
* If the default queue is empty, it will prepare us for our SDL_IOReady() call. */
|
||||||
if (WAYLAND_wl_display_prepare_read(d->display) == 0) {
|
if (WAYLAND_wl_display_prepare_read(d->display) == 0) {
|
||||||
if (SDL_IOReady(WAYLAND_wl_display_get_fd(d->display), SDL_IOR_READ, timeout) > 0) {
|
/* Use SDL_IOR_NO_RETRY to ensure SIGINT will break us out of our wait */
|
||||||
|
int err = SDL_IOReady(WAYLAND_wl_display_get_fd(d->display), SDL_IOR_READ | SDL_IOR_NO_RETRY, timeout);
|
||||||
|
if (err > 0) {
|
||||||
/* There are new events available to read */
|
/* There are new events available to read */
|
||||||
WAYLAND_wl_display_read_events(d->display);
|
WAYLAND_wl_display_read_events(d->display);
|
||||||
WAYLAND_wl_display_dispatch_pending(d->display);
|
WAYLAND_wl_display_dispatch_pending(d->display);
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else if (err == 0) {
|
||||||
/* No events available within the timeout */
|
/* No events available within the timeout */
|
||||||
WAYLAND_wl_display_cancel_read(d->display);
|
WAYLAND_wl_display_cancel_read(d->display);
|
||||||
|
|
||||||
|
@ -277,6 +280,17 @@ Wayland_WaitEventTimeout(_THIS, int timeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
} else {
|
||||||
|
/* Error returned from poll()/select() */
|
||||||
|
WAYLAND_wl_display_cancel_read(d->display);
|
||||||
|
|
||||||
|
if (errno == EINTR) {
|
||||||
|
/* If the wait was interrupted by a signal, we may have generated a
|
||||||
|
* SDL_QUIT event. Let the caller know to call SDL_PumpEvents(). */
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* We already had pending events */
|
/* We already had pending events */
|
||||||
|
|
|
@ -1585,14 +1585,25 @@ X11_WaitEventTimeout(_THIS, int timeout)
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else if (timeout > 0) {
|
|
||||||
if (SDL_IOReady(ConnectionNumber(display), SDL_IOR_READ, timeout) > 0) {
|
|
||||||
X11_XNextEvent(display, &xevent);
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
X11_XNextEvent(display, &xevent);
|
/* Use SDL_IOR_NO_RETRY to ensure SIGINT will break us out of our wait */
|
||||||
|
int err = SDL_IOReady(ConnectionNumber(display), SDL_IOR_READ | SDL_IOR_NO_RETRY, timeout);
|
||||||
|
if (err > 0) {
|
||||||
|
X11_XNextEvent(display, &xevent);
|
||||||
|
} else if (err == 0) {
|
||||||
|
/* Timeout */
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
/* Error returned from poll()/select() */
|
||||||
|
|
||||||
|
if (errno == EINTR) {
|
||||||
|
/* If the wait was interrupted by a signal, we may have generated a
|
||||||
|
* SDL_QUIT event. Let the caller know to call SDL_PumpEvents(). */
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
X11_DispatchEvent(_this, &xevent);
|
X11_DispatchEvent(_this, &xevent);
|
||||||
|
|
Loading…
Reference in New Issue