diff options
author | Timo Teras <timo.teras@iki.fi> | 2010-04-16 16:29:46 +0300 |
---|---|---|
committer | Austin Foxley <austinf@cetoncorp.com> | 2010-04-16 10:13:14 -0700 |
commit | 0eadd98d30c51d26fde4062e6b8c48f3c9b5148d (patch) | |
tree | abbb3367ac54b35b8d7198af729996fe1531dd95 /libc/sysdeps | |
parent | 837e8425ce9a0c1ad1c58a00cf3b9e949e7b17cd (diff) |
libc: remove libc weak __pthreads_* wrappers
It is not possible to override for libpthread to override
the weak libc definitions. This has never worked in uclibc, and
does no longer work in glibc either (unless you use LD_DYNAMIC_WEAK).
The proper thing to do is have weak prototypes in libc, and
definitions in libpthread only. This way libc runs even if
those functions are not defined, but just needs to protect
against the NULL values (done by implementing __uclibc_maybe_call).
This fix the problems if libc is linked before libpthread or
if libpthread is pulled by a dependency library.
Signed-off-by: Timo Teras <timo.teras@iki.fi>
Signed-off-by: Austin Foxley <austinf@cetoncorp.com>
Diffstat (limited to 'libc/sysdeps')
-rw-r--r-- | libc/sysdeps/linux/common/bits/uClibc_mutex.h | 22 | ||||
-rw-r--r-- | libc/sysdeps/linux/common/bits/uClibc_pthread.h | 7 |
2 files changed, 21 insertions, 8 deletions
diff --git a/libc/sysdeps/linux/common/bits/uClibc_mutex.h b/libc/sysdeps/linux/common/bits/uClibc_mutex.h index c6094c3d2..02bcc7225 100644 --- a/libc/sysdeps/linux/common/bits/uClibc_mutex.h +++ b/libc/sysdeps/linux/common/bits/uClibc_mutex.h @@ -13,8 +13,16 @@ #ifdef __UCLIBC_HAS_THREADS__ #include <pthread.h> +#include <bits/libc-lock.h> #include <bits/uClibc_pthread.h> +#define __uclibc_maybe_call(FUNC, ARGS) \ + (__extension__ ({ \ + __typeof (FUNC) *_fn = (FUNC); \ + if (_fn != NULL) { (*_fn) ARGS; } \ + })) + + #define __UCLIBC_MUTEX_TYPE pthread_mutex_t #define __UCLIBC_MUTEX(M) pthread_mutex_t M @@ -22,19 +30,23 @@ #define __UCLIBC_MUTEX_STATIC(M,I) static pthread_mutex_t M = I #define __UCLIBC_MUTEX_EXTERN(M) extern pthread_mutex_t M +#define __UCLIBC_MUTEX_INIT_VAR(M) \ + __uclibc_maybe_call(__pthread_mutex_init,(&(M),NULL)) + #define __UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE(M) \ - __pthread_mutex_lock(&(M)) + __uclibc_maybe_call(__pthread_mutex_lock,(&(M))) #define __UCLIBC_MUTEX_UNLOCK_CANCEL_UNSAFE(M) \ - __pthread_mutex_unlock(&(M)) + __uclibc_maybe_call(__pthread_mutex_unlock,(&(M))) #define __UCLIBC_MUTEX_TRYLOCK_CANCEL_UNSAFE(M) \ - __pthread_mutex_trylock(&(M)) + __uclibc_maybe_call(__pthread_mutex_trylock,(&(M))) #define __UCLIBC_MUTEX_CONDITIONAL_LOCK(M,C) \ do { \ struct _pthread_cleanup_buffer __infunc_pthread_cleanup_buffer; \ - if (C) { \ + int __infunc_need_locking = ((C) && (__pthread_mutex_lock != NULL)); \ + if (__infunc_need_locking) { \ _pthread_cleanup_push_defer(&__infunc_pthread_cleanup_buffer, \ (void (*) (void *))__pthread_mutex_unlock, \ &(M)); \ @@ -43,7 +55,7 @@ ((void)0) #define __UCLIBC_MUTEX_CONDITIONAL_UNLOCK(M,C) \ - if (C) { \ + if (__infunc_need_locking) { \ _pthread_cleanup_pop_restore(&__infunc_pthread_cleanup_buffer,1); \ } \ } while (0) diff --git a/libc/sysdeps/linux/common/bits/uClibc_pthread.h b/libc/sysdeps/linux/common/bits/uClibc_pthread.h index 1d6209f5e..15aa1deed 100644 --- a/libc/sysdeps/linux/common/bits/uClibc_pthread.h +++ b/libc/sysdeps/linux/common/bits/uClibc_pthread.h @@ -28,6 +28,9 @@ #endif #if defined _LIBC && (defined IS_IN_libc || defined NOT_IN_libc) + +struct _pthread_cleanup_buffer; + /* Threading functions internal to uClibc. Make these thread functions * weak so that we can elide them from single-threaded processes. */ extern int weak_function __pthread_mutex_init (pthread_mutex_t *__mutex, @@ -35,16 +38,14 @@ extern int weak_function __pthread_mutex_init (pthread_mutex_t *__mutex, extern int weak_function __pthread_mutex_destroy (pthread_mutex_t *__mutex); extern int weak_function __pthread_mutex_lock (pthread_mutex_t *__mutex); extern int weak_function __pthread_mutex_unlock (pthread_mutex_t *__mutex); -extern void __uclibc_mutex_unlock (void *) attribute_hidden; extern int weak_function __pthread_mutex_trylock (pthread_mutex_t *__mutex); -# ifndef __UCLIBC_HAS_THREADS_NATIVE__ extern void weak_function _pthread_cleanup_push_defer ( struct _pthread_cleanup_buffer *__buffer, void (*__routine) (void *), void *__arg); extern void weak_function _pthread_cleanup_pop_restore ( struct _pthread_cleanup_buffer *__buffer, int __execute); -# endif + #endif #endif |