*** thread_pthread.h.orig Sun Mar 3 12:05:31 2002 --- thread_pthread.h.sem Sun Mar 3 12:05:43 2002 *************** *** 11,16 **** --- 11,20 ---- #undef destructor #endif #include + #ifdef _POSIX_SEMAPHORES + #include + #include + #endif /* try to determine what version of the Pthread Standard is installed. *************** *** 76,81 **** --- 80,95 ---- #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,299 **** --- 308,416 ---- } #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,407 **** --- 522,526 ---- status = pthread_cond_signal( &thelock->lock_released ); CHECK_STATUS("pthread_cond_signal"); } + + #endif /* USE_SEMAPHORES */