1/*
2 * -------------------------------------------------------------
3 *
4 * Module: sem_post.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@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
49int
50sem_post (sem_t * sem)
51     /*
52      * ------------------------------------------------------
53      * DOCPUBLIC
54      *      This function posts a wakeup to a semaphore.
55      *
56      * PARAMETERS
57      *      sem
58      *              pointer to an instance of sem_t
59      *
60      * DESCRIPTION
61      *      This function posts a wakeup to a semaphore. If there
62      *      are waiting threads (or processes), one is awakened;
63      *      otherwise, the semaphore value is incremented by one.
64      *
65      * RESULTS
66      *              0               successfully posted semaphore,
67      *              -1              failed, error in errno
68      * ERRNO
69      *              EINVAL          'sem' is not a valid semaphore,
70      *              ENOSYS          semaphores are not supported,
71      *              ERANGE          semaphore count is too big
72      *
73      * ------------------------------------------------------
74      */
75{
76  int result = 0;
77  sem_t s = *sem;
78
79  if (s == NULL)
80    {
81      result = EINVAL;
82    }
83  else if ((result = pthread_mutex_lock (&s->lock)) == 0)
84    {
85      /* See sem_destroy.c
86       */
87      if (*sem == NULL)
88        {
89          (void) pthread_mutex_unlock (&s->lock);
90          result = EINVAL;
91          return -1;
92        }
93
94      if (s->value < SEM_VALUE_MAX)
95	{
96#if defined(NEED_SEM)
97	  if (++s->value <= 0
98	      && !SetEvent(s->sem))
99	    {
100	      s->value--;
101	      result = EINVAL;
102	    }
103#else
104	  if (++s->value <= 0
105	      && !ReleaseSemaphore (s->sem, 1, NULL))
106	    {
107	      s->value--;
108	      result = EINVAL;
109	    }
110#endif /* NEED_SEM */
111	}
112      else
113	{
114	  result = ERANGE;
115	}
116
117      (void) pthread_mutex_unlock (&s->lock);
118    }
119
120  if (result != 0)
121    {
122      errno = result;
123      return -1;
124    }
125
126  return 0;
127
128}				/* sem_post */
129