From: Lai Jiangshan Date: Thu, 9 Aug 2012 14:19:14 +0000 (-0400) Subject: urcu: fix compat_futex_noasync() X-Git-Tag: v0.7.4~5 X-Git-Url: https://git.liburcu.org/?p=urcu.git;a=commitdiff_plain;h=5b80127fe2aa3defd8a82acec727be2fc885087a urcu: fix compat_futex_noasync() This patch fix two critical problems in the compatibility fallback of compact_futex_noasync(): 1) compat_futex_cond is not bound to any @uaddr, it services all @uaddr, if you wakeup only one thread(pthread_cond_signal), the @uaddr of this waking thread and the @uaddr of the woken-up thread may be different. The woken-up thread will very probably go to sleep again because his own condition is not true. *And* this waking thread(FUTEX_WAKE) wake up NOTHING. 2) If the caller want to wake up all waiting threads, he will use INT_MAX for @val, and: for (i = 0; i < INT_MAX; i++) pthread_cond_signal(&compat_futex_cond); becomes almost infinity loop. Signed-off-by: Lai Jiangshan Signed-off-by: Mathieu Desnoyers --- diff --git a/compat_futex.c b/compat_futex.c index 04de596..bb928e6 100644 --- a/compat_futex.c +++ b/compat_futex.c @@ -43,7 +43,7 @@ static pthread_cond_t compat_futex_cond = PTHREAD_COND_INITIALIZER; int compat_futex_noasync(int32_t *uaddr, int op, int32_t val, const struct timespec *timeout, int32_t *uaddr2, int32_t val3) { - int ret, i, gret = 0; + int ret, gret = 0; /* * Check if NULL. Don't let users expect that they are taken into @@ -67,8 +67,7 @@ int compat_futex_noasync(int32_t *uaddr, int op, int32_t val, pthread_cond_wait(&compat_futex_cond, &compat_futex_lock); break; case FUTEX_WAKE: - for (i = 0; i < val; i++) - pthread_cond_signal(&compat_futex_cond); + pthread_cond_broadcast(&compat_futex_cond); break; default: gret = -EINVAL;