forked from external/yambar
main: detect when X server dies, and abort
This is done by creating an XCB connection, whose only purpose is to detect a POLLHUP (xcb disconncet). Furthermore, make sure SIGINT is blocked in all threads except the main thread.
This commit is contained in:
parent
3f226d8cce
commit
fdadf577e9
1 changed files with 41 additions and 3 deletions
44
main.c
44
main.c
|
@ -8,6 +8,7 @@
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
#include <threads.h>
|
#include <threads.h>
|
||||||
|
#include <poll.h>
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/eventfd.h>
|
#include <sys/eventfd.h>
|
||||||
|
@ -115,18 +116,55 @@ main(int argc, const char *const *argv)
|
||||||
.abort_fd = abort_fd,
|
.abort_fd = abort_fd,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Block SIGINT (this is under the assumption that threads inherit
|
||||||
|
* the signal mask */
|
||||||
|
sigset_t signal_mask;
|
||||||
|
sigemptyset(&signal_mask);
|
||||||
|
sigaddset(&signal_mask, SIGINT);
|
||||||
|
pthread_sigmask(SIG_BLOCK, &signal_mask, NULL);
|
||||||
|
|
||||||
thrd_t bar_thread;
|
thrd_t bar_thread;
|
||||||
thrd_create(&bar_thread, (int (*)(void *))bar->run, &bar_ctx);
|
thrd_create(&bar_thread, (int (*)(void *))bar->run, &bar_ctx);
|
||||||
|
|
||||||
|
/* Now unblock. We should be only thread receiving SIGINT */
|
||||||
|
pthread_sigmask(SIG_UNBLOCK, &signal_mask, NULL);
|
||||||
|
|
||||||
|
/* Connect to XCB, to be able to detect a disconnect (allowing us
|
||||||
|
* to exit) */
|
||||||
|
xcb_connection_t *xcb = xcb_connect(NULL, NULL);
|
||||||
|
assert(xcb != NULL);
|
||||||
|
|
||||||
|
/* Wait for SIGINT, or XCB disconnect */
|
||||||
while (!aborted) {
|
while (!aborted) {
|
||||||
sleep(999999999);
|
struct pollfd fds[] = {
|
||||||
|
{.fd = xcb_get_file_descriptor(xcb), .events = POLLPRI}
|
||||||
|
};
|
||||||
|
|
||||||
|
poll(fds, 1, -1);
|
||||||
|
|
||||||
|
if (aborted)
|
||||||
|
break;
|
||||||
|
|
||||||
|
LOG_INFO("XCB poll data");
|
||||||
|
|
||||||
|
if (fds[0].revents & POLLHUP) {
|
||||||
|
LOG_INFO("disconnected from XCB, exiting");
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Signal abort to all workers */
|
xcb_disconnect(xcb);
|
||||||
|
|
||||||
|
if (aborted)
|
||||||
|
LOG_INFO("aborted");
|
||||||
|
|
||||||
|
/* Signal abort to other threads */
|
||||||
write(abort_fd, &(uint64_t){1}, sizeof(uint64_t));
|
write(abort_fd, &(uint64_t){1}, sizeof(uint64_t));
|
||||||
|
|
||||||
int res;
|
int res;
|
||||||
thrd_join(bar_thread, &res);
|
int r = thrd_join(bar_thread, &res);
|
||||||
|
if (r != 0)
|
||||||
|
LOG_ERRNO_P("failed to join bar thread", r);
|
||||||
|
|
||||||
bar->destroy(bar);
|
bar->destroy(bar);
|
||||||
yml_destroy(conf);
|
yml_destroy(conf);
|
||||||
|
|
Loading…
Add table
Reference in a new issue