Home | History | Annotate | Download | only in pthreads-win32
      1 /*
      2  * -------------------------------------------------------------
      3  *
      4  * Module: sem_init.c
      5  *
      6  * Purpose:
      7  *	Semaphores aren't actually part of PThreads.
      8  *	They are defined by the POSIX Standard:
      9  *
     10  *		POSIX 1003.1-2001
     11  *
     12  * -------------------------------------------------------------
     13  *
     14  *      Pthreads-win32 - POSIX Threads Library for Win32
     15  *      Copyright(C) 1998 John E. Bossom
     16  *      Copyright(C) 1999,2005 Pthreads-win32 contributors
     17  *
     18  *      Contact Email: rpj (at) callisto.canberra.edu.au
     19  *
     20  *      The current list of contributors is contained
     21  *      in the file CONTRIBUTORS included with the source
     22  *      code distribution. The list can also be seen at the
     23  *      following World Wide Web location:
     24  *      http://sources.redhat.com/pthreads-win32/contributors.html
     25  *
     26  *      This library is free software; you can redistribute it and/or
     27  *      modify it under the terms of the GNU Lesser General Public
     28  *      License as published by the Free Software Foundation; either
     29  *      version 2 of the License, or (at your option) any later version.
     30  *
     31  *      This library is distributed in the hope that it will be useful,
     32  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
     33  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     34  *      Lesser General Public License for more details.
     35  *
     36  *      You should have received a copy of the GNU Lesser General Public
     37  *      License along with this library in the file COPYING.LIB;
     38  *      if not, write to the Free Software Foundation, Inc.,
     39  *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
     40  */
     41 
     42 #include "pthread.h"
     43 #include "semaphore.h"
     44 #include "implement.h"
     45 
     46 int
     47 sem_init (sem_t * sem, int pshared, unsigned int value)
     48      /*
     49       * ------------------------------------------------------
     50       * DOCPUBLIC
     51       *      This function initializes a semaphore. The
     52       *      initial value of the semaphore is 'value'
     53       *
     54       * PARAMETERS
     55       *      sem
     56       *              pointer to an instance of sem_t
     57       *
     58       *      pshared
     59       *              if zero, this semaphore may only be shared between
     60       *              threads in the same process.
     61       *              if nonzero, the semaphore can be shared between
     62       *              processes
     63       *
     64       *      value
     65       *              initial value of the semaphore counter
     66       *
     67       * DESCRIPTION
     68       *      This function initializes a semaphore. The
     69       *      initial value of the semaphore is set to 'value'.
     70       *
     71       * RESULTS
     72       *              0               successfully created semaphore,
     73       *              -1              failed, error in errno
     74       * ERRNO
     75       *              EINVAL          'sem' is not a valid semaphore, or
     76       *                              'value' >= SEM_VALUE_MAX
     77       *              ENOMEM          out of memory,
     78       *              ENOSPC          a required resource has been exhausted,
     79       *              ENOSYS          semaphores are not supported,
     80       *              EPERM           the process lacks appropriate privilege
     81       *
     82       * ------------------------------------------------------
     83       */
     84 {
     85   int result = 0;
     86   sem_t s = NULL;
     87 
     88   if (pshared != 0)
     89     {
     90       /*
     91        * Creating a semaphore that can be shared between
     92        * processes
     93        */
     94       result = EPERM;
     95     }
     96   else if (value > (unsigned int)SEM_VALUE_MAX)
     97     {
     98       result = EINVAL;
     99     }
    100   else
    101     {
    102       s = (sem_t) calloc (1, sizeof (*s));
    103 
    104       if (NULL == s)
    105 	{
    106 	  result = ENOMEM;
    107 	}
    108       else
    109 	{
    110 
    111 	  s->value = value;
    112 	  if (pthread_mutex_init(&s->lock, NULL) == 0)
    113 	    {
    114 
    115 #if defined(NEED_SEM)
    116 
    117 	  s->sem = CreateEvent (NULL,
    118 				PTW32_FALSE,	/* auto (not manual) reset */
    119 				PTW32_FALSE,	/* initial state is unset */
    120 				NULL);
    121 
    122 	  if (0 == s->sem)
    123 	    {
    124 	      free (s);
    125 	      (void) pthread_mutex_destroy(&s->lock);
    126 	      result = ENOSPC;
    127 	    }
    128 	  else
    129 	    {
    130 	      s->leftToUnblock = 0;
    131 	    }
    132 
    133 #else /* NEED_SEM */
    134 
    135 	      if ((s->sem = CreateSemaphore (NULL,	/* Always NULL */
    136 					     (long) 0,	/* Force threads to wait */
    137 					     (long) SEM_VALUE_MAX,	/* Maximum value */
    138 					     NULL)) == 0)	/* Name */
    139 		{
    140 		  (void) pthread_mutex_destroy(&s->lock);
    141 		  result = ENOSPC;
    142 		}
    143 
    144 #endif /* NEED_SEM */
    145 
    146 	    }
    147 	  else
    148 	    {
    149 	      result = ENOSPC;
    150 	    }
    151 
    152 	  if (result != 0)
    153 	    {
    154 	      free(s);
    155 	    }
    156 	}
    157     }
    158 
    159   if (result != 0)
    160     {
    161       errno = result;
    162       return -1;
    163     }
    164 
    165   *sem = s;
    166 
    167   return 0;
    168 
    169 }				/* sem_init */
    170