mirror of
https://github.com/python/cpython.git
synced 2025-08-03 16:39:00 +00:00
Patch #525532: Add support for POSIX semaphores.
This commit is contained in:
parent
8e0c82a35f
commit
cc89866b65
1 changed files with 119 additions and 0 deletions
|
@ -11,6 +11,10 @@
|
||||||
#undef destructor
|
#undef destructor
|
||||||
#endif
|
#endif
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#ifdef _POSIX_SEMAPHORES
|
||||||
|
#include <semaphore.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* try to determine what version of the Pthread Standard is installed.
|
/* try to determine what version of the Pthread Standard is installed.
|
||||||
|
@ -76,6 +80,16 @@
|
||||||
#endif
|
#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()
|
/* On platforms that don't use standard POSIX threads pthread_sigmask()
|
||||||
* isn't present. DEC threads uses sigprocmask() instead as do most
|
* isn't present. DEC threads uses sigprocmask() instead as do most
|
||||||
* other UNIX International compliant systems that don't have the full
|
* other UNIX International compliant systems that don't have the full
|
||||||
|
@ -294,6 +308,109 @@ PyThread__exit_prog(int status)
|
||||||
}
|
}
|
||||||
#endif /* NO_EXIT_PROG */
|
#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.
|
* Lock support.
|
||||||
*/
|
*/
|
||||||
|
@ -405,3 +522,5 @@ PyThread_release_lock(PyThread_type_lock lock)
|
||||||
status = pthread_cond_signal( &thelock->lock_released );
|
status = pthread_cond_signal( &thelock->lock_released );
|
||||||
CHECK_STATUS("pthread_cond_signal");
|
CHECK_STATUS("pthread_cond_signal");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* USE_SEMAPHORES */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue