event-object-naming-20040308
[openafs.git] / src / WINNT / pthread / pthread.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 /*
11  * This file contains a skeleton pthread implementation for NT.
12  * This is not intended to be a fully compliant pthread implementation
13  * The purpose of this file is to only implement those functions that
14  * are truly needed to support the afs code base.
15  *
16  * A secondary goal is to allow a "real" pthread implementation to 
17  * replace this file without any modification to code that depends upon
18  * this file
19  *
20  * The function signatures and argument types are meant to be the same
21  * as their UNIX prototypes.
22  * Where possible, the POSIX specified return values are used.
23  * For situations where an error can occur, but no corresponding
24  * POSIX error value exists, unique (within a given function) negative 
25  * numbers are used for errors to avoid collsions with the errno
26  * style values.
27  */
28
29 #include <afs/param.h>
30 #include <afs/stds.h>
31
32 #include <pthread.h>
33 #include <stdlib.h>
34 #include <stdio.h>
35 #include <string.h>
36 #include <errno.h>
37 #include <sys/timeb.h>
38
39 #define PTHREAD_EXIT_EXCEPTION 0x1
40
41 /*
42  * Posix threads uses static initialization for pthread_once control
43  * objects, and under NT, every sophisticated synchronization primitive
44  * uses procedural initialization.  This forces the use of CompareExchange
45  * (aka test and set) and busy waiting for threads that compete to run
46  * a pthread_once'd function.  We make these "busy" threads give up their
47  * timeslice - which should cause acceptable behavior on a single processor
48  * machine, but on a multiprocessor machine this could very well result
49  * in busy waiting.
50  */
51
52 int pthread_once(pthread_once_t *once_control, void (*init_routine)(void)) {
53     int rc = 0;
54
55     if ((once_control != NULL) && (init_routine != NULL)) {
56         if (InterlockedExchange((LPLONG)&once_control->call_started,
57                                 (LONG) 1) == 0) {
58             (*init_routine)();
59             once_control->call_running = 0;
60         } else {
61             /* use Sleep() since SwitchToThread() not available on Win95 */
62             while(once_control->call_running) Sleep(20);
63         }
64     } else {
65         rc = EINVAL;
66     }
67     return rc;
68 }
69
70 /*
71  * For now only support PTHREAD_PROCESS_PRIVATE mutexes.
72  * if PTHREAD_PROCESS_SHARED are required later they can be added
73  */
74
75 int pthread_mutex_init(pthread_mutex_t *mp, const pthread_mutexattr_t *attr) {
76     int rc = 0;
77
78     if ((mp != NULL) && (attr == NULL)) {
79         InitializeCriticalSection(&mp->cs);
80         mp->isLocked = 0;
81         mp->tid = 0;
82     } else {
83         rc = EINVAL;
84     }
85     return rc;
86 }
87
88 /*
89  * Under NT, critical sections can be locked recursively by the owning
90  * thread.  This is opposite of the pthread spec, and so we keep track
91  * of the thread that has locked a critical section.  If the same thread
92  * tries to lock a critical section more than once we fail.
93  */
94 int pthread_mutex_trylock(pthread_mutex_t *mp) {
95     int rc = 0;
96
97 #ifdef AFS_WIN95_ENV
98     /* TryEnterCriticalSection() not available on Win95, so just wait for
99      * the lock.  Correct code generally can't depend on how long the
100      * function takes to return, so the only code that will be broken is
101      * that for which 1) the mutex *mp is obtained and never released or
102      * 2) the mutex *mp is intentionally held until trylock() returns.
103      * These cases are unusual and don't appear in normal (non-test) AFS
104      * code; furthermore, we can reduce (but not eliminate!) the problem by
105      * sneaking a look at isLocked even though we don't hold the
106      * CRITICAL_SECTION in mutex *mp and are thus vulnerable to race
107      * conditions.  Note that self-deadlock isn't a problem since
108      * CRITICAL_SECTION objects are recursive.
109      *
110      * Given the very restricted usage of the pthread library on Windows 95,
111      * we can live with these limitations.
112      */
113     if (mp != NULL) {
114         if (mp->isLocked) {
115             rc = EBUSY;
116         } else {
117             rc = pthread_mutex_lock(mp);
118         }
119     } else {
120         rc = EINVAL;
121     }
122 #else
123     /* TryEnterCriticalSection() provided on other MS platforms of interest */
124     if (mp != NULL) {
125         if (TryEnterCriticalSection(&mp->cs)) {
126             if (mp->isLocked) {
127                 /* same thread tried to recursively lock, fail */
128                 LeaveCriticalSection(&mp->cs);
129                 rc = EBUSY;
130             } else {
131                 mp->isLocked = 1;
132                 mp->tid = GetCurrentThreadId();
133                 rc = 0;
134             }
135         } else {
136             rc = EBUSY;
137         }
138     } else {
139         rc = EINVAL;
140     }
141 #endif /* AFS_WIN95_ENV */
142
143     return rc;
144 }
145
146
147 int pthread_mutex_lock(pthread_mutex_t *mp) {
148     int rc = 0;
149
150     if (mp != NULL) {
151         EnterCriticalSection(&mp->cs);
152         if (!mp->isLocked) {
153             mp->isLocked = 1;
154             mp->tid = GetCurrentThreadId();
155         } else {
156             /* 
157              * same thread tried to recursively lock this mutex.
158              * Under real POSIX, this would cause a deadlock, but NT only 
159              * supports recursive mutexes so we indicate the situation
160              * by returning EDEADLK.
161              */
162             LeaveCriticalSection(&mp->cs);
163             rc = EDEADLK;
164         }
165     } else {
166         rc = EINVAL;
167     }
168         
169     return rc;
170 }
171
172 int pthread_mutex_unlock(pthread_mutex_t *mp) {
173     int rc = 0;
174
175     if (mp != NULL) {
176         if (mp->tid == GetCurrentThreadId()) {
177             mp->isLocked = 0;
178             mp->tid = 0;
179             LeaveCriticalSection(&mp->cs);
180         } else {
181             rc = 0;
182         }
183     } else {
184         rc = EINVAL;
185     }
186     return rc;
187 }
188
189 int pthread_mutex_destroy(pthread_mutex_t *mp) {
190     int rc = 0;
191
192     if (mp != NULL) {
193         DeleteCriticalSection(&mp->cs);
194     } else {
195         rc = EINVAL;
196     }
197
198     return rc;
199 }
200
201 /*
202  * keys is used to keep track of which keys are currently
203  * in use by the threads library.  pthread_tsd_mutex is used
204  * to protect keys.
205  *
206  * The bookkeeping for keys in use and destructor function/key is
207  * at the library level.  Each individual thread only keeps its
208  * per key data value.  This implies that the keys array and the
209  * tsd array in the pthread_t structure need to always be exactly
210  * the same size since the same index is used for both arrays.
211  */
212
213 typedef struct {
214     int inuse;
215     void (*destructor)(void *);
216 } pthread_tsd_table_t;
217
218 static pthread_tsd_table_t keys[PTHREAD_KEYS_MAX];
219 static pthread_mutex_t pthread_tsd_mutex;
220 static pthread_once_t pthread_tsd_once = PTHREAD_ONCE_INIT;
221
222 /*
223  * In order to support p_self() and p_join() under NT,
224  * we have to keep our own list of active threads and provide a mapping
225  * function that maps the NT thread id to our internal structure.
226  * The main reason that this is necessary is that GetCurrentThread
227  * returns a special constant not an actual handle to the thread.
228  * This makes it impossible to write a p_self() function that works
229  * with only the native NT functions.
230  */
231
232 static struct rx_queue active_Q;
233 static struct rx_queue cache_Q;
234
235 static pthread_mutex_t active_Q_mutex;
236 static pthread_mutex_t cache_Q_mutex;
237
238 static pthread_once_t pthread_cache_once = PTHREAD_ONCE_INIT;
239 static int pthread_cache_done;
240
241 typedef struct thread {
242     struct rx_queue thread_queue;
243     void *rc;
244     int running;
245     pthread_cond_t wait_terminate;
246     int waiter_count;
247     int is_joinable;
248     int has_been_joined;
249     HANDLE t_handle;
250     DWORD NT_id;
251     int native_thread;
252     char **tsd;
253 } thread_t, *thread_p;
254
255 static void create_once(void) {
256     queue_Init(&active_Q);
257     queue_Init(&cache_Q);
258     pthread_mutex_init(&active_Q_mutex, (const pthread_mutexattr_t*)0);
259     pthread_mutex_init(&cache_Q_mutex, (const pthread_mutexattr_t*)0);
260     pthread_cache_done = 1;
261 }
262
263 static void put_thread(thread_p old) {
264  
265     CloseHandle(old->t_handle);
266     pthread_mutex_lock(&cache_Q_mutex);
267     queue_Prepend(&cache_Q, old);
268     pthread_mutex_unlock(&cache_Q_mutex);
269 }
270
271 static thread_p get_thread() {
272     thread_p new = NULL;
273  
274     pthread_mutex_lock(&cache_Q_mutex);
275  
276     if (queue_IsEmpty(&cache_Q)) {
277         new = (thread_p) malloc(sizeof(thread_t));
278         if (new != NULL) {
279             /*
280              * One time initialization - we assume threads put back have
281              * unlocked mutexes and condition variables with no waiters
282              *
283              * These functions cannot fail currently.
284              */
285             pthread_cond_init(&new->wait_terminate,(const pthread_condattr_t *)0);
286         }
287     } else {
288         new = queue_First(&cache_Q, thread);
289         queue_Remove(new);
290     }
291  
292     pthread_mutex_unlock(&cache_Q_mutex);
293
294     /* 
295      * Initialization done every time we hand out a thread_t
296      */
297
298     if (new != NULL) {
299         new->rc = NULL;
300         new->running = 1;
301         new->waiter_count = 0;
302         new->has_been_joined = 0;
303     }
304     return new;
305  
306 }
307  
308 /*
309  * The thread start function signature is different on NT than the pthread
310  * spec so we create a tiny stub to map from one signature to the next.
311  * This assumes that a void * can be stored within a DWORD.
312  */
313
314 typedef struct {
315     void *(*func)(void *);
316     void *arg;
317     char *tsd[PTHREAD_KEYS_MAX];
318     thread_p me;
319 } pthread_create_t;
320
321 static DWORD tsd_index = 0xffffffff;
322 static DWORD tsd_pthread_index = 0xffffffff;
323 static pthread_once_t global_tsd_once = PTHREAD_ONCE_INIT;
324 static int tsd_done;
325
326 static void tsd_once(void) {
327     while(tsd_index == 0xffffffff) {
328         tsd_index = TlsAlloc();
329     }
330     while(tsd_pthread_index == 0xffffffff) {
331         tsd_pthread_index = TlsAlloc();
332     }
333     tsd_done = 1;
334 }
335
336 static void tsd_free_all(char *tsd[PTHREAD_KEYS_MAX]) {
337     int call_more_destructors = 0;
338     do {
339         int i;
340         void *value;
341         void (*destructor)(void *);
342         call_more_destructors = 0;
343         for(i=0;i<PTHREAD_KEYS_MAX;i++) {
344             if (tsd[i] != NULL) {
345                 destructor = keys[i].destructor;
346                 value = (void *)tsd[i];
347                 tsd[i] = NULL;
348                 if (destructor != NULL) {
349                     (destructor)(value);
350                     /*
351                      * A side-effect of calling a destructor function is that
352                      * more thread specific may be created for this thread.
353                      * If we call a destructor, we must recycle through the
354                      * entire list again and run any new destructors.
355                      */
356                     call_more_destructors = 1;
357                 }
358             }
359         }
360     } while(call_more_destructors);
361 }
362
363 static DWORD WINAPI afs_pthread_create_stub(LPVOID param) {
364     pthread_create_t *t = (pthread_create_t *) param;
365     void *rc;
366
367     /* 
368      * Initialize thread specific storage structures.
369      */
370
371     memset(t->tsd, 0, (sizeof(char *) * PTHREAD_KEYS_MAX));
372     (tsd_done || pthread_once(&global_tsd_once, tsd_once));
373     TlsSetValue(tsd_index, (LPVOID) (t->tsd));
374     TlsSetValue(tsd_pthread_index, (LPVOID) (t->me));
375
376     /*
377      * Call the function the user passed to pthread_create and catch the
378      * pthread exit exception if it is raised.
379      */
380
381     __try {
382         rc = (*(t->func))(t->arg);
383     } __except(GetExceptionCode() == PTHREAD_EXIT_EXCEPTION) {
384         rc = t->me->rc; /* rc is set at pthread_exit */
385     }
386
387     /*
388      * Cycle through the thread specific data for this thread and
389      * call the destructor function for each non-NULL datum
390      */
391
392     tsd_free_all (t->tsd);
393     t->me->tsd = NULL;
394
395     /*
396      * If we are joinable, signal any waiters.
397      */
398
399     pthread_mutex_lock(&active_Q_mutex);
400     if (t->me->is_joinable) {
401         t->me->running = 0;
402         t->me->rc = rc;
403         if (t->me->waiter_count) {
404             pthread_cond_broadcast(&t->me->wait_terminate);
405         }
406     } else {
407         queue_Remove(t->me);
408         put_thread(t->me);
409     }
410     pthread_mutex_unlock(&active_Q_mutex);
411
412     free(t);
413     return 0;
414 }
415
416 /*
417  * If a pthread function is called on a thread which was not created by
418  * pthread_create(), that thread will have an entry added to the active_Q
419  * by pthread_self(). When the thread terminates, we need to know
420  * about it, so that we can perform cleanup. A dedicated thread is therefore
421  * maintained, which watches for any thread marked "native_thread==1"
422  * in the active_Q to terminate. The thread spends most of its time sleeping:
423  * it can be signalled by a dedicated event in order to alert it to the
424  * presense of a new thread to watch, or will wake up automatically when
425  * a native thread terminates.
426  */
427
428 static DWORD terminate_thread_id = 0;
429 static HANDLE terminate_thread_handle = INVALID_HANDLE_VALUE;
430 static HANDLE terminate_thread_wakeup_event = INVALID_HANDLE_VALUE;
431 static HANDLE *terminate_thread_wakeup_list = NULL;
432 static size_t terminate_thread_wakeup_list_size = 0;
433
434 static DWORD WINAPI terminate_thread_routine(LPVOID param) {
435     thread_p cur, next;
436     size_t native_thread_count;
437     int should_terminate;
438     int terminate_thread_wakeup_list_index;
439
440     for (;;) {
441         /*
442          * Grab the active_Q_mutex, and while we hold it, scan the active_Q
443          * to see how many native threads we need to watch. If we don't need
444          * to watch any, we can stop this watcher thread entirely (or not);
445          * if we do need to watch some, fill the terminate_thread_wakeup_list
446          * array and go to sleep.
447          */
448         cur = NULL;
449         next = NULL;
450         native_thread_count = 0;
451         should_terminate = FALSE;
452         pthread_mutex_lock(&active_Q_mutex);
453
454         for(queue_Scan(&active_Q, cur, next, thread)) {
455             if (cur->native_thread)
456                 ++native_thread_count;
457         }
458
459         /*
460          * At this point we could decide to terminate this watcher thread
461          * whenever there are no longer any native threads to watch--however,
462          * since thread creation is a time-consuming thing, and since this
463          * thread spends all its time sleeping anyway, there's no real
464          * compelling reason to do so. Thus, the following statement is
465          * commented out:
466          *
467          * if (!native_thread_count) {
468          *    should_terminate = TRUE;
469          * }
470          *
471          * Restore the snippet above to cause this watcher thread to only
472          * live whenever there are native threads to watch.
473          *
474          */
475
476         /*
477          * Make sure that our wakeup_list array is large enough to contain
478          * the handles of all the native threads /and/ to contain an
479          * entry for our wakeup_event (in case another native thread comes
480          * along).
481          */
482         if (terminate_thread_wakeup_list_size < (1+native_thread_count)) {
483             if (terminate_thread_wakeup_list)
484                 free (terminate_thread_wakeup_list);
485             terminate_thread_wakeup_list = (HANDLE*)malloc (sizeof(HANDLE) *
486                                 (1+native_thread_count));
487             if (terminate_thread_wakeup_list == NULL) {
488                 should_terminate = TRUE;
489             } else {
490                 terminate_thread_wakeup_list_size = 1+native_thread_count;
491             }
492         }
493
494         if (should_terminate) {
495             /*
496              * Here, we've decided to terminate this watcher thread.
497              * Free our wakeup event and wakeup list, then release the
498              * active_Q_mutex and break this loop.
499              */
500             if (terminate_thread_wakeup_list)
501                 free (terminate_thread_wakeup_list);
502             CloseHandle (terminate_thread_wakeup_event);
503             terminate_thread_id = 0;
504             terminate_thread_handle = INVALID_HANDLE_VALUE;
505             terminate_thread_wakeup_event = INVALID_HANDLE_VALUE;
506             terminate_thread_wakeup_list = NULL;
507             terminate_thread_wakeup_list_size = 0;
508             pthread_mutex_unlock(&active_Q_mutex);
509             break;
510         } else {
511             /*
512              * Here, we've decided to wait for native threads et al.
513              * Fill out the wakeup_list.
514              */
515             memset(terminate_thread_wakeup_list, 0x00, (sizeof(HANDLE) * 
516                                 (1+native_thread_count)));
517
518             terminate_thread_wakeup_list[0] = terminate_thread_wakeup_event;
519             terminate_thread_wakeup_list_index = 1;
520
521             cur = NULL;
522             next = NULL;
523             for(queue_Scan(&active_Q, cur, next, thread)) {
524                 if (cur->native_thread) {
525                     terminate_thread_wakeup_list[terminate_thread_wakeup_list_index]
526                         = cur->t_handle;
527                     ++terminate_thread_wakeup_list_index;
528                 }
529             }
530
531             ResetEvent (terminate_thread_wakeup_event);
532         }
533
534         pthread_mutex_unlock(&active_Q_mutex);
535
536         /*
537          * Time to sleep. We'll wake up if either of the following happen:
538          * 1) Someone sets the terminate_thread_wakeup_event (this will
539          *    happen if another native thread gets added to the active_Q)
540          * 2) One or more of the native threads terminate
541          */
542         terminate_thread_wakeup_list_index = WaitForMultipleObjects(
543                                         1+native_thread_count,
544                                         terminate_thread_wakeup_list,
545                                         FALSE,
546                                         INFINITE);
547
548         /*
549          * If we awoke from sleep because an event other than
550          * terminate_thread_wakeup_event was triggered, it means the
551          * specified thread has terminated. (If more than one thread
552          * terminated, we'll handle this first one and loop around--
553          * the event's handle will still be triggered, so we just won't
554          * block at all when we sleep next time around.)
555          */
556         if (terminate_thread_wakeup_list_index > 0) {
557             pthread_mutex_lock(&active_Q_mutex);
558
559             cur = NULL;
560             next = NULL;
561             for(queue_Scan(&active_Q, cur, next, thread)) {
562                 if (cur->t_handle == terminate_thread_wakeup_list[ terminate_thread_wakeup_list_index ])
563                     break;
564             }
565
566             if(cur != NULL) {
567                 /*
568                  * Cycle through the thread specific data for the specified
569                  * thread and call the destructor function for each non-NULL
570                  * datum. Then remove the thread_t from active_Q and put it
571                  * back on cache_Q for possible later re-use.
572                  */
573                 if(cur->tsd != NULL) {
574                     tsd_free_all(cur->tsd);
575                     free(cur->tsd);
576                     cur->tsd = NULL;
577                 }
578                 queue_Remove(cur);
579                 put_thread(cur);
580             }
581
582             pthread_mutex_unlock(&active_Q_mutex);
583         }
584     }
585     return 0;
586 }
587
588
589 static void pthread_sync_terminate_thread(void) {
590     (pthread_cache_done || pthread_once(&pthread_cache_once, create_once));
591
592     if (terminate_thread_handle == INVALID_HANDLE_VALUE) {
593         CHAR eventName[MAX_PATH];
594         static eventCount = 0;
595         sprintf(eventName, "terminate_thread_wakeup_event %d::%d", _getpid(), eventCount++);
596         terminate_thread_wakeup_event = CreateEvent((LPSECURITY_ATTRIBUTES) 0,
597                                                      TRUE, FALSE, (LPCTSTR) eventName);
598         terminate_thread_handle = CreateThread((LPSECURITY_ATTRIBUTES) 0, 0, 
599                                                 terminate_thread_routine, (LPVOID) 0, 0, 
600                                                 &terminate_thread_id);
601     } else {
602         SetEvent (terminate_thread_wakeup_event);
603     }
604 }
605
606
607 /*
608  * Only support the detached attribute specifier for pthread_create.
609  * Under NT, thread stacks grow automatically as needed.
610  */
611
612 int pthread_create(pthread_t *tid, const pthread_attr_t *attr, void *(*func)(void *), void *arg) {
613     int rc = 0;
614     pthread_create_t *t = NULL;
615
616     (pthread_cache_done || pthread_once(&pthread_cache_once, create_once));
617
618     if ((tid != NULL) && (func != NULL)) {
619         if ((t = (pthread_create_t *) malloc(sizeof(pthread_create_t))) &&
620             (t->me = get_thread()) ) {
621             t->func = func;
622             t->arg = arg;
623             *tid = (pthread_t) t->me;
624             if (attr != NULL) {
625                 t->me->is_joinable = attr->is_joinable;
626             } else {
627                 t->me->is_joinable = PTHREAD_CREATE_JOINABLE;
628             }
629             t->me->native_thread = 0;
630             t->me->tsd = t->tsd;
631             /*
632              * At the point (before we actually create the thread)
633              * we need to add our entry to the active queue.  This ensures
634              * us that other threads who may run after this thread returns
635              * will find an entry for the create thread regardless of
636              * whether the newly created thread has run or not.
637              * In the event the thread create fails, we will have temporarily
638              * added an entry to the list that was never valid, but we
639              * (i.e. the thread that is calling thread_create) are the
640              * only one who could possibly know about the bogus entry
641              * since we hold the active_Q_mutex.
642              */
643             pthread_mutex_lock(&active_Q_mutex);
644             queue_Prepend(&active_Q, t->me);
645             t->me->t_handle = CreateThread((LPSECURITY_ATTRIBUTES) 0, 0, 
646                                 afs_pthread_create_stub, (LPVOID) t, 0, 
647                                 &t->me->NT_id);
648             if (t->me->t_handle == 0) {
649                 /* 
650                  * we only free t if the thread wasn't created, otherwise
651                  * it's free'd by the new thread.
652                  */
653                 queue_Remove(t->me);
654                 put_thread(t->me);
655                 free(t);
656                 rc = EAGAIN;
657             }
658             pthread_mutex_unlock(&active_Q_mutex);
659         } else {
660             if (t != NULL) {
661                 free(t);
662             }
663             rc = ENOMEM;
664         }
665     } else {
666         rc = EINVAL;
667     }
668     return rc;
669 }
670
671 int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr) {
672     int rc = 0;
673
674     /*
675      * Only support default attribute -> must pass a NULL pointer for
676      * attr parameter.
677      */
678     if ((attr == NULL) && (cond != NULL)) {
679         InitializeCriticalSection(&cond->cs);
680         queue_Init(&cond->waiting_threads);
681     } else {
682         rc = EINVAL;
683     }
684
685     return rc;
686 }
687
688 /*
689  * In order to optimize the performance of condition variables,
690  * we maintain a pool of cond_waiter_t's that have been dynamically
691  * allocated.  There is no attempt made to garbage collect these -
692  * once they have been created, they stay in the cache for the life
693  * of the process.
694  */
695  
696 static struct rx_queue waiter_cache;
697 static CRITICAL_SECTION waiter_cache_cs;
698 static int waiter_cache_init;
699 static pthread_once_t waiter_cache_once = PTHREAD_ONCE_INIT;
700  
701 static void init_waiter_cache(void) {
702     InitializeCriticalSection(&waiter_cache_cs);
703     waiter_cache_init = 1;
704     queue_Init(&waiter_cache);
705 }
706  
707 static cond_waiters_t *get_waiter() {
708     cond_waiters_t *new = NULL;
709  
710     (waiter_cache_init || pthread_once(&waiter_cache_once, init_waiter_cache));
711  
712     EnterCriticalSection(&waiter_cache_cs);
713  
714     if (queue_IsEmpty(&waiter_cache)) {
715         new = (cond_waiters_t *) malloc(sizeof(cond_waiters_t));
716         if (new != NULL) {
717         CHAR eventName[MAX_PATH];
718         static eventCount = 0;
719         sprintf(eventName, "cond_waiters_t %d::%d", _getpid(), eventCount++);
720         new->event = CreateEvent((LPSECURITY_ATTRIBUTES) 0, FALSE,
721                                   FALSE, (LPCTSTR) eventName);
722             if (new->event == NULL) {
723                 free(new);
724                 new = NULL;
725             }
726         }
727     } else {
728         new = queue_First(&waiter_cache, cond_waiter);
729         queue_Remove(new);
730     }
731  
732     LeaveCriticalSection(&waiter_cache_cs);
733     return new;
734  
735 }
736  
737 static void put_waiter(cond_waiters_t *old) {
738  
739     (waiter_cache_init || pthread_once(&waiter_cache_once, init_waiter_cache));
740  
741     EnterCriticalSection(&waiter_cache_cs);
742     queue_Prepend(&waiter_cache, old);
743     LeaveCriticalSection(&waiter_cache_cs);
744 }
745
746 static int cond_wait_internal(pthread_cond_t *cond, pthread_mutex_t *mutex, const DWORD time) {
747     int rc=0;
748     cond_waiters_t *my_entry = get_waiter();
749     cond_waiters_t *cur, *next;
750     int hasnt_been_signalled=0;
751
752     if ((cond != NULL) && (mutex != NULL) && (my_entry != NULL)) {
753         EnterCriticalSection(&cond->cs);
754         queue_Append(&cond->waiting_threads, my_entry);
755         LeaveCriticalSection(&cond->cs);
756
757         if (!pthread_mutex_unlock(mutex)) {
758             switch(WaitForSingleObject(my_entry->event, time)) {
759                 case WAIT_FAILED:
760                     rc = -1;
761                     break;
762                 case WAIT_TIMEOUT:
763                     rc = ETIME;
764                     /*
765                      * This is a royal pain.  We've timed out waiting
766                      * for the signal, but between the time out and here
767                      * it is possible that we were actually signalled by 
768                      * another thread.  So we grab the condition lock
769                      * and scan the waiting thread queue to see if we are
770                      * still there.  If we are, we just remove ourselves.
771                      *
772                      * If we are no longer listed in the waiter queue,
773                      * it means that we were signalled after the time
774                      * out occurred and so we have to do another wait
775                      * WHICH HAS TO SUCCEED!  In this case, we reset
776                      * rc to indicate that we were signalled.
777                      *
778                      * We have to wait or otherwise, the event
779                      * would be cached in the signalled state, which
780                      * is wrong.  It might be more efficient to just
781                      * close and reopen the event.
782                      */
783                     EnterCriticalSection(&cond->cs);
784                     for(queue_Scan(&cond->waiting_threads, cur,
785                                    next, cond_waiter)) {
786                         if (cur == my_entry) {
787                             hasnt_been_signalled = 1;
788                             break;
789                         }
790                     }
791                     if (hasnt_been_signalled) {
792                         queue_Remove(cur);
793                     } else {
794                         rc = 0;
795                         if (ResetEvent(my_entry->event)) {
796                             if (pthread_mutex_lock(mutex)) {
797                                 rc = -5;
798                             }
799                         } else {
800                             rc = -6;
801                         }
802                     }
803                     LeaveCriticalSection(&cond->cs);
804                     break;
805                 case WAIT_ABANDONED:
806                     rc = -2;
807                     break;
808                 case WAIT_OBJECT_0:
809                     if (pthread_mutex_lock(mutex)) {
810                         rc = -3;
811                     }
812                     break;
813                 default:
814                     rc = -4;
815                     break;
816             }
817         } else {
818             rc = EINVAL;
819         }
820     } else {
821         rc = EINVAL;
822     }
823
824     if (my_entry != NULL) {
825         put_waiter(my_entry);
826     }
827
828     return rc;
829 }
830
831 int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) {
832     int rc = 0;
833
834     rc = cond_wait_internal(cond, mutex, INFINITE);
835     return rc;
836 }
837
838 int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime) {
839     int rc = 0;
840     struct _timeb now, then;
841     short n_milli, t_milli;
842
843     if (abstime->tv_nsec < 1000000000) {
844
845         /*
846          * pthread timedwait uses an absolute time, NT uses relative so
847          * we convert here.  The millitm field in the timeb struct is
848          * unsigned, but we need to do subtraction preserving the sign, 
849          * so we copy the fields into temporary variables.
850          *
851          * WARNING:
852          * In NT 4.0 SP3, WaitForSingleObject can occassionally timeout
853          * earlier than requested.  Therefore, our pthread_cond_timedwait
854          * can also return early.
855          */
856
857         _ftime(&now);
858         n_milli = now.millitm;
859         then.time = abstime->tv_sec;
860         t_milli = abstime->tv_nsec/1000000;
861
862         if((then.time > now.time || 
863            (then.time == now.time && t_milli > n_milli))) {
864             if((t_milli -= n_milli) < 0) {
865                 t_milli += 1000;
866                 then.time--;
867             }
868             then.time -= now.time;
869
870             if ((then.time + (clock() / CLOCKS_PER_SEC)) <= 50000000) {
871                 /*
872                  * Under NT, we can only wait for milliseconds, so we
873                  * round up the wait time here.
874                  */
875                 rc = cond_wait_internal(cond, mutex, 
876                                  ((then.time * 1000) + (t_milli)));
877             } else {
878                 rc = EINVAL;
879             }
880         } else {
881             rc = ETIME;
882         }
883     } else {
884         rc = EINVAL;
885     }
886
887     return rc;
888 }
889
890 int pthread_cond_signal(pthread_cond_t *cond) {
891     int rc = 0;
892     cond_waiters_t *release_thread;
893
894     if (cond != NULL) {
895         EnterCriticalSection(&cond->cs);
896
897         /*
898          * remove the first waiting thread from the queue
899          * and resume his execution
900          */
901         if (queue_IsNotEmpty(&cond->waiting_threads)) {
902             release_thread = queue_First(&cond->waiting_threads,
903                                          cond_waiter);
904             queue_Remove(release_thread);
905             if (!SetEvent(release_thread->event)) {
906                 rc = -1;
907             }
908         }
909
910         LeaveCriticalSection(&cond->cs);
911     } else {
912         rc = EINVAL;
913     }
914
915     return rc;
916 }
917
918 int pthread_cond_broadcast(pthread_cond_t *cond) {
919     int rc = 0;
920     cond_waiters_t *release_thread, *next_thread;
921
922     if(cond != NULL) {
923         EnterCriticalSection(&cond->cs);
924
925         /*
926          * Empty the waiting_threads queue. 
927          */
928         if (queue_IsNotEmpty(&cond->waiting_threads)) {
929             for(queue_Scan(&cond->waiting_threads, release_thread,
930                            next_thread, cond_waiter)) {
931                 queue_Remove(release_thread);
932                 if (!SetEvent(release_thread->event)) {
933                     rc = -1;
934                 }
935             }
936         }
937
938         LeaveCriticalSection(&cond->cs);
939     } else {
940         rc = EINVAL;
941     }
942
943     return rc;
944 }
945
946 int pthread_cond_destroy(pthread_cond_t *cond) {
947     int rc = 0;
948
949     if (cond != NULL) {
950         DeleteCriticalSection(&cond->cs);
951     } else {
952         rc = EINVAL;
953     }
954         
955     /*
956      * A previous version of this file had code to check the waiter
957      * queue and empty it here.  This has been removed in the hopes
958      * that it will aid in debugging.
959      */
960
961     return rc;
962 }
963
964 int pthread_join(pthread_t target_thread, void **status) {
965     int rc = 0;
966     thread_p me, target;
967     thread_p cur, next;
968
969     target = (thread_p) target_thread;
970     me = (thread_p) pthread_self();
971
972     if (me != target) {
973         /*
974          * Check to see that the target thread is joinable and hasn't
975          * already been joined.
976          */
977
978         pthread_mutex_lock(&active_Q_mutex);
979
980         for(queue_Scan(&active_Q, cur, next, thread)) {
981             if (target == cur) break;
982         }
983
984         if (target == cur) {
985             if ((!target->is_joinable) || (target->has_been_joined)) {
986                 rc = ESRCH;
987             }
988         } else {
989             rc = ESRCH;
990         }
991
992         if (rc) {
993             pthread_mutex_unlock(&active_Q_mutex);
994             return rc;
995         }
996
997         target->waiter_count++;
998         while(target->running) {
999             pthread_cond_wait(&target->wait_terminate, &active_Q_mutex);
1000         }
1001
1002         /*
1003          * Only one waiter gets the status and is allowed to join, all the
1004          * others get an error.
1005          */
1006
1007         if (target->has_been_joined) {
1008             rc = ESRCH;
1009         } else {
1010             target->has_been_joined = 1;
1011             if (status) {
1012                 *status = target->rc;
1013             }
1014         }
1015
1016         /*
1017          * If we're the last waiter it is our responsibility to remove
1018          * this entry from the terminated list and put it back in the
1019          * cache.
1020          */
1021
1022         target->waiter_count--;
1023         if (target->waiter_count == 0) {
1024             queue_Remove(target);
1025             pthread_mutex_unlock(&active_Q_mutex);
1026             put_thread(target);
1027         } else {
1028             pthread_mutex_unlock(&active_Q_mutex);
1029         }
1030     } else {
1031         rc = EDEADLK;
1032     }
1033
1034     return rc;
1035 }
1036
1037 /*
1038  * Note that we can't return an error from pthread_getspecific so
1039  * we return a NULL pointer instead.
1040  */
1041
1042 void *pthread_getspecific(pthread_key_t key) {
1043     void *rc = NULL;
1044     char **tsd = TlsGetValue(tsd_index);
1045
1046     if ((key > -1) && (key < PTHREAD_KEYS_MAX )) {
1047         rc = (void *) *(tsd + key);
1048     }
1049
1050     return rc;
1051 }
1052
1053 static int p_tsd_done;
1054
1055 static void pthread_tsd_init(void) {
1056     pthread_mutex_init(&pthread_tsd_mutex, (const pthread_mutexattr_t*)0);
1057     p_tsd_done = 1;
1058 }
1059
1060 int pthread_key_create(pthread_key_t *keyp, void (*destructor)(void *value)) {
1061     int rc = 0;
1062     int i;
1063
1064     if (p_tsd_done || (!pthread_once(&pthread_tsd_once, pthread_tsd_init))) {
1065         if (!pthread_mutex_lock(&pthread_tsd_mutex)) {
1066             for(i=0;i<PTHREAD_KEYS_MAX;i++) {
1067                 if (!keys[i].inuse) break;
1068             }
1069
1070             if (!keys[i].inuse) {
1071                 keys[i].inuse = 1;
1072                 keys[i].destructor = destructor;
1073                 *keyp = i;
1074             } else {
1075                 rc = EAGAIN;
1076             }
1077             pthread_mutex_unlock(&pthread_tsd_mutex);
1078         } else {
1079             rc = -1;
1080         }
1081     } else {
1082         rc = -2;
1083     }
1084
1085     return rc;
1086 }
1087
1088 int pthread_key_delete(pthread_key_t key) {
1089     int rc = 0;
1090
1091     if (p_tsd_done || (!pthread_once(&pthread_tsd_once, pthread_tsd_init))) {
1092         if ((key > -1) && (key < PTHREAD_KEYS_MAX )) {
1093             if (!pthread_mutex_lock(&pthread_tsd_mutex)) {
1094                 keys[key].inuse = 0;
1095                 keys[key].destructor = NULL;
1096                 pthread_mutex_unlock(&pthread_tsd_mutex);
1097             } else {
1098                 rc = -1;
1099             }
1100         } else {
1101             rc = EINVAL;
1102         }
1103     } else {
1104         rc = -2;
1105     }
1106
1107     return rc;
1108 }
1109
1110 int pthread_setspecific(pthread_key_t key, const void *value) {
1111     int rc = 0;
1112     char **tsd;
1113
1114     if (p_tsd_done || (!pthread_once(&pthread_tsd_once, pthread_tsd_init))) {
1115         if ((key > -1) && (key < PTHREAD_KEYS_MAX )) {
1116             if (!pthread_mutex_lock(&pthread_tsd_mutex)) {
1117                 if (keys[key].inuse) {
1118                     tsd = TlsGetValue(tsd_index);
1119                     *(tsd + key) = (char *) value;
1120                 } else {
1121                     rc = EINVAL;
1122                 }
1123                 pthread_mutex_unlock(&pthread_tsd_mutex);
1124             } else {
1125                 rc = -1;
1126             }
1127         } else {
1128             rc = EINVAL;
1129         }
1130     } else {
1131       rc = -2;
1132     }
1133
1134     return rc;
1135 }
1136
1137 pthread_t pthread_self(void) {
1138     thread_p cur;
1139     DWORD my_id = GetCurrentThreadId();
1140
1141     (pthread_cache_done || pthread_once(&pthread_cache_once, create_once));
1142     (tsd_done || pthread_once(&global_tsd_once, tsd_once));
1143
1144     pthread_mutex_lock(&active_Q_mutex);
1145
1146     cur = TlsGetValue (tsd_pthread_index);
1147
1148     if(!cur) {
1149         /*
1150          * This thread's ID was not found in our list of pthread-API client
1151          * threads (e.g., those threads created via pthread_create). Create
1152          * an entry for it.
1153          */
1154         if ((cur = get_thread()) != NULL) {
1155             cur->is_joinable = 0;
1156             cur->NT_id = my_id;
1157             cur->native_thread = 1;
1158             DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
1159              GetCurrentProcess(), &cur->t_handle, 0,
1160              TRUE, DUPLICATE_SAME_ACCESS);
1161
1162             /*
1163              * We'll also need a place to store key data for this thread
1164              */
1165             if ((cur->tsd = malloc(sizeof(char*) * PTHREAD_KEYS_MAX)) != NULL) {
1166                 memset(cur->tsd, 0, (sizeof(char*) * PTHREAD_KEYS_MAX));
1167             }
1168             TlsSetValue(tsd_index, (LPVOID)cur->tsd);
1169             TlsSetValue(tsd_pthread_index, (LPVOID)cur);
1170
1171             /*
1172              * The thread_t structure is complete; add it to the active_Q
1173              */
1174             queue_Prepend(&active_Q, cur);
1175
1176             /*
1177              * We were able to successfully insert a new entry into the
1178              * active_Q; however, when this thread terminates, we will need
1179              * to know about it. The pthread_sync_terminate_thread() routine
1180              * will make sure there is a dedicated thread waiting for any
1181              * native-thread entries in the active_Q to terminate.
1182              */
1183             pthread_sync_terminate_thread();
1184         }
1185     }
1186
1187     pthread_mutex_unlock(&active_Q_mutex);
1188
1189     return (void *) cur;
1190 }
1191
1192 int pthread_equal(pthread_t t1, pthread_t t2) {
1193     return (t1 == t2);
1194 }
1195
1196 int pthread_attr_destroy(pthread_attr_t *attr) {
1197     int rc = 0;
1198
1199     return rc;
1200 }
1201
1202 int pthread_attr_init(pthread_attr_t *attr) {
1203     int rc = 0;
1204
1205     if (attr != NULL) {
1206         attr->is_joinable = PTHREAD_CREATE_JOINABLE;
1207     } else {
1208         rc = EINVAL;
1209     }
1210
1211     return rc;
1212 }
1213
1214 int pthread_attr_getdetachstate(pthread_attr_t *attr, int *detachstate) {
1215     int rc = 0;
1216
1217     if ((attr != NULL) && (detachstate != NULL)) {
1218             *detachstate = attr->is_joinable;
1219     } else {
1220         rc = EINVAL;
1221     }
1222     return rc;
1223 }
1224
1225 int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate) {
1226     int rc = 0;
1227
1228     if ((attr != NULL) && ((detachstate == PTHREAD_CREATE_JOINABLE) ||
1229         (detachstate == PTHREAD_CREATE_DETACHED))) {
1230         attr->is_joinable = detachstate;
1231     } else {
1232         rc = EINVAL;
1233     }
1234     return rc;
1235 }
1236
1237 void pthread_exit(void *status) {
1238     thread_p me = (thread_p) pthread_self();
1239
1240     /*
1241      * Support pthread_exit for thread's created by calling pthread_create
1242      * only.  Do this by using an exception that will transfer control
1243      * back to afs_pthread_create_stub.  Store away our status before
1244      * returning.
1245      *
1246      * If this turns out to be a native thread, the exception will be
1247      * unhandled and the process will terminate.
1248      */
1249
1250     me->rc = status;
1251     RaiseException(PTHREAD_EXIT_EXCEPTION, 0, 0, NULL);
1252
1253 }