/[pcsx2_0.9.7]/trunk/3rdparty/w32pthreads/pthread_cond_destroy.c
ViewVC logotype

Contents of /trunk/3rdparty/w32pthreads/pthread_cond_destroy.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (show annotations) (download)
Tue Sep 7 03:24:11 2010 UTC (9 years, 10 months ago) by william
File MIME type: text/plain
File size: 7367 byte(s)
committing r3113 initial commit again...
1 /*
2 * pthread_cond_destroy.c
3 *
4 * Description:
5 * This translation unit implements condition variables and their primitives.
6 *
7 *
8 * --------------------------------------------------------------------------
9 *
10 * Pthreads-win32 - POSIX Threads Library for Win32
11 * Copyright(C) 1998 John E. Bossom
12 * Copyright(C) 1999,2005 Pthreads-win32 contributors
13 *
14 * Contact Email: rpj@callisto.canberra.edu.au
15 *
16 * The current list of contributors is contained
17 * in the file CONTRIBUTORS included with the source
18 * code distribution. The list can also be seen at the
19 * following World Wide Web location:
20 * http://sources.redhat.com/pthreads-win32/contributors.html
21 *
22 * This library is free software; you can redistribute it and/or
23 * modify it under the terms of the GNU Lesser General Public
24 * License as published by the Free Software Foundation; either
25 * version 2 of the License, or (at your option) any later version.
26 *
27 * This library is distributed in the hope that it will be useful,
28 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
30 * Lesser General Public License for more details.
31 *
32 * You should have received a copy of the GNU Lesser General Public
33 * License along with this library in the file COPYING.LIB;
34 * if not, write to the Free Software Foundation, Inc.,
35 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
36 */
37
38 #include "ptw32pch.h"
39
40 int
41 pthread_cond_destroy (pthread_cond_t * cond)
42 /*
43 * ------------------------------------------------------
44 * DOCPUBLIC
45 * This function destroys a condition variable
46 *
47 *
48 * PARAMETERS
49 * cond
50 * pointer to an instance of pthread_cond_t
51 *
52 *
53 * DESCRIPTION
54 * This function destroys a condition variable.
55 *
56 * NOTES:
57 * 1) A condition variable can be destroyed
58 * immediately after all the threads that
59 * are blocked on it are awakened. e.g.
60 *
61 * struct list {
62 * pthread_mutex_t lm;
63 * ...
64 * }
65 *
66 * struct elt {
67 * key k;
68 * int busy;
69 * pthread_cond_t notbusy;
70 * ...
71 * }
72 *
73 *
74 * struct elt *
75 * list_find(struct list *lp, key k)
76 * {
77 * struct elt *ep;
78 *
79 * pthread_mutex_lock(&lp->lm);
80 * while ((ep = find_elt(l,k) != NULL) && ep->busy)
81 * pthread_cond_wait(&ep->notbusy, &lp->lm);
82 * if (ep != NULL)
83 * ep->busy = 1;
84 * pthread_mutex_unlock(&lp->lm);
85 * return(ep);
86 * }
87 *
88 * delete_elt(struct list *lp, struct elt *ep)
89 * {
90 * pthread_mutex_lock(&lp->lm);
91 * assert(ep->busy);
92 * ... remove ep from list ...
93 * ep->busy = 0;
94 * (A) pthread_cond_broadcast(&ep->notbusy);
95 * pthread_mutex_unlock(&lp->lm);
96 * (B) pthread_cond_destroy(&rp->notbusy);
97 * free(ep);
98 * }
99 *
100 * In this example, the condition variable
101 * and its list element may be freed (line B)
102 * immediately after all threads waiting for
103 * it are awakened (line A), since the mutex
104 * and the code ensure that no other thread
105 * can touch the element to be deleted.
106 *
107 * RESULTS
108 * 0 successfully released condition variable,
109 * EINVAL 'cond' is invalid,
110 * EBUSY 'cond' is in use,
111 *
112 * ------------------------------------------------------
113 */
114 {
115 pthread_cond_t cv;
116 int result = 0, result1 = 0, result2 = 0;
117
118 /*
119 * Assuming any race condition here is harmless.
120 */
121 if (cond == NULL || *cond == NULL)
122 {
123 return EINVAL;
124 }
125
126 if (*cond != PTHREAD_COND_INITIALIZER)
127 {
128 EnterCriticalSection (&ptw32_cond_list_lock);
129
130 cv = *cond;
131
132 /*
133 * Close the gate; this will synchronize this thread with
134 * all already signaled waiters to let them retract their
135 * waiter status - SEE NOTE 1 ABOVE!!!
136 */
137 if (sem_wait (&(cv->semBlockLock)) != 0)
138 {
139 return errno;
140 }
141
142 /*
143 * !TRY! lock mtxUnblockLock; try will detect busy condition
144 * and will not cause a deadlock with respect to concurrent
145 * signal/broadcast.
146 */
147 if ((result = pthread_mutex_trylock (&(cv->mtxUnblockLock))) != 0)
148 {
149 (void) sem_post (&(cv->semBlockLock));
150 return result;
151 }
152
153 /*
154 * Check whether cv is still busy (still has waiters)
155 */
156 if (cv->nWaitersBlocked > cv->nWaitersGone)
157 {
158 if (sem_post (&(cv->semBlockLock)) != 0)
159 {
160 result = errno;
161 }
162 result1 = pthread_mutex_unlock (&(cv->mtxUnblockLock));
163 result2 = EBUSY;
164 }
165 else
166 {
167 /*
168 * Now it is safe to destroy
169 */
170 *cond = NULL;
171
172 if (sem_destroy (&(cv->semBlockLock)) != 0)
173 {
174 result = errno;
175 }
176 if (sem_destroy (&(cv->semBlockQueue)) != 0)
177 {
178 result1 = errno;
179 }
180 if ((result2 = pthread_mutex_unlock (&(cv->mtxUnblockLock))) == 0)
181 {
182 result2 = pthread_mutex_destroy (&(cv->mtxUnblockLock));
183 }
184
185 /* Unlink the CV from the list */
186
187 if (ptw32_cond_list_head == cv)
188 {
189 ptw32_cond_list_head = cv->next;
190 }
191 else
192 {
193 cv->prev->next = cv->next;
194 }
195
196 if (ptw32_cond_list_tail == cv)
197 {
198 ptw32_cond_list_tail = cv->prev;
199 }
200 else
201 {
202 cv->next->prev = cv->prev;
203 }
204
205 (void) free (cv);
206 }
207
208 LeaveCriticalSection (&ptw32_cond_list_lock);
209 }
210 else
211 {
212 /*
213 * See notes in ptw32_cond_check_need_init() above also.
214 */
215 EnterCriticalSection (&ptw32_cond_test_init_lock);
216
217 /*
218 * Check again.
219 */
220 if (*cond == PTHREAD_COND_INITIALIZER)
221 {
222 /*
223 * This is all we need to do to destroy a statically
224 * initialised cond that has not yet been used (initialised).
225 * If we get to here, another thread waiting to initialise
226 * this cond will get an EINVAL. That's OK.
227 */
228 *cond = NULL;
229 }
230 else
231 {
232 /*
233 * The cv has been initialised while we were waiting
234 * so assume it's in use.
235 */
236 result = EBUSY;
237 }
238
239 LeaveCriticalSection (&ptw32_cond_test_init_lock);
240 }
241
242 return ((result != 0) ? result : ((result1 != 0) ? result1 : result2));
243 }

  ViewVC Help
Powered by ViewVC 1.1.22