@@ -56,141 +56,3 @@ pthread_t pthread_self(void)
5656 t .tid = GetCurrentThreadId ();
5757 return t ;
5858}
59-
60- int pthread_cond_init (pthread_cond_t * cond , const void * unused )
61- {
62- cond -> waiters = 0 ;
63- cond -> was_broadcast = 0 ;
64- InitializeCriticalSection (& cond -> waiters_lock );
65-
66- cond -> sema = CreateSemaphore (NULL , 0 , LONG_MAX , NULL );
67- if (!cond -> sema )
68- die ("CreateSemaphore() failed" );
69-
70- cond -> continue_broadcast = CreateEvent (NULL , /* security */
71- FALSE, /* auto-reset */
72- FALSE, /* not signaled */
73- NULL ); /* name */
74- if (!cond -> continue_broadcast )
75- die ("CreateEvent() failed" );
76-
77- return 0 ;
78- }
79-
80- int pthread_cond_destroy (pthread_cond_t * cond )
81- {
82- CloseHandle (cond -> sema );
83- CloseHandle (cond -> continue_broadcast );
84- DeleteCriticalSection (& cond -> waiters_lock );
85- return 0 ;
86- }
87-
88- int pthread_cond_wait (pthread_cond_t * cond , CRITICAL_SECTION * mutex )
89- {
90- int last_waiter ;
91-
92- EnterCriticalSection (& cond -> waiters_lock );
93- cond -> waiters ++ ;
94- LeaveCriticalSection (& cond -> waiters_lock );
95-
96- /*
97- * Unlock external mutex and wait for signal.
98- * NOTE: we've held mutex locked long enough to increment
99- * waiters count above, so there's no problem with
100- * leaving mutex unlocked before we wait on semaphore.
101- */
102- LeaveCriticalSection (mutex );
103-
104- /* let's wait - ignore return value */
105- WaitForSingleObject (cond -> sema , INFINITE );
106-
107- /*
108- * Decrease waiters count. If we are the last waiter, then we must
109- * notify the broadcasting thread that it can continue.
110- * But if we continued due to cond_signal, we do not have to do that
111- * because the signaling thread knows that only one waiter continued.
112- */
113- EnterCriticalSection (& cond -> waiters_lock );
114- cond -> waiters -- ;
115- last_waiter = cond -> was_broadcast && cond -> waiters == 0 ;
116- LeaveCriticalSection (& cond -> waiters_lock );
117-
118- if (last_waiter ) {
119- /*
120- * cond_broadcast was issued while mutex was held. This means
121- * that all other waiters have continued, but are contending
122- * for the mutex at the end of this function because the
123- * broadcasting thread did not leave cond_broadcast, yet.
124- * (This is so that it can be sure that each waiter has
125- * consumed exactly one slice of the semaphor.)
126- * The last waiter must tell the broadcasting thread that it
127- * can go on.
128- */
129- SetEvent (cond -> continue_broadcast );
130- /*
131- * Now we go on to contend with all other waiters for
132- * the mutex. Auf in den Kampf!
133- */
134- }
135- /* lock external mutex again */
136- EnterCriticalSection (mutex );
137-
138- return 0 ;
139- }
140-
141- /*
142- * IMPORTANT: This implementation requires that pthread_cond_signal
143- * is called while the mutex is held that is used in the corresponding
144- * pthread_cond_wait calls!
145- */
146- int pthread_cond_signal (pthread_cond_t * cond )
147- {
148- int have_waiters ;
149-
150- EnterCriticalSection (& cond -> waiters_lock );
151- have_waiters = cond -> waiters > 0 ;
152- LeaveCriticalSection (& cond -> waiters_lock );
153-
154- /*
155- * Signal only when there are waiters
156- */
157- if (have_waiters )
158- return ReleaseSemaphore (cond -> sema , 1 , NULL ) ?
159- 0 : err_win_to_posix (GetLastError ());
160- else
161- return 0 ;
162- }
163-
164- /*
165- * DOUBLY IMPORTANT: This implementation requires that pthread_cond_broadcast
166- * is called while the mutex is held that is used in the corresponding
167- * pthread_cond_wait calls!
168- */
169- int pthread_cond_broadcast (pthread_cond_t * cond )
170- {
171- EnterCriticalSection (& cond -> waiters_lock );
172-
173- if ((cond -> was_broadcast = cond -> waiters > 0 )) {
174- /* wake up all waiters */
175- ReleaseSemaphore (cond -> sema , cond -> waiters , NULL );
176- LeaveCriticalSection (& cond -> waiters_lock );
177- /*
178- * At this point all waiters continue. Each one takes its
179- * slice of the semaphor. Now it's our turn to wait: Since
180- * the external mutex is held, no thread can leave cond_wait,
181- * yet. For this reason, we can be sure that no thread gets
182- * a chance to eat *more* than one slice. OTOH, it means
183- * that the last waiter must send us a wake-up.
184- */
185- WaitForSingleObject (cond -> continue_broadcast , INFINITE );
186- /*
187- * Since the external mutex is held, no thread can enter
188- * cond_wait, and, hence, it is safe to reset this flag
189- * without cond->waiters_lock held.
190- */
191- cond -> was_broadcast = 0 ;
192- } else {
193- LeaveCriticalSection (& cond -> waiters_lock );
194- }
195- return 0 ;
196- }
0 commit comments