diff options
| -rw-r--r-- | ChangeLog | 16 | ||||
| -rw-r--r-- | implement.h | 12 | ||||
| -rw-r--r-- | semaphore.c | 139 | ||||
| -rw-r--r-- | semaphore.h | 11 | 
4 files changed, 106 insertions, 72 deletions
@@ -1,5 +1,20 @@  2001-06-06  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
 +	* semaphore.h (sem_t): Is now an opaque pointer;
 +	moved actual definition to implement.h.
 +	* implement.h (sem_t_): Move here from semaphore.h;
 +	was the definition of sem_t.
 +	* semaphore.c: Wherever necessary, changed use of sem
 +	from that of a pointer to a pointer-pointer; added
 +	extra checks for a valid sem_t; NULL sem_t when
 +	it is destroyed; added extra checks when creating
 +	and destroying sem_t elements in the NEED_SEM
 +	code branches; changed from using a pthread_mutex_t
 +	((*sem)->mutex) to CRITICAL_SECTION ((*sem)->sem_lock_cs)
 +	in NEED_SEM branches for access serialisation.
 +
 +2001-06-06  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
 +
  	* mutex.c (pthread_mutexattr_init): Remove 
  	ptw32_mutex_default_kind.
 @@ -3086,4 +3101,3 @@ Sat Jul 11 14:48:54 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>  	* create.c (pthread_create): A dummy stub right now.
  	* pthread.h (pthread_create): Add function prototype.
 -
 diff --git a/implement.h b/implement.h index 1b57b60..9518f9e 100644 --- a/implement.h +++ b/implement.h @@ -114,11 +114,21 @@ struct pthread_attr_t_ {  /*   * ====================   * ==================== - * Mutexes and Condition Variables + * Semaphores, Mutexes and Condition Variables   * ====================   * ====================   */ +#ifdef NEED_SEM +typedef struct { +  unsigned int	value; +  CRITICAL_SECTION sem_lock_cs; +  HANDLE	event; +} sem_t_; +#else /* NEED_SEM */ +typedef HANDLE sem_t_; +#endif /* NEED_SEM */ +  #define PTW32_OBJECT_AUTO_INIT ((void *) -1)  #define PTW32_OBJECT_INVALID   NULL diff --git a/semaphore.c b/semaphore.c index 15441e8..0f06c4b 100644 --- a/semaphore.c +++ b/semaphore.c @@ -9,18 +9,6 @@   *   *              POSIX 1003.1b-1993      (POSIX.1b)   * - * Contents: - *              Public Methods                    Author - *              --------------                    ------ - *              sem_init                          John E. Bossom  Mar 1998 - *              sem_destroy                       John E. Bossom  Mar 1998 - *              sem_trywait                       John E. Bossom  Mar 1998 - *              sem_wait                          John E. Bossom  Mar 1998 - *              sem_post                          John E. Bossom  Mar 1998 - * - *              Private Methods - *              --------------- - *   * -------------------------------------------------------------   *   * Pthreads-win32 - POSIX Threads Library for Win32 @@ -104,29 +92,46 @@ sem_init (sem_t * sem, int pshared, unsigned int value)  #ifdef NEED_SEM -      sem->value = value; -      pthread_mutex_init(&sem->mutex, NULL); -      sem->event = CreateEvent (NULL, -				FALSE,	/* manual reset */ -				FALSE,	/* initial state */ -				NULL); -      if (value != 0) +      sem_t s = (sem_t) calloc (1, sizeof (*sem_t)); + +      if (s == NULL)          { -	  SetEvent(sem->event); +          result = ENOMEM;          } +      else +        { +          s->value = value; +          s->event = CreateEvent (NULL, +                                  FALSE,	/* manual reset */ +                                  FALSE,	/* initial state */ +                                  NULL); +          if (s->Event == 0) +            { +              result = ENOSPC; +            } +          else +            { +              if (value != 0) +                { +                  SetEvent(s->event); +                } +              InitializeCriticalSection(&s->sem_lock_cs); + +              *sem = s; +            }  #else /* NEED_SEM */        /*         * NOTE: Taking advantage of the fact that -       *               sem_t is a simple structure with one entry; -       *               We don't have to allocate it... +       * sem_t is a simple structure with one entry; +       * We don't have to allocate it...         */        *sem = CreateSemaphore ( -			       0, -			       value, -			       0x7FFFFFF, -			       NULL); +                              0, +                              value, +                              0x7FFFFFF, +                              NULL);        if (*sem == 0)  	{ @@ -175,34 +180,42 @@ sem_destroy (sem_t * sem)        */  {    int result = 0; +  sem_t s = *sem; -  if (sem == NULL) +  if (sem == NULL || *sem == NULL)      {        result = EINVAL;      } +  else +    { +      *sem = NULL;  #ifdef NEED_SEM -  else -    { -      pthread_mutex_destroy(&sem->mutex); -      if (!CloseHandle(sem->event)) +      if (! CloseHandle(s->event))          {            result = EINVAL;          } -    } +      else +        { +          DeleteCriticalSection(&s->sem_lock_cs); +          free(s); +        }  #else /* NEED_SEM */ -  else if (! CloseHandle (*sem)) -    { -      result = EINVAL; -    } +      if (! CloseHandle (s)) +        { +          result = EINVAL; +        }  #endif /* NEED_SEM */ +    } +    if (result != 0)      { +      *sem = s;        errno = result;        return -1;      } @@ -242,28 +255,27 @@ sem_trywait (sem_t * sem)        * ------------------------------------------------------        */  { -  int result = 0; - -  if (sem == NULL) -    { -      result = EINVAL; -    } -  #ifdef NEED_SEM -  /* not yet implemented! */ -  result = EINVAL; +  /* +   * not yet implemented! +   */ +  int result = EINVAL;    return -1;  #else /* NEED_SEM */ +  int result = 0; + +  if (sem == NULL || *sem == NULL) +    { +      result = EINVAL; +    }    else if (WaitForSingleObject (*sem, 0) == WAIT_TIMEOUT)      {        result = EAGAIN;      } -#endif /* NEED_SEM */ -    if (result != 0)      {        errno = result; @@ -272,6 +284,8 @@ sem_trywait (sem_t * sem)    return 0; +#endif /* NEED_SEM */ +  }				/* sem_trywait */ @@ -280,14 +294,16 @@ sem_trywait (sem_t * sem)  void   ptw32_decrease_semaphore(sem_t * sem)  { -  pthread_mutex_lock(&sem->mutex); +  register sem_t s = *sem; + +  EnterCriticalSection(&s->sem_lock_cs); -  if (sem->value != 0) +  if (s->value != 0)      { -      sem->value--; -      if (sem->value != 0) +      s->value--; +      if (s->value != 0)          { -          SetEvent(sem->event); +          SetEvent(s->event);          }      }    else @@ -295,20 +311,21 @@ ptw32_decrease_semaphore(sem_t * sem)        /* this case should not happen! */      } -  pthread_mutex_unlock(&sem->mutex); +  LeaveCriticalSection(&s->sem_lock_cs);  }  BOOL   ptw32_increase_semaphore(sem_t * sem, unsigned int n)  {    BOOL result; +  register sem_t s = *sem; -  pthread_mutex_lock(&sem->mutex); +  EnterCriticalSection(&s->sem_lock_cs); -  if (sem->value + n > sem->value) +  if (s->value + n > s->value)      { -       sem->value += n; -       SetEvent(sem->event); +       s->value += n; +       SetEvent(s->event);         result = TRUE;      }    else @@ -316,7 +333,7 @@ ptw32_increase_semaphore(sem_t * sem, unsigned int n)         result = FALSE;      } -  pthread_mutex_unlock(&sem->mutex); +  LeaveCriticalSection(&s->sem_lock_cs);    return result;  } @@ -355,7 +372,7 @@ sem_wait (sem_t * sem)  {    int result = 0; -  if (sem == NULL) +  if (sem == NULL || *sem == NULL)      {        result = EINVAL;      } @@ -364,7 +381,7 @@ sem_wait (sem_t * sem)  #ifdef NEED_SEM -	result = pthreadCancelableWait (sem->event); +	result = pthreadCancelableWait ((*sem)->event);  #else /* NEED_SEM */ @@ -419,7 +436,7 @@ sem_post (sem_t * sem)  {    int result = 0; -  if (sem == NULL) +  if (sem == NULL || *sem == NULL)      {  	result = EINVAL;      } diff --git a/semaphore.h b/semaphore.h index bc66e35..3616b11 100644 --- a/semaphore.h +++ b/semaphore.h @@ -64,15 +64,8 @@ extern "C"  typedef unsigned int mode_t;  #endif -#ifdef NEED_SEM -typedef struct { -	unsigned int	value; -	pthread_mutex_t mutex; -	HANDLE	event; -} sem_t; -#else /* NEED_SEM */ -typedef HANDLE sem_t; -#endif /* NEED_SEM */ + +typedef sem_t_ * sem_t;  int sem_init (sem_t * sem,  	      int pshared,  | 
