summaryrefslogtreecommitdiffstats
path: root/Python/thread_pthread.h
diff options
context:
space:
mode:
authorMartin v. Löwis <martin@v.loewis.de>2002-03-17 09:53:51 (GMT)
committerMartin v. Löwis <martin@v.loewis.de>2002-03-17 09:53:51 (GMT)
commitcc89866b65a313de0a304b2f1b13952ea2b3b595 (patch)
tree972e28acae29ddee05f27d6653cfc7a0c1071bd5 /Python/thread_pthread.h
parent8e0c82a35f1f9a9d43e85a0567382cb40b7d2525 (diff)
downloadcpython-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.h119
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 */