diff options
author | Martin v. Löwis <martin@v.loewis.de> | 2002-03-17 09:53:51 (GMT) |
---|---|---|
committer | Martin v. Löwis <martin@v.loewis.de> | 2002-03-17 09:53:51 (GMT) |
commit | cc89866b65a313de0a304b2f1b13952ea2b3b595 (patch) | |
tree | 972e28acae29ddee05f27d6653cfc7a0c1071bd5 /Python/thread_pthread.h | |
parent | 8e0c82a35f1f9a9d43e85a0567382cb40b7d2525 (diff) | |
download | cpython-cc89866b65a313de0a304b2f1b13952ea2b3b595.zip cpython-cc89866b65a313de0a304b2f1b13952ea2b3b595.tar.gz cpython-cc89866b65a313de0a304b2f1b13952ea2b3b595.tar.bz2 |
Patch #525532: Add support for POSIX semaphores.
Diffstat (limited to 'Python/thread_pthread.h')
-rw-r--r-- | Python/thread_pthread.h | 119 |
1 files changed, 119 insertions, 0 deletions
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 <signal.h> +#ifdef _POSIX_SEMAPHORES +#include <semaphore.h> +#include <errno.h> +#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 */ |