pselect atomic signal masking for Xlib (deadlocks bad)

This commit is contained in:
Jack Andersen 2015-11-17 10:25:17 -10:00
parent 4d133edd2c
commit 9e1441c323
2 changed files with 20 additions and 9 deletions

View File

@ -129,6 +129,11 @@ class HIDListenerUdev final : public IHIDListener
s.sa_flags = 0; s.sa_flags = 0;
sigaction(SIGTERM, &s, nullptr); sigaction(SIGTERM, &s, nullptr);
sigset_t waitmask, origmask;
sigemptyset(&waitmask);
sigaddset(&waitmask, SIGTERM);
pthread_sigmask(SIG_BLOCK, &waitmask, &origmask);
udev_monitor_enable_receiving(listener->m_udevMon); udev_monitor_enable_receiving(listener->m_udevMon);
int fd = udev_monitor_get_fd(listener->m_udevMon); int fd = udev_monitor_get_fd(listener->m_udevMon);
while (listener->m_udevRunning) while (listener->m_udevRunning)
@ -136,7 +141,7 @@ class HIDListenerUdev final : public IHIDListener
fd_set fds; fd_set fds;
FD_ZERO(&fds); FD_ZERO(&fds);
FD_SET(fd, &fds); FD_SET(fd, &fds);
if (select(fd+1, &fds, nullptr, nullptr, nullptr) < 0) if (pselect(fd+1, &fds, nullptr, nullptr, nullptr, &origmask) < 0)
{ {
/* SIGTERM handled here */ /* SIGTERM handled here */
if (errno == EINTR) if (errno == EINTR)

View File

@ -223,21 +223,27 @@ public:
return PLAT_XLIB; return PLAT_XLIB;
} }
/* Empty handler for SIGTERM */ /* Empty handler for SIGINT */
static void _sigterm(int) {} static void _sigint(int) {}
int run() int run()
{ {
if (!m_xDisp) if (!m_xDisp)
return 1; return 1;
/* SIGTERM will be used to terminate main thread when client thread ends */ /* SIGINT will be used to cancel main thread when client thread ends
* (also enables graceful quitting via ctrl-c) */
pthread_t mainThread = pthread_self(); pthread_t mainThread = pthread_self();
struct sigaction s; struct sigaction s;
s.sa_handler = _sigterm; s.sa_handler = _sigint;
sigemptyset(&s.sa_mask); sigemptyset(&s.sa_mask);
s.sa_flags = 0; s.sa_flags = 0;
sigaction(SIGTERM, &s, nullptr); sigaction(SIGINT, &s, nullptr);
sigset_t waitmask, origmask;
sigemptyset(&waitmask);
sigaddset(&waitmask, SIGINT);
pthread_sigmask(SIG_BLOCK, &waitmask, &origmask);
/* Spawn client thread */ /* Spawn client thread */
int clientReturn = INT_MIN; int clientReturn = INT_MIN;
@ -250,7 +256,7 @@ public:
innerLk.unlock(); innerLk.unlock();
initcv.notify_one(); initcv.notify_one();
clientReturn = m_callback.appMain(this); clientReturn = m_callback.appMain(this);
pthread_kill(mainThread, SIGTERM); pthread_kill(mainThread, SIGINT);
}); });
initcv.wait(outerLk); initcv.wait(outerLk);
@ -261,9 +267,9 @@ public:
FD_ZERO(&fds); FD_ZERO(&fds);
FD_SET(m_xcbFd, &fds); FD_SET(m_xcbFd, &fds);
FD_SET(m_dbusFd, &fds); FD_SET(m_dbusFd, &fds);
if (select(m_maxFd+1, &fds, NULL, NULL, NULL) < 0) if (pselect(m_maxFd+1, &fds, NULL, NULL, NULL, &origmask) < 0)
{ {
/* SIGTERM handled here */ /* SIGINT handled here */
if (errno == EINTR) if (errno == EINTR)
break; break;
} }