]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Patch #525532: Add support for POSIX semaphores.
authorMartin v. Löwis <martin@v.loewis.de>
Sun, 17 Mar 2002 09:53:51 +0000 (09:53 +0000)
committerMartin v. Löwis <martin@v.loewis.de>
Sun, 17 Mar 2002 09:53:51 +0000 (09:53 +0000)
Python/thread_pthread.h

index 6e921287e172f68a2dd2fe13dd2b27dd25b22a56..56aec4460dec4e5f083aeb78168ff04b4bdba5b2 100644 (file)
 #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.
 #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 */