X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=src%2Furcu.c;h=c60307e15351241dbb0158b5d48d589852fcca65;hb=90f72b8c054ca4e3b4b45f630549c784e26ce79a;hp=59f2e8f18fdddc5a781e25d2478ca86e18a9fee5;hpb=a18d0428065b301086d4e8a85bc057dc39946891;p=userspace-rcu.git diff --git a/src/urcu.c b/src/urcu.c index 59f2e8f..c60307e 100644 --- a/src/urcu.c +++ b/src/urcu.c @@ -109,9 +109,13 @@ void rcu_init(void) static int init_done; void __attribute__((constructor)) rcu_init(void); -void __attribute__((destructor)) rcu_exit(void); + +static DEFINE_URCU_TLS(int, rcu_signal_was_blocked); #endif +void __attribute__((destructor)) rcu_exit(void); +static void urcu_call_rcu_exit(void); + /* * rcu_gp_lock ensures mutual exclusion between threads calling * synchronize_rcu(). @@ -537,8 +541,52 @@ int rcu_read_ongoing(void) return _rcu_read_ongoing(); } +#ifdef RCU_SIGNAL +/* + * Make sure the signal used by the urcu-signal flavor is unblocked + * while the thread is registered. + */ +static +void urcu_signal_unblock(void) +{ + sigset_t mask, oldmask; + int ret; + + ret = sigemptyset(&mask); + urcu_posix_assert(!ret); + ret = sigaddset(&mask, SIGRCU); + urcu_posix_assert(!ret); + ret = pthread_sigmask(SIG_UNBLOCK, &mask, &oldmask); + urcu_posix_assert(!ret); + URCU_TLS(rcu_signal_was_blocked) = sigismember(&oldmask, SIGRCU); +} + +static +void urcu_signal_restore(void) +{ + sigset_t mask; + int ret; + + if (!URCU_TLS(rcu_signal_was_blocked)) + return; + ret = sigemptyset(&mask); + urcu_posix_assert(!ret); + ret = sigaddset(&mask, SIGRCU); + urcu_posix_assert(!ret); + ret = pthread_sigmask(SIG_BLOCK, &mask, NULL); + urcu_posix_assert(!ret); +} +#else +static +void urcu_signal_unblock(void) { } +static +void urcu_signal_restore(void) { } +#endif + void rcu_register_thread(void) { + urcu_signal_unblock(); + URCU_TLS(rcu_reader).tid = pthread_self(); urcu_posix_assert(URCU_TLS(rcu_reader).need_mb == 0); urcu_posix_assert(!(URCU_TLS(rcu_reader).ctr & URCU_GP_CTR_NEST_MASK)); @@ -558,6 +606,8 @@ void rcu_unregister_thread(void) URCU_TLS(rcu_reader).registered = 0; cds_list_del(&URCU_TLS(rcu_reader).node); mutex_unlock(&rcu_registry_lock); + + urcu_signal_restore(); } #ifdef RCU_MEMBARRIER @@ -648,21 +698,24 @@ void rcu_init(void) urcu_die(errno); } +/* + * Don't unregister the SIGRCU signal handler anymore, because + * call_rcu threads could still be using it shortly before the + * application exits. + * Assertion disabled because call_rcu threads are now rcu + * readers, and left running at exit. + * urcu_posix_assert(cds_list_empty(®istry)); + */ + +#endif /* #ifdef RCU_SIGNAL */ + void rcu_exit(void) { - /* - * Don't unregister the SIGRCU signal handler anymore, because - * call_rcu threads could still be using it shortly before the - * application exits. - * Assertion disabled because call_rcu threads are now rcu - * readers, and left running at exit. - * urcu_posix_assert(cds_list_empty(®istry)); - */ + urcu_call_rcu_exit(); } -#endif /* #ifdef RCU_SIGNAL */ - DEFINE_RCU_FLAVOR(rcu_flavor); #include "urcu-call-rcu-impl.h" #include "urcu-defer-impl.h" +#include "urcu-poll-impl.h"