Fix: compat futex duplicated lock and completion
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Mon, 30 Sep 2013 18:54:22 +0000 (14:54 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Mon, 30 Sep 2013 18:54:22 +0000 (14:54 -0400)
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 <nvs@tbricks.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
compat_futex.c

index bb928e61d6849fc90f63ab5b07fcf82718f28990..e7342fe38ccda2330b45e157cd0c1d7cb02cd3ef 100644 (file)
 #include <urcu/arch.h>
 #include <urcu/futex.h>
 
 #include <urcu/arch.h>
 #include <urcu/futex.h>
 
-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.
 
 /*
  * _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();
 
         */
        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;
        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:
                break;
        case FUTEX_WAKE:
-               pthread_cond_broadcast(&compat_futex_cond);
+               pthread_cond_broadcast(&__urcu_compat_futex_cond);
                break;
        default:
                gret = -EINVAL;
        }
 end:
                break;
        default:
                gret = -EINVAL;
        }
 end:
-       ret = pthread_mutex_unlock(&compat_futex_lock);
+       ret = pthread_mutex_unlock(&__urcu_compat_futex_lock);
        assert(!ret);
        return gret;
 }
        assert(!ret);
        return gret;
 }
This page took 0.033901 seconds and 4 git commands to generate.