diff options
author | rpj <rpj> | 2002-12-17 08:01:50 +0000 |
---|---|---|
committer | rpj <rpj> | 2002-12-17 08:01:50 +0000 |
commit | 8da677c58a7c95a4bf83808d9395ea7e8d49f18e (patch) | |
tree | 217e17e4738d87d0d2adb71361b76cf06590296c | |
parent | 52c1047709bbc61fa793bcc6a28daabea88d2a20 (diff) |
* pthread_mutex_lock.c (ptw32_semwait): New static routine to provide
a non-cancelable sem_wait() function. This is consistent with the
way that pthread_mutex_timedlock.c does it.
(pthread_mutex_lock): Use ptw32_semwait() instead of sem_wait().
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | pthread_mutex_lock.c | 132 | ||||
-rw-r--r-- | pthread_mutex_timedlock.c | 2 |
3 files changed, 114 insertions, 27 deletions
@@ -1,3 +1,10 @@ +2002-12-17 Ross Johnson <rpj@digit.ise.canberra.edu.au> + + * pthread_mutex_lock.c (ptw32_semwait): New static routine to provide + a non-cancelable sem_wait() function. This is consistent with the + way that pthread_mutex_timedlock.c does it. + (pthread_mutex_lock): Use ptw32_semwait() instead of sem_wait(). + 2002-12-11 Thomas Pfaff <tpfaff@gmx.net> * pthread_mutex_trylock.c: Should return EBUSY rather than EDEADLK. diff --git a/pthread_mutex_lock.c b/pthread_mutex_lock.c index 5ba97dc..cdcb701 100644 --- a/pthread_mutex_lock.c +++ b/pthread_mutex_lock.c @@ -38,6 +38,80 @@ #include "implement.h" +static INLINE int +ptw32_semwait (sem_t * sem) + /* + * ------------------------------------------------------ + * DESCRIPTION + * This function waits on a POSIX semaphore. If the + * semaphore value is greater than zero, it decreases + * its value by one. If the semaphore value is zero, then + * the calling thread (or process) is blocked until it can + * successfully decrease the value. + * + * Unlike sem_wait(), this routine is not a cancelation point. + * + * RESULTS + * 0 successfully decreased semaphore, + * -1 failed, error in errno. + * ERRNO + * EINVAL 'sem' is not a valid semaphore, + * ENOSYS semaphores are not supported, + * EINTR the function was interrupted by a signal, + * EDEADLK a deadlock condition was detected. + * + * ------------------------------------------------------ + */ +{ + int result = 0; + + DWORD status; + + if (sem == NULL) + { + result = EINVAL; + } + else + { + +#ifdef NEED_SEM + + status = WaitForSingleObject( (*sem)->event, INFINITE ); + +#else /* NEED_SEM */ + + status = WaitForSingleObject( (*sem)->sem, INFINITE ); + +#endif + + if (status == WAIT_OBJECT_0) + { + +#ifdef NEED_SEM + + ptw32_decrease_semaphore(sem); + +#endif /* NEED_SEM */ + + return 0; + } + else + { + result = EINVAL; + } + } + + if (result != 0) + { + errno = result; + return -1; + } + + return 0; + +} /* ptw32_semwait */ + + int pthread_mutex_lock(pthread_mutex_t *mutex) { @@ -59,9 +133,9 @@ pthread_mutex_lock(pthread_mutex_t *mutex) if (*mutex == PTHREAD_MUTEX_INITIALIZER) { if ((result = ptw32_mutex_check_need_init(mutex)) != 0) - { - return(result); - } + { + return(result); + } } mx = *mutex; @@ -70,35 +144,39 @@ pthread_mutex_lock(pthread_mutex_t *mutex) { mx->recursive_count = 1; mx->ownerThread = (mx->kind != PTHREAD_MUTEX_FAST_NP - ? pthread_self() - : (pthread_t) PTW32_MUTEX_OWNER_ANONYMOUS); + ? pthread_self() + : (pthread_t) PTW32_MUTEX_OWNER_ANONYMOUS); } else { if( mx->kind != PTHREAD_MUTEX_FAST_NP && - pthread_equal( mx->ownerThread, pthread_self() ) ) - { - (void) InterlockedDecrement( &mx->lock_idx ); - - if( mx->kind == PTHREAD_MUTEX_RECURSIVE_NP ) - { - mx->recursive_count++; - } - else - { - result = EDEADLK; - } - } + pthread_equal( mx->ownerThread, pthread_self() ) ) + { + (void) InterlockedDecrement( &mx->lock_idx ); + + if( mx->kind == PTHREAD_MUTEX_RECURSIVE_NP ) + { + mx->recursive_count++; + } + else + { + result = EDEADLK; + } + } else - { - if ((result = sem_wait( &mx->wait_sema )) == 0) - { - mx->recursive_count = 1; - mx->ownerThread = (mx->kind != PTHREAD_MUTEX_FAST_NP - ? pthread_self() - : (pthread_t) PTW32_MUTEX_OWNER_ANONYMOUS); - } - } + { + if (ptw32_semwait( &mx->wait_sema ) == 0) + { + mx->recursive_count = 1; + mx->ownerThread = (mx->kind != PTHREAD_MUTEX_FAST_NP + ? pthread_self() + : (pthread_t) PTW32_MUTEX_OWNER_ANONYMOUS); + } + else + { + result = errno; + } + } } return(result); diff --git a/pthread_mutex_timedlock.c b/pthread_mutex_timedlock.c index da03c03..c553a53 100644 --- a/pthread_mutex_timedlock.c +++ b/pthread_mutex_timedlock.c @@ -60,6 +60,8 @@ ptw32_timed_semwait (sem_t * sem, const struct timespec * abstime) * If 'abstime' is a NULL pointer then this function will * block until it can successfully decrease the value or * until interrupted by a signal. + * + * Unlike sem_timedwait(), this routine is not a cancelation point. * * RESULTS * 2 abstime has passed already |