Send a crash report when a hung process is detected.
[chromium-blink-merge.git] / native_client_sdk / src / libraries / third_party / pthreads-win32 / pthread_cond_destroy.c
blob40d4a0896c296805b24e666504c688fb47a54d97
1 /*
2 * pthread_cond_destroy.c
4 * Description:
5 * This translation unit implements condition variables and their primitives.
8 * --------------------------------------------------------------------------
10 * Pthreads-win32 - POSIX Threads Library for Win32
11 * Copyright(C) 1998 John E. Bossom
12 * Copyright(C) 1999,2005 Pthreads-win32 contributors
14 * Contact Email: rpj@callisto.canberra.edu.au
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
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.
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.
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
38 #include "pthread.h"
39 #include "implement.h"
41 int
42 pthread_cond_destroy (pthread_cond_t * cond)
44 * ------------------------------------------------------
45 * DOCPUBLIC
46 * This function destroys a condition variable
49 * PARAMETERS
50 * cond
51 * pointer to an instance of pthread_cond_t
54 * DESCRIPTION
55 * This function destroys a condition variable.
57 * NOTES:
58 * 1) A condition variable can be destroyed
59 * immediately after all the threads that
60 * are blocked on it are awakened. e.g.
62 * struct list {
63 * pthread_mutex_t lm;
64 * ...
65 * }
67 * struct elt {
68 * key k;
69 * int busy;
70 * pthread_cond_t notbusy;
71 * ...
72 * }
75 * struct elt *
76 * list_find(struct list *lp, key k)
77 * {
78 * struct elt *ep;
80 * pthread_mutex_lock(&lp->lm);
81 * while ((ep = find_elt(l,k) != NULL) && ep->busy)
82 * pthread_cond_wait(&ep->notbusy, &lp->lm);
83 * if (ep != NULL)
84 * ep->busy = 1;
85 * pthread_mutex_unlock(&lp->lm);
86 * return(ep);
87 * }
89 * delete_elt(struct list *lp, struct elt *ep)
90 * {
91 * pthread_mutex_lock(&lp->lm);
92 * assert(ep->busy);
93 * ... remove ep from list ...
94 * ep->busy = 0;
95 * (A) pthread_cond_broadcast(&ep->notbusy);
96 * pthread_mutex_unlock(&lp->lm);
97 * (B) pthread_cond_destroy(&rp->notbusy);
98 * free(ep);
99 * }
101 * In this example, the condition variable
102 * and its list element may be freed (line B)
103 * immediately after all threads waiting for
104 * it are awakened (line A), since the mutex
105 * and the code ensure that no other thread
106 * can touch the element to be deleted.
108 * RESULTS
109 * 0 successfully released condition variable,
110 * EINVAL 'cond' is invalid,
111 * EBUSY 'cond' is in use,
113 * ------------------------------------------------------
116 pthread_cond_t cv;
117 int result = 0, result1 = 0, result2 = 0;
120 * Assuming any race condition here is harmless.
122 if (cond == NULL || *cond == NULL)
124 return EINVAL;
127 if (*cond != PTHREAD_COND_INITIALIZER)
129 ptw32_mcs_local_node_t node;
130 ptw32_mcs_lock_acquire(&ptw32_cond_list_lock, &node);
132 cv = *cond;
135 * Close the gate; this will synchronize this thread with
136 * all already signaled waiters to let them retract their
137 * waiter status - SEE NOTE 1 ABOVE!!!
139 if (ptw32_semwait (&(cv->semBlockLock)) != 0) /* Non-cancelable */
141 result = errno;
143 else
146 * !TRY! lock mtxUnblockLock; try will detect busy condition
147 * and will not cause a deadlock with respect to concurrent
148 * signal/broadcast.
150 if ((result = pthread_mutex_trylock (&(cv->mtxUnblockLock))) != 0)
152 (void) sem_post (&(cv->semBlockLock));
156 if (result != 0)
158 ptw32_mcs_lock_release(&node);
159 return result;
163 * Check whether cv is still busy (still has waiters)
165 if (cv->nWaitersBlocked > cv->nWaitersGone)
167 if (sem_post (&(cv->semBlockLock)) != 0)
169 result = errno;
171 result1 = pthread_mutex_unlock (&(cv->mtxUnblockLock));
172 result2 = EBUSY;
174 else
177 * Now it is safe to destroy
179 *cond = NULL;
181 if (sem_destroy (&(cv->semBlockLock)) != 0)
183 result = errno;
185 if (sem_destroy (&(cv->semBlockQueue)) != 0)
187 result1 = errno;
189 if ((result2 = pthread_mutex_unlock (&(cv->mtxUnblockLock))) == 0)
191 result2 = pthread_mutex_destroy (&(cv->mtxUnblockLock));
194 /* Unlink the CV from the list */
196 if (ptw32_cond_list_head == cv)
198 ptw32_cond_list_head = cv->next;
200 else
202 cv->prev->next = cv->next;
205 if (ptw32_cond_list_tail == cv)
207 ptw32_cond_list_tail = cv->prev;
209 else
211 cv->next->prev = cv->prev;
214 (void) free (cv);
217 ptw32_mcs_lock_release(&node);
219 else
221 ptw32_mcs_local_node_t node;
223 * See notes in ptw32_cond_check_need_init() above also.
225 ptw32_mcs_lock_acquire(&ptw32_cond_test_init_lock, &node);
228 * Check again.
230 if (*cond == PTHREAD_COND_INITIALIZER)
233 * This is all we need to do to destroy a statically
234 * initialised cond that has not yet been used (initialised).
235 * If we get to here, another thread waiting to initialise
236 * this cond will get an EINVAL. That's OK.
238 *cond = NULL;
240 else
243 * The cv has been initialised while we were waiting
244 * so assume it's in use.
246 result = EBUSY;
249 ptw32_mcs_lock_release(&node);
252 return ((result != 0) ? result : ((result1 != 0) ? result1 : result2));