- add sources.
[platform/framework/web/crosswalk.git] / src / native_client_sdk / src / libraries / third_party / pthreads-win32 / sem_post_multiple.c
1 /*
2  * -------------------------------------------------------------
3  *
4  * Module: sem_post_multiple.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
49 int
50 sem_post_multiple (sem_t * sem, int count)
51      /*
52       * ------------------------------------------------------
53       * DOCPUBLIC
54       *      This function posts multiple wakeups to a semaphore.
55       *
56       * PARAMETERS
57       *      sem
58       *              pointer to an instance of sem_t
59       *
60       *      count
61       *              counter, must be greater than zero.
62       *
63       * DESCRIPTION
64       *      This function posts multiple wakeups to a semaphore. If there
65       *      are waiting threads (or processes), n <= count are awakened;
66       *      the semaphore value is incremented by count - n.
67       *
68       * RESULTS
69       *              0               successfully posted semaphore,
70       *              -1              failed, error in errno
71       * ERRNO
72       *              EINVAL          'sem' is not a valid semaphore
73       *                              or count is less than or equal to zero.
74       *              ERANGE          semaphore count is too big
75       *
76       * ------------------------------------------------------
77       */
78 {
79   int result = 0;
80   long waiters;
81   sem_t s = *sem;
82
83   if (s == NULL || count <= 0)
84     {
85       result = EINVAL;
86     }
87   else if ((result = pthread_mutex_lock (&s->lock)) == 0)
88     {
89       /* See sem_destroy.c
90        */
91       if (*sem == NULL)
92         {
93           (void) pthread_mutex_unlock (&s->lock);
94           result = EINVAL;
95           return -1;
96         }
97
98       if (s->value <= (SEM_VALUE_MAX - count))
99         {
100           waiters = -s->value;
101           s->value += count;
102           if (waiters > 0)
103             {
104 #if defined(NEED_SEM)
105               if (SetEvent(s->sem))
106                 {
107                   waiters--;
108                   s->leftToUnblock += count - 1;
109                   if (s->leftToUnblock > waiters)
110                     {
111                       s->leftToUnblock = waiters;
112                     }
113                 }
114 #else
115               if (ReleaseSemaphore (s->sem,  (waiters<=count)?waiters:count, 0))
116                 {
117                   /* No action */
118                 }
119 #endif
120               else
121                 {
122                   s->value -= count;
123                   result = EINVAL;
124                 }
125             }
126         }
127       else
128         {
129           result = ERANGE;
130         }
131       (void) pthread_mutex_unlock (&s->lock);
132     }
133
134   if (result != 0)
135     {
136       errno = result;
137       return -1;
138     }
139
140   return 0;
141
142 }                               /* sem_post_multiple */