diff options
| -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 | 
