From cc89866b65a313de0a304b2f1b13952ea2b3b595 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20v=2E=20L=C3=B6wis?= Date: Sun, 17 Mar 2002 09:53:51 +0000 Subject: Patch #525532: Add support for POSIX semaphores. --- Python/thread_pthread.h | 119 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/Python/thread_pthread.h b/Python/thread_pthread.h index 6e92128..56aec44 100644 --- a/Python/thread_pthread.h +++ b/Python/thread_pthread.h @@ -11,6 +11,10 @@ #undef destructor #endif #include +#ifdef _POSIX_SEMAPHORES +#include +#include +#endif /* try to determine what version of the Pthread Standard is installed. @@ -76,6 +80,16 @@ #endif +/* Whether or not to use semaphores directly rather than emulating them with + * mutexes and condition variables: + */ +#ifdef _POSIX_SEMAPHORES +# define USE_SEMAPHORES +#else +# undef USE_SEMAPHORES +#endif + + /* On platforms that don't use standard POSIX threads pthread_sigmask() * isn't present. DEC threads uses sigprocmask() instead as do most * other UNIX International compliant systems that don't have the full @@ -294,6 +308,109 @@ PyThread__exit_prog(int status) } #endif /* NO_EXIT_PROG */ +#ifdef USE_SEMAPHORES + +/* + * Lock support. + */ + +PyThread_type_lock +PyThread_allocate_lock(void) +{ + sem_t *lock; + int status, error = 0; + + dprintf(("PyThread_allocate_lock called\n")); + if (!initialized) + PyThread_init_thread(); + + lock = (sem_t *)malloc(sizeof(sem_t)); + + if (lock) { + status = sem_init(lock,0,1); + CHECK_STATUS("sem_init"); + + if (error) { + free((void *)lock); + lock = NULL; + } + } + + dprintf(("PyThread_allocate_lock() -> %p\n", lock)); + return (PyThread_type_lock)lock; +} + +void +PyThread_free_lock(PyThread_type_lock lock) +{ + sem_t *thelock = (sem_t *)lock; + int status, error = 0; + + dprintf(("PyThread_free_lock(%p) called\n", lock)); + + if (!thelock) + return; + + status = sem_destroy(thelock); + CHECK_STATUS("sem_destroy"); + + free((void *)thelock); +} + +/* + * As of February 2002, Cygwin thread implementations mistakenly report error + * codes in the return value of the sem_ calls (like the pthread_ functions). + * Correct implementations return -1 and put the code in errno. This supports + * either. + */ +static int +fix_status(int status) +{ + return (status == -1) ? errno : status; +} + +int +PyThread_acquire_lock(PyThread_type_lock lock, int waitflag) +{ + int success; + sem_t *thelock = (sem_t *)lock; + int status, error = 0; + + dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag)); + + do { + if (waitflag) + status = fix_status(sem_wait(thelock)); + else + status = fix_status(sem_trywait(thelock)); + } while (status == EINTR); /* Retry if interrupted by a signal */ + + if (waitflag) { + CHECK_STATUS("sem_wait"); + } else if (status != EAGAIN) { + CHECK_STATUS("sem_trywait"); + } + + success = (status == 0) ? 1 : 0; + + dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success)); + return success; +} + +void +PyThread_release_lock(PyThread_type_lock lock) +{ + sem_t *thelock = (sem_t *)lock; + int status, error = 0; + + dprintf(("PyThread_release_lock(%p) called\n", lock)); + + status = sem_post(thelock); + CHECK_STATUS("sem_post"); +} + +#else /* USE_SEMAPHORES */ + /* * Lock support. */ @@ -405,3 +522,5 @@ PyThread_release_lock(PyThread_type_lock lock) status = pthread_cond_signal( &thelock->lock_released ); CHECK_STATUS("pthread_cond_signal"); } + +#endif /* USE_SEMAPHORES */ -- cgit v0.12