Patch #525532: Add support for POSIX semaphores.

This commit is contained in:
Martin v. Löwis 2002-03-17 09:53:51 +00:00
parent 8e0c82a35f
commit cc89866b65
1 changed files with 119 additions and 0 deletions

View File

@ -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 */