Patch #525532: Add support for POSIX semaphores.
This commit is contained in:
parent
8e0c82a35f
commit
cc89866b65
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue