diff options
author | Eric Wong <normalperson@yhbt.net> | 2013-06-21 03:34:25 +0000 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2013-06-25 21:33:57 +0000 |
commit | 07569135228020880d8092d9aaf7d6325cc48d26 (patch) | |
tree | bd3716776e146bd41e4b8510875f043a02a0ac7b /sig.c | |
parent | ba8a3673a6ada7122c89e420455901b6b1288500 (diff) | |
download | cmogstored-07569135228020880d8092d9aaf7d6325cc48d26.tar.gz |
Cancellation with epoll_wait, accept4 (and accept) may cause events to be lost, as cancellation relies on signals anyways in glibc/Linux. So instead, we use signaling ourselves and explicitly test for cancellation only if we know we are interrupted and in a state where a thread can safely be cancelled. ref: http://mid.gmane.org/CAE2sS1gxQkqmcywQ07pmgNHM+CyqzMkuASVjmWDL+hgaTMURWQ@mail.gmail.com
Diffstat (limited to 'sig.c')
-rw-r--r-- | sig.c | 15 |
1 files changed, 15 insertions, 0 deletions
@@ -9,12 +9,27 @@ */ static sigset_t fullset; +static sigset_t cancelset; sigset_t mog_emptyset; __attribute__((constructor)) void sig_init(void) { CHECK(int, 0, sigfillset(&fullset)); CHECK(int, 0, sigemptyset(&mog_emptyset)); + CHECK(int, 0, sigfillset(&cancelset)); + CHECK(int, 0, sigdelset(&cancelset, SIGURG)); +} + +/* this runs at the start of every thread managed by thrpool */ +void mog_cancel_prepare(void) +{ + int old; + + CHECK(int, 0, pthread_sigmask(SIG_SETMASK, &cancelset, NULL)); + mog_cancel_disable(); + CHECK(int, 0, pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &old)); + assert(old == PTHREAD_CANCEL_DEFERRED + && "async cancel enabled redundantly"); } void mog_intr_disable(void) |