Home | History | Annotate | Download | only in pthreads-win32
      1 /*
      2  * -------------------------------------------------------------
      3  *
      4  * Module: sem_destroy.c
      5  *
      6  * Purpose:
      7  *	Semaphores aren't actually part of the PThreads standard.
      8  *	They are defined by the POSIX Standard:
      9  *
     10  *		POSIX 1003.1b-1993	(POSIX.1b)
     11  *
     12  * -------------------------------------------------------------
     13  *
     14  * --------------------------------------------------------------------------
     15  *
     16  *      Pthreads-win32 - POSIX Threads Library for Win32
     17  *      Copyright(C) 1998 John E. Bossom
     18  *      Copyright(C) 1999,2005 Pthreads-win32 contributors
     19  *
     20  *      Contact Email: rpj (at) callisto.canberra.edu.au
     21  *
     22  *      The current list of contributors is contained
     23  *      in the file CONTRIBUTORS included with the source
     24  *      code distribution. The list can also be seen at the
     25  *      following World Wide Web location:
     26  *      http://sources.redhat.com/pthreads-win32/contributors.html
     27  *
     28  *      This library is free software; you can redistribute it and/or
     29  *      modify it under the terms of the GNU Lesser General Public
     30  *      License as published by the Free Software Foundation; either
     31  *      version 2 of the License, or (at your option) any later version.
     32  *
     33  *      This library is distributed in the hope that it will be useful,
     34  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
     35  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     36  *      Lesser General Public License for more details.
     37  *
     38  *      You should have received a copy of the GNU Lesser General Public
     39  *      License along with this library in the file COPYING.LIB;
     40  *      if not, write to the Free Software Foundation, Inc.,
     41  *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
     42  */
     43 
     44 #include "pthread.h"
     45 #include "semaphore.h"
     46 #include "implement.h"
     47 
     48 
     49 int
     50 sem_destroy (sem_t * sem)
     51      /*
     52       * ------------------------------------------------------
     53       * DOCPUBLIC
     54       *      This function destroys an unnamed semaphore.
     55       *
     56       * PARAMETERS
     57       *      sem
     58       *              pointer to an instance of sem_t
     59       *
     60       * DESCRIPTION
     61       *      This function destroys an unnamed semaphore.
     62       *
     63       * RESULTS
     64       *              0               successfully destroyed semaphore,
     65       *              -1              failed, error in errno
     66       * ERRNO
     67       *              EINVAL          'sem' is not a valid semaphore,
     68       *              ENOSYS          semaphores are not supported,
     69       *              EBUSY           threads (or processes) are currently
     70       *                                      blocked on 'sem'
     71       *
     72       * ------------------------------------------------------
     73       */
     74 {
     75   int result = 0;
     76   sem_t s = NULL;
     77 
     78   if (sem == NULL || *sem == NULL)
     79     {
     80       result = EINVAL;
     81     }
     82   else
     83     {
     84       s = *sem;
     85 
     86       if ((result = pthread_mutex_lock (&s->lock)) == 0)
     87         {
     88           if (s->value < 0)
     89             {
     90               (void) pthread_mutex_unlock (&s->lock);
     91               result = EBUSY;
     92             }
     93           else
     94             {
     95               /* There are no threads currently blocked on this semaphore. */
     96 
     97               if (!CloseHandle (s->sem))
     98 	        {
     99                   (void) pthread_mutex_unlock (&s->lock);
    100 	          result = EINVAL;
    101 	        }
    102 	      else
    103 	        {
    104                   /*
    105                    * Invalidate the semaphore handle when we have the lock.
    106                    * Other sema operations should test this after acquiring the lock
    107                    * to check that the sema is still valid, i.e. before performing any
    108                    * operations. This may only be necessary before the sema op routine
    109                    * returns so that the routine can return EINVAL - e.g. if setting
    110                    * s->value to SEM_VALUE_MAX below does force a fall-through.
    111                    */
    112                   *sem = NULL;
    113 
    114                   /* Prevent anyone else actually waiting on or posting this sema.
    115                    */
    116                   s->value = SEM_VALUE_MAX;
    117 
    118                   (void) pthread_mutex_unlock (&s->lock);
    119 
    120                   do
    121                     {
    122                       /* Give other threads a chance to run and exit any sema op
    123                        * routines. Due to the SEM_VALUE_MAX value, if sem_post or
    124                        * sem_wait were blocked by us they should fall through.
    125                        */
    126                       Sleep(0);
    127                     }
    128                   while (pthread_mutex_destroy (&s->lock) == EBUSY);
    129                 }
    130             }
    131         }
    132     }
    133 
    134   if (result != 0)
    135     {
    136       errno = result;
    137       return -1;
    138     }
    139 
    140   free (s);
    141 
    142   return 0;
    143 
    144 }				/* sem_destroy */
    145