diff options
| author | rpj <rpj> | 2002-07-30 12:52:52 +0000 | 
|---|---|---|
| committer | rpj <rpj> | 2002-07-30 12:52:52 +0000 | 
| commit | ccd0f86e370fa71acd47c17cb9579877403c81d1 (patch) | |
| tree | 16ddf8cef155093de95b62cd9d3cd6f522970d45 | |
| parent | 5c1bda8e72572064653230f4fcbdf0d5df627085 (diff) | |
* sem_timedwait.c (sem_timedwait): Tighten checks for
  unreasonable abstime values - that would result in
  unexpected timeout values.
* w32_CancelableWait.c (ptw32_cancelable_wait):
  Tighten up return value checking and add comments.
| -rw-r--r-- | ChangeLog | 11 | ||||
| -rw-r--r-- | sem_timedwait.c | 130 | ||||
| -rw-r--r-- | w32_CancelableWait.c | 125 | 
3 files changed, 150 insertions, 116 deletions
| @@ -1,3 +1,12 @@ +2002-07-30  Ross Johnson  <rpj@ise.canberra.edu.au>
 +
 +	* sem_timedwait.c (sem_timedwait): Tighten checks for
 +	unreasonable abstime values - that would result in
 +	unexpected timeout values.
 +
 +	* w32_CancelableWait.c (ptw32_cancelable_wait):
 +	Tighten up return value checking and add comments.
 +
  2002-06-04  Rob Fanner  <rfanner@stonethree.com>
  	* sem_getvalue.c (sem_getvalue): The Johnson M. Hart
 @@ -7,7 +16,7 @@  	value. There is a small probability that this may
  	block other threads, but only momentarily.
 -2002-06-03  Ross Johnson  <rpj@digit.ise.canberra.edu.au>
 +2002-06-03  Ross Johnson  <rpj@ise.canberra.edu.au>
  	* sem_init.c (sem_init): Initialise Win32 semaphores
  	to _POSIX_SEM_VALUE_MAX (which this implementation
 diff --git a/sem_timedwait.c b/sem_timedwait.c index 11178f2..a6fc753 100644 --- a/sem_timedwait.c +++ b/sem_timedwait.c @@ -116,63 +116,95 @@ sem_timedwait (sem_t * sem, const struct timespec * abstime)    else      {        if (abstime == NULL) -	{ -	  milliseconds = INFINITE; -	} +				{ +					milliseconds = INFINITE; +				}        else -	{ -	  /*  -	   * Calculate timeout as milliseconds from current system time.  -	   */ - -	  /* get current system time */ - +				{ +					milliseconds = 0; + +					/*  +					 * Calculate timeout as milliseconds from current system time.  +					 */ +					 +					/* get current system time */ +					  #ifdef NEED_FTIME -	  { -	    FILETIME ft; -	    SYSTEMTIME st; - -	    GetSystemTime(&st); -	    SystemTimeToFileTime(&st, &ft); -	    /* -	     * GetSystemTimeAsFileTime(&ft); would be faster, -	     * but it does not exist on WinCE -	     */ - -	    ptw32_filetime_to_timespec(&ft, &currSysTime); -	  } - -	  /* -	   * subtract current system time from abstime -	   */ -	  milliseconds = (abstime->tv_sec - currSysTime.tv_sec) * MILLISEC_PER_SEC; -	  milliseconds += ((abstime->tv_nsec - currSysTime.tv_nsec) -                           + (NANOSEC_PER_MILLISEC/2)) / NANOSEC_PER_MILLISEC; - +					{ +						FILETIME ft; +						SYSTEMTIME st; + +						GetSystemTime(&st); +						SystemTimeToFileTime(&st, &ft); +						/* +						 * GetSystemTimeAsFileTime(&ft); would be faster, +						 * but it does not exist on WinCE +						 */ +						 +						ptw32_filetime_to_timespec(&ft, &currSysTime); +					} +					 +					/* +					 * subtract current system time from abstime in a way that checks +					 * that abstime is never in the past, or is never equivalent to the +					 * defined INFINITE value (0xFFFFFFFF). +					 */ +					if (abstime->tv_sec >= currSysTime.tv_sec) +						{ +							DWORD tmpMilliseconds; +							DWORD tmpCurrMilliseconds; +							 +							tmpMilliseconds = (abstime->tv_sec - currSysTime.tv_sec) * MILLISEC_PER_SEC; +							tmpMilliseconds += ((abstime->tv_nsec + (NANOSEC_PER_MILLISEC/2)) +								/ NANOSEC_PER_MILLISEC); +							tmpCurrMilliseconds = ((currSysTime.tv_nsec + (NANOSEC_PER_MILLISEC/2)) +								/ NANOSEC_PER_MILLISEC); +							if (tmpMilliseconds > tmpCurrMilliseconds) +								{ +									milliseconds = tmpMilliseconds - tmpCurrMilliseconds; +									if (milliseconds == INFINITE) +										{ +											milliseconds--; +										} +								} +						} +					  #else /* NEED_FTIME */ -	  _ftime(&currSysTime); - -	  /* -	   * subtract current system time from abstime -	   */ -	  milliseconds = (abstime->tv_sec - currSysTime.time) * MILLISEC_PER_SEC; -	  milliseconds += ((abstime->tv_nsec + (NANOSEC_PER_MILLISEC/2)) / NANOSEC_PER_MILLISEC) -            - currSysTime.millitm; - +					_ftime(&currSysTime); +					 +					/* +					 * subtract current system time from abstime in a way that checks +					 * that abstime is never in the past, or is never equivalent to the +					 * defined INFINITE value (0xFFFFFFFF). +					 */ +					if (abstime->tv_sec >= currSysTime.time) +						{ +							DWORD tmpMilliseconds; +							 +							tmpMilliseconds = (abstime->tv_sec - currSysTime.time) * MILLISEC_PER_SEC; +							tmpMilliseconds += ((abstime->tv_nsec + (NANOSEC_PER_MILLISEC/2)) +								/ NANOSEC_PER_MILLISEC); +							if (tmpMilliseconds > currSysTime.millitm) +								{ +									milliseconds = tmpMilliseconds - currSysTime.millitm; +									if (milliseconds == INFINITE) +										{ +											milliseconds--; +										} +								} +						} +					  #endif /* NEED_FTIME */ - - -	  if (((int) milliseconds) < 0) -	    milliseconds = 0; -	} - +					 +				} +			  #ifdef NEED_SEM - +			        result = (pthreadCancelableTimedWait ((*sem)->event, milliseconds)); - +			  #else /* NEED_SEM */ - +			        result = (pthreadCancelableTimedWait ((*sem)->sem, milliseconds));  #endif diff --git a/w32_CancelableWait.c b/w32_CancelableWait.c index ba1c92a..2f84743 100644 --- a/w32_CancelableWait.c +++ b/w32_CancelableWait.c @@ -68,13 +68,13 @@ ptw32_cancelable_wait (HANDLE waitHandle, DWORD timeout)         * Get cancelEvent handle         */        if (self->cancelState == PTHREAD_CANCEL_ENABLE) -	{ +				{ -	  if ((handles[1] = self->cancelEvent) != NULL) -	    { -	      nHandles++; -	    } -	} +					if ((handles[1] = self->cancelEvent) != NULL) +						{ +							nHandles++; +						} +				}      }    else      { @@ -88,68 +88,61 @@ ptw32_cancelable_wait (HANDLE waitHandle, DWORD timeout)  				    timeout); -  if (status == WAIT_FAILED) -    { -      result = EINVAL; -    } -  else if (status == WAIT_TIMEOUT) -    { -      result = ETIMEDOUT; -    } -  else if (status == WAIT_ABANDONED_0) -    { -      result = EINVAL; -    } -  else -    { -      /* -       * Either got the handle or the cancel event -       * was signaled -       */ -      switch (status - WAIT_OBJECT_0) -	{ - -	case 0: -	  /* -	   * Got the handle -	   */ -	  result = 0; -	  break; - -	case 1: -	  /* -	   * Got cancel request -	   */ -	  ResetEvent (handles[1]); - -	  if (self != NULL && !self->implicit) -	    { -	      /* -	       * Thread started with pthread_create. -	       * Make sure we haven't been async-canceled in the meantime. -	       */ -	      (void) pthread_mutex_lock(&self->cancelLock); -	      if (self->state < PThreadStateCanceling) +	switch (status - WAIT_OBJECT_0)  		{ -		  self->state = PThreadStateCanceling; -		  self->cancelState = PTHREAD_CANCEL_DISABLE; -		  (void) pthread_mutex_unlock(&self->cancelLock); -		  ptw32_throw(PTW32_EPS_CANCEL); - -		  /* Never reached */ +			case 0: +				/* +				 * Got the handle. +				 * In the event that both handles are signalled, the smallest index +				 * value (us) is returned. As it has been arranged, this ensures that +				 * we don't drop a signal that we should act on (i.e. semaphore, +				 * mutex, or condition variable etc). +				 */ +				result = 0; +				break; + +			case 1: +				/* +				 * Got cancel request. +				 * In the event that both handles are signalled, the cancel will +				 * be ignored (see case 0 comment). +				 */ +				ResetEvent (handles[1]); + +				if (self != NULL && !self->implicit) +					{ +						/* +						 * Thread started with pthread_create. +						 * Make sure we haven't been async-canceled in the meantime. +						 */ +						(void) pthread_mutex_lock(&self->cancelLock); +						if (self->state < PThreadStateCanceling) +							{ +								self->state = PThreadStateCanceling; +								self->cancelState = PTHREAD_CANCEL_DISABLE; +								(void) pthread_mutex_unlock(&self->cancelLock); +								ptw32_throw(PTW32_EPS_CANCEL); +										 +								/* Never reached */ +							} +						(void) pthread_mutex_unlock(&self->cancelLock); +					} +						 +				/* Should never get to here. */ +				result = EINVAL; +				break; + +			default: +				if (status == WAIT_TIMEOUT) +					{ +						result = ETIMEDOUT; +					} +				else +					{ +						result = EINVAL; +					} +				break;  		} -	      (void) pthread_mutex_unlock(&self->cancelLock); -	    } - -	  /* Should never get to here. */ -	  result = EINVAL; -	  break; - -	default: -	  result = EINVAL; -	  break; -	} -    }    return (result); | 
