From: Mathieu Desnoyers Date: Mon, 30 Sep 2013 18:54:22 +0000 (-0400) Subject: Fix: compat futex duplicated lock and completion X-Git-Tag: v0.9.0~139 X-Git-Url: https://git.liburcu.org/?a=commitdiff_plain;ds=sidebyside;h=5c02e37d09b7b89f68429751344d2af00c89f4fd;p=urcu.git Fix: compat futex duplicated lock and completion compat_futex.c has one instance included in each urcu shared object, as well as within some of the test applications. However, it is expected that an entire program interact with the same lock and completion variables. Therefore, define them as globally visible, but weak, so the entire program agree on which object should be used. Reported-by: Vladimir Nikulichev Signed-off-by: Mathieu Desnoyers --- diff --git a/compat_futex.c b/compat_futex.c index bb928e6..e7342fe 100644 --- a/compat_futex.c +++ b/compat_futex.c @@ -31,8 +31,18 @@ #include #include -static pthread_mutex_t compat_futex_lock = PTHREAD_MUTEX_INITIALIZER; -static pthread_cond_t compat_futex_cond = PTHREAD_COND_INITIALIZER; +/* + * Using attribute "weak" for __urcu_compat_futex_lock and + * __urcu_compat_futex_cond. Those are globally visible by the entire + * program, even though many shared objects may have their own version. + * The first version that gets loaded will be used by the entire program + * (executable and all shared objects). + */ + +__attribute__((weak)) +pthread_mutex_t __urcu_compat_futex_lock = PTHREAD_MUTEX_INITIALIZER; +__attribute__((weak)) +pthread_cond_t __urcu_compat_futex_cond = PTHREAD_COND_INITIALIZER; /* * _NOT SIGNAL-SAFE_. pthread_cond is not signal-safe anyway. Though. @@ -58,22 +68,22 @@ int compat_futex_noasync(int32_t *uaddr, int op, int32_t val, */ cmm_smp_mb(); - ret = pthread_mutex_lock(&compat_futex_lock); + ret = pthread_mutex_lock(&__urcu_compat_futex_lock); assert(!ret); switch (op) { case FUTEX_WAIT: if (*uaddr != val) goto end; - pthread_cond_wait(&compat_futex_cond, &compat_futex_lock); + pthread_cond_wait(&__urcu_compat_futex_cond, &__urcu_compat_futex_lock); break; case FUTEX_WAKE: - pthread_cond_broadcast(&compat_futex_cond); + pthread_cond_broadcast(&__urcu_compat_futex_cond); break; default: gret = -EINVAL; } end: - ret = pthread_mutex_unlock(&compat_futex_lock); + ret = pthread_mutex_unlock(&__urcu_compat_futex_lock); assert(!ret); return gret; }