diff options
author | Samuel Thibault <sthibault@debian.org> | 2009-08-20 09:54:45 +0200 |
---|---|---|
committer | Julien Danjou <julien@danjou.info> | 2009-08-20 09:54:45 +0200 |
commit | 3d8dfe9a9ad0a22bdcec555bd3d0d9b5950a6dab (patch) | |
tree | d241894d05e20db502e7901e7c9f0d31bca35903 | |
parent | ef2431f5bdef1da9f2f7701232def164910b191b (diff) |
Provide sem_* functions
Some applications, instead of using pthread_mutex_t, use anonymous
semaphores (sem_init) for locking.
Signed-off-by: Julien Danjou <julien@danjou.info>
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | stubs.c | 103 |
2 files changed, 104 insertions, 1 deletions
diff --git a/configure.ac b/configure.ac index b7f0698..ffccea9 100644 --- a/configure.ac +++ b/configure.ac @@ -31,7 +31,7 @@ fi PKG_CONFIG_LIBS= -AC_CHECK_FUNCS([pthread_self pthread_mutex_init pthread_mutex_destroy pthread_mutex_lock pthread_mutex_unlock pthread_cond_init pthread_cond_destroy pthread_cond_wait pthread_cond_signal pthread_cond_broadcast pthread_equal], +AC_CHECK_FUNCS([pthread_self pthread_mutex_init pthread_mutex_destroy pthread_mutex_lock pthread_mutex_unlock pthread_cond_init pthread_cond_destroy pthread_cond_wait pthread_cond_signal pthread_cond_broadcast pthread_equal sem_init sem_destroy sem_wait sem_trywait], [], [PKG_CONFIG_LIBS='-L${libdir} -lpthread-stubs']) AC_SUBST([PKG_CONFIG_LIBS]) AM_CONDITIONAL(BUILD_LIB, test "x$PKG_CONFIG_LIBS" != x) @@ -25,6 +25,8 @@ */ #include <pthread.h> +#include <errno.h> +#include <semaphore.h> #include "config.h" #ifndef HAVE_PTHREAD_SELF @@ -126,6 +128,51 @@ int pthread_equal() __attribute__ ((weak, alias ("__pthread_equal_stub"))); # endif #endif +#ifndef HAVE_SEM_INIT +#define NEED_SEM_INIT_STUB +# ifdef SUPPORT_ATTRIBUTE_ALIAS +int sem_init() __attribute__ ((weak, alias ("__sem_init_stub"))); +# else +# pragma weak sem_init = __sem_init_stub +# endif +#endif + +#ifndef HAVE_SEM_DESTROY +#define NEED_ZERO_STUB +# ifdef SUPPORT_ATTRIBUTE_ALIAS +int sem_destroy() __attribute__ ((weak, alias ("__pthread_zero_stub"))); +# else +# pragma weak sem_destroy = __sem_destroy_stub +# endif +#endif + +#ifndef HAVE_SEM_WAIT +#define NEED_SEM_WAIT_STUB +# ifdef SUPPORT_ATTRIBUTE_ALIAS +int sem_wait() __attribute__ ((weak, alias ("__sem_wait_stub"))); +# else +# pragma weak sem_wait = __sem_wait_stub +# endif +#endif + +#ifndef HAVE_SEM_TRYWAIT +#define NEED_SEM_TRYWAIT_STUB +# ifdef SUPPORT_ATTRIBUTE_ALIAS +int sem_trywait() __attribute__ ((weak, alias ("__sem_trywait_stub"))); +# else +# pragma weak sem_trywait = __sem_trywait_stub +# endif +#endif + +#ifndef HAVE_SEM_POST +#define NEED_SEM_POST_STUB +# ifdef SUPPORT_ATTRIBUTE_ALIAS +int sem_post() __attribute__ ((weak, alias ("__sem_post_stub"))); +# else +# pragma weak sem_post = __sem_post_stub +# endif +#endif + #ifdef NEED_ZERO_STUB static int __pthread_zero_stub() { @@ -139,3 +186,59 @@ static int __pthread_equal_stub(pthread_t t1, pthread_t t2) return (t1 == t2); } #endif + +#ifdef NEED_SEM_INIT_STUB +static int __sem_init_stub(sem_t *_sem, int pshared, unsigned int value) +{ + unsigned int *sem = (unsigned int *) _sem; + if (pshared) { + errno = ENOSYS; + return -1; + } + + if (sizeof(sem_t) < sizeof(unsigned int)) { + errno = ENOSYS; + return -1; + } + + *sem = value; + return 0; +} +#endif + +#ifdef NEED_SEM_WAIT_STUB +static int __sem_wait_stub(sem_t *_sem) +{ + unsigned int *sem = (unsigned int *) _sem; + if (!*sem) { + /* Not available, simulate a blocking sem_wait */ + pause(); + errno = EINTR; + return -1; + } + *sem--; + return 0; +} +#endif + +#ifdef NEED_SEM_TRYWAIT_STUB +static int __sem_trywait_stub(sem_t *_sem) +{ + unsigned int *sem = (unsigned int *) _sem; + if (!*sem) { + errno = EAGAIN; + return -1; + } + *sem--; + return 0; +} +#endif + +#ifdef NEED_SEM_POST_STUB +static int __sem_post_stub(sem_t *_sem) +{ + unsigned int *sem = (unsigned int *) _sem; + *sem++; + return 0; +} +#endif |