* DOUBLY IMPORTANT: This implementation requires that pthread_cond_broadcast * is called while the mutex is held that is used in the corresponding * pthread_cond_wait calls! */
| 187 | * pthread_cond_wait calls! |
| 188 | */ |
| 189 | int pthread_cond_broadcast(pthread_cond_t *cond) |
| 190 | { |
| 191 | EnterCriticalSection(&cond->waiters_lock); |
| 192 | |
| 193 | if ((cond->was_broadcast = cond->waiters > 0)) { |
| 194 | /* wake up all waiters */ |
| 195 | ReleaseSemaphore(cond->sema, cond->waiters, NULL); |
| 196 | LeaveCriticalSection(&cond->waiters_lock); |
| 197 | /* |
| 198 | * At this point all waiters continue. Each one takes its |
| 199 | * slice of the semaphor. Now it's our turn to wait: Since |
| 200 | * the external mutex is held, no thread can leave cond_wait, |
| 201 | * yet. For this reason, we can be sure that no thread gets |
| 202 | * a chance to eat *more* than one slice. OTOH, it means |
| 203 | * that the last waiter must send us a wake-up. |
| 204 | */ |
| 205 | WaitForSingleObject(cond->continue_broadcast, INFINITE); |
| 206 | /* |
| 207 | * Since the external mutex is held, no thread can enter |
| 208 | * cond_wait, and, hence, it is safe to reset this flag |
| 209 | * without cond->waiters_lock held. |
| 210 | */ |
| 211 | cond->was_broadcast = 0; |
| 212 | } else { |
| 213 | LeaveCriticalSection(&cond->waiters_lock); |
| 214 | } |
| 215 | return 0; |
| 216 | } |
no outgoing calls
no test coverage detected
searching dependent graphs…