* Makefile: Add reference to ICSharpCode.SharpZipLib.dll.
[mono.git] / mono / io-layer / threads.c
1 /*
2  * threads.c:  Thread handles
3  *
4  * Author:
5  *      Dick Porter (dick@ximian.com)
6  *
7  * (C) 2002-2006 Ximian, Inc.
8  */
9
10 #include <config.h>
11 #include <stdio.h>
12 #include <glib.h>
13 #include <string.h>
14 #include <mono/utils/gc_wrapper.h>
15 #include <pthread.h>
16 #include <signal.h>
17 #include <sched.h>
18 #include <sys/time.h>
19 #include <errno.h>
20 #include <sys/types.h>
21 #include <unistd.h>
22
23 #include <mono/io-layer/wapi.h>
24 #include <mono/io-layer/wapi-private.h>
25 #include <mono/io-layer/handles-private.h>
26 #include <mono/io-layer/misc-private.h>
27 #include <mono/io-layer/mono-mutex.h>
28 #include <mono/io-layer/thread-private.h>
29 #include <mono/io-layer/mono-spinlock.h>
30 #include <mono/io-layer/mutex-private.h>
31 #include <mono/io-layer/atomic.h>
32
33 #ifdef HAVE_VALGRIND_MEMCHECK_H
34 #include <valgrind/memcheck.h>
35 #endif
36
37 #undef DEBUG
38 #undef TLS_DEBUG
39
40 #if 0
41 #define WAIT_DEBUG(code) do { code } while (0)
42 #else
43 #define WAIT_DEBUG(code) do { } while (0)
44 #endif
45
46 /* Hash threads with tids. I thought of using TLS for this, but that
47  * would have to set the data in the new thread, which is more hassle
48  */
49 static mono_once_t thread_hash_once = MONO_ONCE_INIT;
50 static pthread_key_t thread_hash_key;
51
52 /* This key is used with attached threads and a destructor to signal
53  * when attached threads exit, as they don't have the thread_exit()
54  * infrastructure
55  */
56 static pthread_key_t thread_attached_key;
57
58 struct _WapiHandleOps _wapi_thread_ops = {
59         NULL,                           /* close */
60         NULL,                           /* signal */
61         NULL,                           /* own */
62         NULL,                           /* is_owned */
63         NULL,                           /* special_wait */
64         NULL                            /* prewait */
65 };
66
67 static mono_once_t thread_ops_once=MONO_ONCE_INIT;
68
69 static void thread_ops_init (void)
70 {
71         _wapi_handle_register_capabilities (WAPI_HANDLE_THREAD,
72                                             WAPI_HANDLE_CAP_WAIT);
73 }
74
75 void _wapi_thread_cleanup (void)
76 {
77         int ret;
78         
79         ret = pthread_key_delete (thread_hash_key);
80         g_assert (ret == 0);
81         
82         ret = pthread_key_delete (thread_attached_key);
83         g_assert (ret == 0);
84 }
85
86 /* Called by thread_exit(), but maybe indirectly by
87  * mono_thread_manage() via mono_thread_signal_self() too
88  */
89 static void _wapi_thread_abandon_mutexes (gpointer handle)
90 {
91         struct _WapiHandle_thread *thread_handle;
92         gboolean ok;
93         int i;
94         pid_t pid = _wapi_getpid ();
95         pthread_t tid = pthread_self ();
96         
97 #ifdef DEBUG
98         g_message ("%s: Thread %p abandoning held mutexes", __func__, handle);
99 #endif
100
101         if (handle == NULL) {
102                 handle = _wapi_thread_handle_from_id (pthread_self ());
103                 if (handle == NULL) {
104                         /* Something gone badly wrong... */
105                         return;
106                 }
107         }
108         
109         ok = _wapi_lookup_handle (handle, WAPI_HANDLE_THREAD,
110                                   (gpointer *)&thread_handle);
111         if (ok == FALSE) {
112                 g_warning ("%s: error looking up thread handle %p", __func__,
113                            handle);
114                 return;
115         }
116         
117         if (!pthread_equal (thread_handle->id, tid)) {
118                 return;
119         }
120         
121         for (i = 0; i < thread_handle->owned_mutexes->len; i++) {
122                 gpointer mutex = g_ptr_array_index (thread_handle->owned_mutexes, i);
123                 
124                 _wapi_mutex_abandon (mutex, pid, tid);
125                 _wapi_thread_disown_mutex (mutex);
126         }
127 }
128
129 void _wapi_thread_set_termination_details (gpointer handle,
130                                            guint32 exitstatus)
131 {
132         struct _WapiHandle_thread *thread_handle;
133         gboolean ok;
134         int thr_ret;
135         
136         if (_wapi_handle_issignalled (handle) ||
137             _wapi_handle_type (handle) == WAPI_HANDLE_UNUSED) {
138                 /* We must have already deliberately finished with
139                  * this thread, so don't do any more now
140                  */
141                 return;
142         }
143
144 #ifdef DEBUG
145         g_message ("%s: Thread %p terminating", __func__, handle);
146 #endif
147
148         _wapi_thread_abandon_mutexes (handle);
149         
150         ok = _wapi_lookup_handle (handle, WAPI_HANDLE_THREAD,
151                                   (gpointer *)&thread_handle);
152         if (ok == FALSE) {
153                 g_warning ("%s: error looking up thread handle %p", __func__,
154                            handle);
155
156                 return;
157         }
158         
159         pthread_cleanup_push ((void(*)(void *))_wapi_handle_unlock_handle,
160                               handle);
161         thr_ret = _wapi_handle_lock_handle (handle);
162         g_assert (thr_ret == 0);
163         
164         thread_handle->exitstatus = exitstatus;
165         thread_handle->state = THREAD_STATE_EXITED;
166         MONO_SEM_DESTROY (&thread_handle->suspend_sem);
167         g_ptr_array_free (thread_handle->owned_mutexes, TRUE);
168
169         _wapi_handle_set_signal_state (handle, TRUE, TRUE);
170
171         thr_ret = _wapi_handle_unlock_handle (handle);
172         g_assert (thr_ret == 0);
173         pthread_cleanup_pop (0);
174         
175 #ifdef DEBUG
176         g_message("%s: Recording thread handle %p id %ld status as %d",
177                   __func__, handle, thread_handle->id, exitstatus);
178 #endif
179         
180         /* The thread is no longer active, so unref it */
181         _wapi_handle_unref (handle);
182 }
183
184 void _wapi_thread_signal_self (guint32 exitstatus)
185 {
186         gpointer handle;
187         
188         handle = _wapi_thread_handle_from_id (pthread_self ());
189         if (handle == NULL) {
190                 /* Something gone badly wrong... */
191                 return;
192         }
193         
194         _wapi_thread_set_termination_details (handle, exitstatus);
195 }
196
197 /* Called by the thread creation code as a thread is finishing up, and
198  * by ExitThread()
199 */
200 static void thread_exit (guint32 exitstatus, gpointer handle) G_GNUC_NORETURN;
201 static void thread_exit (guint32 exitstatus, gpointer handle)
202 {
203         _wapi_thread_set_termination_details (handle, exitstatus);
204         
205         /* Call pthread_exit() to call destructors and really exit the
206          * thread
207          */
208         pthread_exit (NULL);
209 }
210
211 static void thread_attached_exit (gpointer handle)
212 {
213         /* Drop the extra reference we take in thread_attach, now this
214          * thread is dead
215          */
216         
217         _wapi_thread_set_termination_details (handle, 0);
218 }
219
220 static void thread_hash_init(void)
221 {
222         int thr_ret;
223         
224         thr_ret = pthread_key_create (&thread_hash_key, NULL);
225         g_assert (thr_ret == 0);
226
227         thr_ret = pthread_key_create (&thread_attached_key,
228                                       thread_attached_exit);
229         g_assert (thr_ret == 0);
230 }
231
232 static void _wapi_thread_suspend (struct _WapiHandle_thread *thread)
233 {
234         g_assert (pthread_equal (thread->id, pthread_self ()));
235         
236         while (MONO_SEM_WAIT (&thread->suspend_sem) != 0 &&
237                errno == EINTR);
238 }
239
240 static void _wapi_thread_resume (struct _WapiHandle_thread *thread)
241 {
242         MONO_SEM_POST (&thread->suspend_sem);
243 }
244
245 static void *thread_start_routine (gpointer args) G_GNUC_NORETURN;
246 static void *thread_start_routine (gpointer args)
247 {
248         struct _WapiHandle_thread *thread = (struct _WapiHandle_thread *)args;
249         int thr_ret;
250         
251         thr_ret = pthread_detach (pthread_self ());
252         g_assert (thr_ret == 0);
253
254         thr_ret = pthread_setspecific (thread_hash_key,
255                                        (void *)thread->handle);
256         if (thr_ret != 0) {
257                 /* This is only supposed to happen when Mono is
258                    shutting down.  We cannot assert on it, though,
259                    because we must not depend on metadata, which is
260                    where the shutdown code is.
261
262                    This is a race condition which arises because
263                    pthreads don't allow creation of suspended threads.
264                    Once Mono is set to shut down no new thread is
265                    allowed to start, even though threads may still be
266                    created.  We emulate suspended threads in this
267                    function by calling _wapi_thread_suspend() below.
268
269                    So it can happen that even though Mono is already
270                    shutting down we still end up here, and at this
271                    point the thread_hash_key might already be
272                    destroyed. */
273                 pthread_exit (NULL);
274         }
275
276         thread->id = pthread_self();
277
278 #ifdef DEBUG
279         g_message ("%s: started thread id %ld", __func__, thread->id);
280 #endif
281
282         if (thread->create_flags & CREATE_SUSPENDED) {
283                 _wapi_thread_suspend (thread);
284         }
285         
286         thread_exit (thread->start_routine (thread->start_arg),
287                      thread->handle);
288
289 #ifndef __GNUC__
290         /* Even though we tell gcc that this function doesn't return,
291          * other compilers won't see that.
292          */
293         return(NULL);
294 #endif
295 }
296
297 /**
298  * CreateThread:
299  * @security: Ignored for now.
300  * @stacksize: the size in bytes of the new thread's stack. Use 0 to
301  * default to the normal stack size. (Ignored for now).
302  * @start: The function that the new thread should start with
303  * @param: The parameter to give to @start.
304  * @create: If 0, the new thread is ready to run immediately.  If
305  * %CREATE_SUSPENDED, the new thread will be in the suspended state,
306  * requiring a ResumeThread() call to continue running.
307  * @tid: If non-NULL, the ID of the new thread is stored here.  NB
308  * this is defined as a DWORD (ie 32bit) in the MS API, but we need to
309  * cope with 64 bit IDs for s390x and amd64.
310  *
311  * Creates a new threading handle.
312  *
313  * Return value: a new handle, or NULL
314  */
315 gpointer CreateThread(WapiSecurityAttributes *security G_GNUC_UNUSED, guint32 stacksize,
316                       WapiThreadStart start, gpointer param, guint32 create,
317                       gsize *tid) 
318 {
319         struct _WapiHandle_thread thread_handle = {0}, *thread_handle_p;
320         pthread_attr_t attr;
321         gpointer handle;
322         gboolean ok;
323         int ret;
324         int thr_ret;
325         int i, unrefs = 0;
326         gpointer ct_ret = NULL;
327         
328         mono_once (&thread_hash_once, thread_hash_init);
329         mono_once (&thread_ops_once, thread_ops_init);
330         
331         if (start == NULL) {
332                 return(NULL);
333         }
334
335         thread_handle.state = THREAD_STATE_START;
336         thread_handle.owned_mutexes = g_ptr_array_new ();
337         thread_handle.create_flags = create;
338         thread_handle.start_routine = start;
339         thread_handle.start_arg = param;
340         
341         handle = _wapi_handle_new (WAPI_HANDLE_THREAD, &thread_handle);
342         if (handle == _WAPI_HANDLE_INVALID) {
343                 g_warning ("%s: error creating thread handle", __func__);
344                 SetLastError (ERROR_GEN_FAILURE);
345                 
346                 return (NULL);
347         }
348
349         pthread_cleanup_push ((void(*)(void *))_wapi_handle_unlock_handle,
350                               handle);
351         thr_ret = _wapi_handle_lock_handle (handle);
352         g_assert (thr_ret == 0);
353         
354         ok = _wapi_lookup_handle (handle, WAPI_HANDLE_THREAD,
355                                   (gpointer *)&thread_handle_p);
356         if (ok == FALSE) {
357                 g_warning ("%s: error looking up thread handle %p", __func__,
358                            handle);
359                 SetLastError (ERROR_GEN_FAILURE);
360                 
361                 goto cleanup;
362         }
363
364         /* Hold a reference while the thread is active, because we use
365          * the handle to store thread exit information
366          */
367         _wapi_handle_ref (handle);
368         
369         /* Set a 2M stack size.  This is the default on Linux, but BSD
370          * needs it.  (The original bug report from Martin Dvorak <md@9ll.cz>
371          * set the size to 2M-4k.  I don't know why it's short by 4k, so
372          * I'm leaving it as 2M until I'm told differently.)
373          */
374         thr_ret = pthread_attr_init(&attr);
375         g_assert (thr_ret == 0);
376         
377         /* defaults of 2Mb for 32bits and 4Mb for 64bits */
378         /* temporarily changed to use 1 MB: this allows more threads
379          * to be used, as well as using less virtual memory and so
380          * more is available for the GC heap.
381          */
382         if (stacksize == 0){
383 #if HAVE_VALGRIND_MEMCHECK_H
384                 if (RUNNING_ON_VALGRIND) {
385                         stacksize = 1 << 20;
386                 } else {
387                         stacksize = (SIZEOF_VOID_P / 4) * 1024 * 1024;
388                 }
389 #else
390                 stacksize = (SIZEOF_VOID_P / 4) * 1024 * 1024;
391 #endif
392         }
393
394 #ifdef HAVE_PTHREAD_ATTR_SETSTACKSIZE
395         thr_ret = pthread_attr_setstacksize(&attr, stacksize);
396         g_assert (thr_ret == 0);
397 #endif
398
399         MONO_SEM_INIT (&thread_handle_p->suspend_sem, 0);
400         thread_handle_p->handle = handle;
401         
402         ret = pthread_create (&thread_handle_p->id, &attr,
403                               thread_start_routine, (void *)thread_handle_p);
404         if (ret != 0) {
405 #ifdef DEBUG
406                 g_message ("%s: Thread create error: %s", __func__,
407                            strerror(ret));
408 #endif
409
410                 /* Two, because of the reference we took above */
411                 unrefs = 2;
412                 
413                 goto cleanup;
414         }
415         ct_ret = handle;
416         
417 #ifdef DEBUG
418         g_message("%s: Started thread handle %p ID %ld", __func__, handle,
419                   thread_handle_p->id);
420 #endif
421         
422         if (tid != NULL) {
423 #ifdef PTHREAD_POINTER_ID
424                 /* Don't use GPOINTER_TO_UINT here, it can't cope with
425                  * sizeof(void *) > sizeof(uint) when a cast to uint
426                  * would overflow
427                  */
428                 *tid = (gsize)(thread_handle_p->id);
429 #else
430                 *tid = thread_handle_p->id;
431 #endif
432         }
433
434 cleanup:
435         thr_ret = _wapi_handle_unlock_handle (handle);
436         g_assert (thr_ret == 0);
437         pthread_cleanup_pop (0);
438         
439         /* Must not call _wapi_handle_unref() with the shared handles
440          * already locked
441          */
442         for (i = 0; i < unrefs; i++) {
443                 _wapi_handle_unref (handle);
444         }
445         
446         return(ct_ret);
447 }
448
449 /* The only time this function is called when tid != pthread_self ()
450  * is from OpenThread (), so we can fast-path most cases by just
451  * looking up the handle in TLS.  OpenThread () must cope with a NULL
452  * return and do a handle search in that case.
453  */
454 gpointer _wapi_thread_handle_from_id (pthread_t tid)
455 {
456         gpointer ret;
457
458         if (pthread_equal (tid, pthread_self ()) &&
459             (ret = pthread_getspecific (thread_hash_key)) != NULL) {
460                 /* We know the handle */
461
462 #ifdef DEBUG
463                 g_message ("%s: Returning %p for self thread %ld from TLS",
464                            __func__, ret, tid);
465 #endif
466                 
467                 return(ret);
468         }
469         
470 #ifdef DEBUG
471         g_message ("%s: Returning NULL for unknown or non-self thread %ld",
472                    __func__, tid);
473 #endif
474                 
475
476         return(NULL);
477 }
478
479 static gboolean find_thread_by_id (gpointer handle, gpointer user_data)
480 {
481         pthread_t tid = (pthread_t)user_data;
482         struct _WapiHandle_thread *thread_handle;
483         gboolean ok;
484         
485         /* Ignore threads that have already exited (ie they are signalled) */
486         if (_wapi_handle_issignalled (handle) == FALSE) {
487                 ok = _wapi_lookup_handle (handle, WAPI_HANDLE_THREAD,
488                                           (gpointer *)&thread_handle);
489                 if (ok == FALSE) {
490                         /* It's possible that the handle has vanished
491                          * during the _wapi_search_handle before it
492                          * gets here, so don't spam the console with
493                          * warnings.
494                          */
495                         return(FALSE);
496                 }
497                 
498 #ifdef DEBUG
499                 g_message ("%s: looking at thread %ld from process %d", __func__, thread_handle->id, 0);
500 #endif
501
502                 if (pthread_equal (thread_handle->id, tid)) {
503 #ifdef DEBUG
504                         g_message ("%s: found the thread we are looking for",
505                                    __func__);
506 #endif
507                         return(TRUE);
508                 }
509         }
510         
511 #ifdef DEBUG
512         g_message ("%s: not found %ld, returning FALSE", __func__, tid);
513 #endif
514         
515         return(FALSE);
516 }
517
518 /* NB tid is 32bit in MS API, but we need 64bit on amd64 and s390x
519  * (and probably others)
520  */
521 gpointer OpenThread (guint32 access G_GNUC_UNUSED, gboolean inherit G_GNUC_UNUSED, gsize tid)
522 {
523         gpointer ret=NULL;
524         
525         mono_once (&thread_hash_once, thread_hash_init);
526         mono_once (&thread_ops_once, thread_ops_init);
527         
528 #ifdef DEBUG
529         g_message ("%s: looking up thread %"G_GSIZE_FORMAT, __func__, tid);
530 #endif
531
532         ret = _wapi_thread_handle_from_id ((pthread_t)tid);
533         if (ret == NULL) {
534                 /* We need to search for this thread */
535                 ret = _wapi_search_handle (WAPI_HANDLE_THREAD, find_thread_by_id, (gpointer)tid, NULL, FALSE/*TRUE*/);  /* FIXME: have a proper look at this, me might not need to set search_shared = TRUE */
536         } else {
537                 /* if _wapi_search_handle() returns a found handle, it
538                  * refs it itself
539                  */
540                 _wapi_handle_ref (ret);
541         }
542         
543 #ifdef DEBUG
544         g_message ("%s: returning thread handle %p", __func__, ret);
545 #endif
546         
547         return(ret);
548 }
549
550 /**
551  * ExitThread:
552  * @exitcode: Sets the thread's exit code, which can be read from
553  * another thread with GetExitCodeThread().
554  *
555  * Terminates the calling thread.  A thread can also exit by returning
556  * from its start function. When the last thread in a process
557  * terminates, the process itself terminates.
558  */
559 void ExitThread(guint32 exitcode)
560 {
561         gpointer thread = _wapi_thread_handle_from_id (pthread_self ());
562         
563         if (thread != NULL) {
564                 thread_exit(exitcode, thread);
565         } else {
566                 /* Just blow this thread away */
567                 pthread_exit (NULL);
568         }
569 }
570
571 /**
572  * GetExitCodeThread:
573  * @handle: The thread handle to query
574  * @exitcode: The thread @handle exit code is stored here
575  *
576  * Finds the exit code of @handle, and stores it in @exitcode.  If the
577  * thread @handle is still running, the value stored is %STILL_ACTIVE.
578  *
579  * Return value: %TRUE, or %FALSE on error.
580  */
581 gboolean GetExitCodeThread(gpointer handle, guint32 *exitcode)
582 {
583         struct _WapiHandle_thread *thread_handle;
584         gboolean ok;
585         
586         ok = _wapi_lookup_handle (handle, WAPI_HANDLE_THREAD,
587                                   (gpointer *)&thread_handle);
588         if (ok == FALSE) {
589                 g_warning ("%s: error looking up thread handle %p", __func__,
590                            handle);
591                 return (FALSE);
592         }
593         
594 #ifdef DEBUG
595         g_message ("%s: Finding exit status for thread handle %p id %ld",
596                    __func__, handle, thread_handle->id);
597 #endif
598
599         if (exitcode == NULL) {
600 #ifdef DEBUG
601                 g_message ("%s: Nowhere to store exit code", __func__);
602 #endif
603                 return(FALSE);
604         }
605         
606         if (thread_handle->state != THREAD_STATE_EXITED) {
607 #ifdef DEBUG
608                 g_message ("%s: Thread still active (state %d, exited is %d)",
609                            __func__, thread_handle->state,
610                            THREAD_STATE_EXITED);
611 #endif
612                 *exitcode = STILL_ACTIVE;
613                 return(TRUE);
614         }
615         
616         *exitcode = thread_handle->exitstatus;
617         
618         return(TRUE);
619 }
620
621 /**
622  * GetCurrentThreadId:
623  *
624  * Looks up the thread ID of the current thread.  This ID can be
625  * passed to OpenThread() to create a new handle on this thread.
626  *
627  * Return value: the thread ID.  NB this is defined as DWORD (ie 32
628  * bit) in the MS API, but we need to cope with 64 bit IDs for s390x
629  * and amd64.  This doesn't really break the API, it just embraces and
630  * extends it on 64bit platforms :)
631  */
632 gsize GetCurrentThreadId(void)
633 {
634         pthread_t tid = pthread_self();
635         
636 #ifdef PTHREAD_POINTER_ID
637         /* Don't use GPOINTER_TO_UINT here, it can't cope with
638          * sizeof(void *) > sizeof(uint) when a cast to uint would
639          * overflow
640          */
641         return((gsize)tid);
642 #else
643         return(tid);
644 #endif
645 }
646
647 static gpointer thread_attach(gsize *tid)
648 {
649         struct _WapiHandle_thread thread_handle = {0}, *thread_handle_p;
650         gpointer handle;
651         gboolean ok;
652         int thr_ret;
653         
654         mono_once (&thread_hash_once, thread_hash_init);
655         mono_once (&thread_ops_once, thread_ops_init);
656
657         thread_handle.state = THREAD_STATE_START;
658         thread_handle.owned_mutexes = g_ptr_array_new ();
659
660         handle = _wapi_handle_new (WAPI_HANDLE_THREAD, &thread_handle);
661         if (handle == _WAPI_HANDLE_INVALID) {
662                 g_warning ("%s: error creating thread handle", __func__);
663                 
664                 SetLastError (ERROR_GEN_FAILURE);
665                 return (NULL);
666         }
667
668         pthread_cleanup_push ((void(*)(void *))_wapi_handle_unlock_handle,
669                               handle);
670         thr_ret = _wapi_handle_lock_handle (handle);
671         g_assert (thr_ret == 0);
672         
673         ok = _wapi_lookup_handle (handle, WAPI_HANDLE_THREAD,
674                                   (gpointer *)&thread_handle_p);
675         if (ok == FALSE) {
676                 g_warning ("%s: error looking up thread handle %p", __func__,
677                            handle);
678                 
679                 SetLastError (ERROR_GEN_FAILURE);
680                 goto cleanup;
681         }
682
683         /* Hold a reference while the thread is active, because we use
684          * the handle to store thread exit information
685          */
686         _wapi_handle_ref (handle);
687
688         /* suspend_sem is not used for attached threads, but
689          * thread_exit() might try to destroy it
690          */
691         MONO_SEM_INIT (&thread_handle_p->suspend_sem, 0);
692         thread_handle_p->handle = handle;
693         thread_handle_p->id = pthread_self ();
694
695         thr_ret = pthread_setspecific (thread_hash_key, (void *)handle);
696         g_assert (thr_ret == 0);
697
698         thr_ret = pthread_setspecific (thread_attached_key, (void *)handle);
699         g_assert (thr_ret == 0);
700         
701 #ifdef DEBUG
702         g_message("%s: Attached thread handle %p ID %ld", __func__, handle,
703                   thread_handle_p->id);
704 #endif
705
706         if (tid != NULL) {
707 #ifdef PTHREAD_POINTER_ID
708                 /* Don't use GPOINTER_TO_UINT here, it can't cope with
709                  * sizeof(void *) > sizeof(uint) when a cast to uint
710                  * would overflow
711                  */
712                 *tid = (gsize)(thread_handle_p->id);
713 #else
714                 *tid = thread_handle_p->id;
715 #endif
716         }
717
718 cleanup:
719         thr_ret = _wapi_handle_unlock_handle (handle);
720         g_assert (thr_ret == 0);
721         pthread_cleanup_pop (0);
722         
723         return(handle);
724 }
725
726 gpointer _wapi_thread_duplicate ()
727 {
728         gpointer ret = NULL;
729         
730         mono_once (&thread_hash_once, thread_hash_init);
731         mono_once (&thread_ops_once, thread_ops_init);
732         
733         ret = _wapi_thread_handle_from_id (pthread_self ());
734         if (!ret) {
735                 ret = thread_attach (NULL);
736         } else {
737                 _wapi_handle_ref (ret);
738         }
739         
740         return(ret);
741 }
742
743 /**
744  * GetCurrentThread:
745  *
746  * Looks up the handle associated with the current thread.  Under
747  * Windows this is a pseudohandle, and must be duplicated with
748  * DuplicateHandle() for some operations.
749  *
750  * Return value: The current thread handle, or %NULL on failure.
751  * (Unknown whether Windows has a possible failure here.  It may be
752  * necessary to implement the pseudohandle-constant behaviour).
753  */
754 gpointer GetCurrentThread(void)
755 {
756         mono_once(&thread_hash_once, thread_hash_init);
757         mono_once (&thread_ops_once, thread_ops_init);
758         
759         return(_WAPI_THREAD_CURRENT);
760 }
761
762 /**
763  * ResumeThread:
764  * @handle: the thread handle to resume
765  *
766  * Decrements the suspend count of thread @handle. A thread can only
767  * run if its suspend count is zero.
768  *
769  * Return value: the previous suspend count, or 0xFFFFFFFF on error.
770  */
771 guint32 ResumeThread(gpointer handle)
772 {
773         struct _WapiHandle_thread *thread_handle;
774         gboolean ok;
775         
776         ok = _wapi_lookup_handle (handle, WAPI_HANDLE_THREAD,
777                                   (gpointer *)&thread_handle);
778         if (ok == FALSE) {
779                 g_warning ("%s: error looking up thread handle %p", __func__,
780                            handle);
781                 
782                 return (0xFFFFFFFF);
783         }
784
785         /* This is still a kludge that only copes with starting a
786          * thread that was suspended on create, so don't bother with
787          * the suspend count crap yet
788          */
789         _wapi_thread_resume (thread_handle);
790         return(0xFFFFFFFF);
791 }
792
793 /**
794  * SuspendThread:
795  * @handle: the thread handle to suspend
796  *
797  * Increments the suspend count of thread @handle. A thread can only
798  * run if its suspend count is zero.
799  *
800  * Return value: the previous suspend count, or 0xFFFFFFFF on error.
801  */
802 guint32 SuspendThread(gpointer handle)
803 {
804         return(0xFFFFFFFF);
805 }
806
807 /*
808  * We assume here that TLS_MINIMUM_AVAILABLE is less than
809  * PTHREAD_KEYS_MAX, allowing enough overhead for a few TLS keys for
810  * library usage.
811  *
812  * Currently TLS_MINIMUM_AVAILABLE is 64 and _POSIX_THREAD_KEYS_MAX
813  * (the minimum value for PTHREAD_KEYS_MAX) is 128, so we should be
814  * fine.
815  */
816
817 static pthread_key_t TLS_keys[TLS_MINIMUM_AVAILABLE];
818 static gboolean TLS_used[TLS_MINIMUM_AVAILABLE]={FALSE};
819 static guint32 TLS_spinlock=0;
820
821 guint32
822 mono_pthread_key_for_tls (guint32 idx)
823 {
824         return (guint32)TLS_keys [idx];
825 }
826
827 /**
828  * TlsAlloc:
829  *
830  * Allocates a Thread Local Storage (TLS) index.  Any thread in the
831  * same process can use this index to store and retrieve values that
832  * are local to that thread.
833  *
834  * Return value: The index value, or %TLS_OUT_OF_INDEXES if no index
835  * is available.
836  */
837 guint32 TlsAlloc(void)
838 {
839         guint32 i;
840         int thr_ret;
841         
842         MONO_SPIN_LOCK (TLS_spinlock);
843         
844         for(i=0; i<TLS_MINIMUM_AVAILABLE; i++) {
845                 if(TLS_used[i]==FALSE) {
846                         TLS_used[i]=TRUE;
847                         thr_ret = pthread_key_create(&TLS_keys[i], NULL);
848                         g_assert (thr_ret == 0);
849
850                         MONO_SPIN_UNLOCK (TLS_spinlock);
851         
852 #ifdef TLS_DEBUG
853                         g_message ("%s: returning key %d", __func__, i);
854 #endif
855                         
856                         return(i);
857                 }
858         }
859
860         MONO_SPIN_UNLOCK (TLS_spinlock);
861         
862 #ifdef TLS_DEBUG
863         g_message ("%s: out of indices", __func__);
864 #endif
865                         
866         
867         return(TLS_OUT_OF_INDEXES);
868 }
869
870 #define MAKE_GC_ID(idx) (GUINT_TO_POINTER((idx)|(GetCurrentThreadId()<<8)))
871
872 /**
873  * TlsFree:
874  * @idx: The TLS index to free
875  *
876  * Releases a TLS index, making it available for reuse.  This call
877  * will delete any TLS data stored under index @idx in all threads.
878  *
879  * Return value: %TRUE on success, %FALSE otherwise.
880  */
881 gboolean TlsFree(guint32 idx)
882 {
883         int thr_ret;
884         
885 #ifdef TLS_DEBUG
886         g_message ("%s: freeing key %d", __func__, idx);
887 #endif
888
889         MONO_SPIN_LOCK (TLS_spinlock);
890         
891         if(TLS_used[idx]==FALSE) {
892                 MONO_SPIN_UNLOCK (TLS_spinlock);
893
894                 return(FALSE);
895         }
896         
897         TLS_used[idx]=FALSE;
898         thr_ret = pthread_key_delete(TLS_keys[idx]);
899         g_assert (thr_ret == 0);
900         
901         MONO_SPIN_UNLOCK (TLS_spinlock);
902         
903         return(TRUE);
904 }
905
906 /**
907  * TlsGetValue:
908  * @idx: The TLS index to retrieve
909  *
910  * Retrieves the TLS data stored under index @idx.
911  *
912  * Return value: The value stored in the TLS index @idx in the current
913  * thread, or %NULL on error.  As %NULL can be a valid return value,
914  * in this case GetLastError() returns %ERROR_SUCCESS.
915  */
916 gpointer TlsGetValue(guint32 idx)
917 {
918         gpointer ret;
919         
920 #ifdef TLS_DEBUG
921         g_message ("%s: looking up key %d", __func__, idx);
922 #endif
923         
924         ret=pthread_getspecific(TLS_keys[idx]);
925
926 #ifdef TLS_DEBUG
927         g_message ("%s: returning %p", __func__, ret);
928 #endif
929         
930         return(ret);
931 }
932
933 /**
934  * TlsSetValue:
935  * @idx: The TLS index to store
936  * @value: The value to store under index @idx
937  *
938  * Stores @value at TLS index @idx.
939  *
940  * Return value: %TRUE on success, %FALSE otherwise.
941  */
942 gboolean TlsSetValue(guint32 idx, gpointer value)
943 {
944         int ret;
945
946 #ifdef TLS_DEBUG
947         g_message ("%s: setting key %d to %p", __func__, idx, value);
948 #endif
949         
950         MONO_SPIN_LOCK (TLS_spinlock);
951         
952         if(TLS_used[idx]==FALSE) {
953 #ifdef TLS_DEBUG
954                 g_message ("%s: key %d unused", __func__, idx);
955 #endif
956
957                 MONO_SPIN_UNLOCK (TLS_spinlock);
958
959                 return(FALSE);
960         }
961         
962         ret=pthread_setspecific(TLS_keys[idx], value);
963         if(ret!=0) {
964 #ifdef TLS_DEBUG
965                 g_message ("%s: pthread_setspecific error: %s", __func__,
966                            strerror (ret));
967 #endif
968
969                 MONO_SPIN_UNLOCK (TLS_spinlock);
970
971                 return(FALSE);
972         }
973         
974         MONO_SPIN_UNLOCK (TLS_spinlock);
975         
976         return(TRUE);
977 }
978
979 /**
980  * SleepEx:
981  * @ms: The time in milliseconds to suspend for
982  * @alertable: if TRUE, the wait can be interrupted by an APC call
983  *
984  * Suspends execution of the current thread for @ms milliseconds.  A
985  * value of zero causes the thread to relinquish its time slice.  A
986  * value of %INFINITE causes an infinite delay.
987  */
988 guint32 SleepEx(guint32 ms, gboolean alertable)
989 {
990         struct timespec req, rem;
991         int ms_quot, ms_rem;
992         int ret;
993         gpointer current_thread = NULL;
994         
995 #ifdef DEBUG
996         g_message("%s: Sleeping for %d ms", __func__, ms);
997 #endif
998
999         if (alertable) {
1000                 current_thread = _wapi_thread_handle_from_id (pthread_self ());
1001                 if (current_thread == NULL) {
1002                         SetLastError (ERROR_INVALID_HANDLE);
1003                         return(WAIT_FAILED);
1004                 }
1005                 
1006                 if (_wapi_thread_apc_pending (current_thread)) {
1007                         _wapi_thread_dispatch_apc_queue (current_thread);
1008                         return WAIT_IO_COMPLETION;
1009                 }
1010         }
1011         
1012         if(ms==0) {
1013                 sched_yield();
1014                 return 0;
1015         }
1016         
1017         /* FIXME: check for INFINITE and sleep forever */
1018         ms_quot = ms / 1000;
1019         ms_rem = ms % 1000;
1020         
1021         req.tv_sec=ms_quot;
1022         req.tv_nsec=ms_rem*1000000;
1023         
1024 again:
1025         ret=nanosleep(&req, &rem);
1026
1027         if (alertable && _wapi_thread_apc_pending (current_thread)) {
1028                 _wapi_thread_dispatch_apc_queue (current_thread);
1029                 return WAIT_IO_COMPLETION;
1030         }
1031         
1032         if(ret==-1) {
1033                 /* Sleep interrupted with rem time remaining */
1034 #ifdef DEBUG
1035                 guint32 rems=rem.tv_sec*1000 + rem.tv_nsec/1000000;
1036                 
1037                 g_message("%s: Still got %d ms to go", __func__, rems);
1038 #endif
1039                 req=rem;
1040                 goto again;
1041         }
1042
1043         return 0;
1044 }
1045
1046 void Sleep(guint32 ms)
1047 {
1048         SleepEx(ms, FALSE);
1049 }
1050
1051 gboolean _wapi_thread_cur_apc_pending (void)
1052 {
1053         gpointer thread = _wapi_thread_handle_from_id (pthread_self ());
1054         
1055         if (thread == NULL) {
1056                 SetLastError (ERROR_INVALID_HANDLE);
1057                 return(FALSE);
1058         }
1059         
1060         return(_wapi_thread_apc_pending (thread));
1061 }
1062
1063 gboolean _wapi_thread_apc_pending (gpointer handle)
1064 {
1065         struct _WapiHandle_thread *thread;
1066         gboolean ok;
1067         
1068         ok = _wapi_lookup_handle (handle, WAPI_HANDLE_THREAD,
1069                                   (gpointer *)&thread);
1070         if (ok == FALSE) {
1071 #ifdef DEBUG
1072                 /* This might happen at process shutdown, as all
1073                  * thread handles are forcibly closed.  If a thread
1074                  * still has an alertable wait the final
1075                  * _wapi_thread_apc_pending check will probably fail
1076                  * to find the handle
1077                  */
1078                 g_warning ("%s: error looking up thread handle %p", __func__,
1079                            handle);
1080 #endif
1081                 return (FALSE);
1082         }
1083         
1084         return(thread->has_apc || thread->wait_handle == INTERRUPTION_REQUESTED_HANDLE);
1085 }
1086
1087 gboolean _wapi_thread_dispatch_apc_queue (gpointer handle)
1088 {
1089         /* We don't support calling APC functions */
1090         struct _WapiHandle_thread *thread;
1091         gboolean ok;
1092         
1093         ok = _wapi_lookup_handle (handle, WAPI_HANDLE_THREAD,
1094                                   (gpointer *)&thread);
1095         g_assert (ok);
1096
1097         thread->has_apc = FALSE;
1098
1099         return(TRUE);
1100 }
1101
1102 /*
1103  * In this implementation, APC_CALLBACK is ignored.
1104  * if HANDLE refers to the current thread, the only effect this function has 
1105  * that if called from a signal handler, and the thread was waiting when receiving 
1106  * the signal, the wait will be broken after the signal handler returns.
1107  * In this case, this function is async-signal-safe.
1108  */
1109 guint32 QueueUserAPC (WapiApcProc apc_callback, gpointer handle, 
1110                       gpointer param)
1111 {
1112         struct _WapiHandle_thread *thread_handle;
1113         gboolean ok;
1114         
1115         ok = _wapi_lookup_handle (handle, WAPI_HANDLE_THREAD,
1116                                   (gpointer *)&thread_handle);
1117         if (ok == FALSE) {
1118                 g_warning ("%s: error looking up thread handle %p", __func__,
1119                            handle);
1120                 return (0);
1121         }
1122
1123         g_assert (thread_handle->id == GetCurrentThreadId ());
1124         /* No locking/memory barriers are needed here */
1125         thread_handle->has_apc = TRUE;
1126         return(1);
1127 }
1128
1129 /*
1130  * wapi_interrupt_thread:
1131  *
1132  *   This is not part of the WIN32 API.
1133  * The state of the thread handle HANDLE is set to 'interrupted' which means that
1134  * if the thread calls one of the WaitFor functions, the function will return with 
1135  * WAIT_IO_COMPLETION instead of waiting. Also, if the thread was waiting when
1136  * this function was called, the wait will be broken.
1137  * It is possible that the wait functions return WAIT_IO_COMPLETION, but the
1138  * target thread didn't receive the interrupt signal yet, in this case it should
1139  * call the wait function again. This essentially means that the target thread will
1140  * busy wait until it is ready to process the interruption.
1141  * FIXME: get rid of QueueUserAPC and thread->has_apc, SleepEx seems to require it.
1142  */
1143 void wapi_interrupt_thread (gpointer thread_handle)
1144 {
1145         struct _WapiHandle_thread *thread;
1146         gboolean ok;
1147         gpointer prev_handle, wait_handle;
1148         guint32 idx;
1149         pthread_cond_t *cond;
1150         mono_mutex_t *mutex;
1151         
1152         ok = _wapi_lookup_handle (thread_handle, WAPI_HANDLE_THREAD,
1153                                   (gpointer *)&thread);
1154         g_assert (ok);
1155
1156         while (TRUE) {
1157                 wait_handle = thread->wait_handle;
1158
1159                 /* 
1160                  * Atomically obtain the handle the thread is waiting on, and
1161                  * change it to a flag value.
1162                  */
1163                 prev_handle = InterlockedCompareExchangePointer (&thread->wait_handle,
1164                                                                                                                  INTERRUPTION_REQUESTED_HANDLE, wait_handle);
1165                 if (prev_handle == INTERRUPTION_REQUESTED_HANDLE)
1166                         /* Already interrupted */
1167                         return;
1168                 if (prev_handle == wait_handle)
1169                         break;
1170
1171                 /* Try again */
1172         }
1173
1174         WAIT_DEBUG (printf ("%p: state -> INTERRUPTED.\n", thread_handle->id););
1175
1176         if (!wait_handle)
1177                 /* Not waiting */
1178                 return;
1179
1180         /* If we reach here, then wait_handle is set to the flag value, 
1181          * which means that the target thread is either
1182          * - before the first CAS in timedwait, which means it won't enter the
1183          * wait.
1184          * - it is after the first CAS, so it is already waiting, or it will 
1185          * enter the wait, and it will be interrupted by the broadcast.
1186          */
1187         idx = GPOINTER_TO_UINT(wait_handle);
1188         cond = &_WAPI_PRIVATE_HANDLES(idx).signal_cond;
1189         mutex = &_WAPI_PRIVATE_HANDLES(idx).signal_mutex;
1190
1191         mono_mutex_lock (mutex);
1192         mono_cond_broadcast (cond);
1193         mono_mutex_unlock (mutex);
1194
1195         /* ref added by set_wait_handle */
1196         _wapi_handle_unref (wait_handle);
1197 }
1198
1199 /*
1200  * wapi_clear_interruption:
1201  *
1202  *   This is not part of the WIN32 API. 
1203  * Clear the 'interrupted' state of the calling thread.
1204  */
1205 void wapi_clear_interruption (void)
1206 {
1207         struct _WapiHandle_thread *thread;
1208         gboolean ok;
1209         gpointer prev_handle;
1210         gpointer thread_handle;
1211
1212         thread_handle = OpenThread (0, 0, GetCurrentThreadId ());
1213         ok = _wapi_lookup_handle (thread_handle, WAPI_HANDLE_THREAD,
1214                                                           (gpointer *)&thread);
1215         g_assert (ok);
1216
1217         prev_handle = InterlockedCompareExchangePointer (&thread->wait_handle,
1218                                                                                                          NULL, INTERRUPTION_REQUESTED_HANDLE);
1219         if (prev_handle == INTERRUPTION_REQUESTED_HANDLE)
1220                 WAIT_DEBUG (printf ("%p: state -> NORMAL.\n", GetCurrentThreadId ()););
1221
1222         _wapi_handle_unref (thread_handle);
1223 }
1224
1225 char* wapi_current_thread_desc ()
1226 {
1227         struct _WapiHandle_thread *thread;
1228         int i;
1229         gboolean ok;
1230         gpointer handle;
1231         gpointer thread_handle;
1232         GString* text;
1233         char *res;
1234
1235         thread_handle = OpenThread (0, 0, GetCurrentThreadId ());
1236         ok = _wapi_lookup_handle (thread_handle, WAPI_HANDLE_THREAD,
1237                                                           (gpointer *)&thread);
1238         if (!ok)
1239                 return g_strdup_printf ("thread handle %p state : lookup failure", thread_handle);
1240
1241         handle = thread->wait_handle;
1242         text = g_string_new (0);
1243         g_string_append_printf (text, "thread handle %p state : ", thread_handle);
1244
1245         if (!handle)
1246                 g_string_append_printf (text, "not waiting");
1247         else if (handle == INTERRUPTION_REQUESTED_HANDLE)
1248                 g_string_append_printf (text, "interrupted state");
1249         else
1250                 g_string_append_printf (text, "waiting on %p : %s ", handle, _wapi_handle_typename[_wapi_handle_type (handle)]);
1251         g_string_append_printf (text, " owns (");
1252         for (i = 0; i < thread->owned_mutexes->len; i++) {
1253                 gpointer mutex = g_ptr_array_index (thread->owned_mutexes, i);
1254                 if (i > 0)
1255                         g_string_append_printf (text, ", %p", mutex);
1256                 else
1257                         g_string_append_printf (text, "%p", mutex);
1258         }
1259         g_string_append_printf (text, ")");
1260
1261         res = text->str;
1262         g_string_free (text, FALSE);
1263         return res;
1264 }
1265
1266 /**
1267  * wapi_thread_set_wait_handle:
1268  *
1269  *   Set the wait handle for the current thread to HANDLE. Return TRUE on success, FALSE
1270  * if the thread is in interrupted state, and cannot start waiting.
1271  */
1272 gboolean wapi_thread_set_wait_handle (gpointer handle)
1273 {
1274         struct _WapiHandle_thread *thread;
1275         gboolean ok;
1276         gpointer prev_handle;
1277         gpointer thread_handle;
1278
1279         thread_handle = OpenThread (0, 0, GetCurrentThreadId ());
1280         ok = _wapi_lookup_handle (thread_handle, WAPI_HANDLE_THREAD,
1281                                                           (gpointer *)&thread);
1282         g_assert (ok);
1283
1284         prev_handle = InterlockedCompareExchangePointer (&thread->wait_handle,
1285                                                                                                          handle, NULL);
1286         _wapi_handle_unref (thread_handle);
1287
1288         if (prev_handle == NULL) {
1289                 /* thread->wait_handle acts as an additional reference to the handle */
1290                 _wapi_handle_ref (handle);
1291
1292                 WAIT_DEBUG (printf ("%p: state -> WAITING.\n", GetCurrentThreadId ()););
1293         } else {
1294                 g_assert (prev_handle == INTERRUPTION_REQUESTED_HANDLE);
1295                 WAIT_DEBUG (printf ("%p: unable to set state to WAITING.\n", GetCurrentThreadId ()););
1296         }
1297
1298         return prev_handle == NULL;
1299 }
1300
1301 /**
1302  * wapi_thread_clear_wait_handle:
1303  *
1304  *   Clear the wait handle of the current thread.
1305  */
1306 void wapi_thread_clear_wait_handle (gpointer handle)
1307 {
1308         struct _WapiHandle_thread *thread;
1309         gboolean ok;
1310         gpointer prev_handle;
1311         gpointer thread_handle;
1312
1313         thread_handle = OpenThread (0, 0, GetCurrentThreadId ());
1314         ok = _wapi_lookup_handle (thread_handle, WAPI_HANDLE_THREAD,
1315                                                           (gpointer *)&thread);
1316         g_assert (ok);
1317
1318         prev_handle = InterlockedCompareExchangePointer (&thread->wait_handle,
1319                                                                                                          NULL, handle);
1320
1321         if (prev_handle == handle) {
1322                 _wapi_handle_unref (handle);
1323                 WAIT_DEBUG (printf ("%p: state -> NORMAL.\n", GetCurrentThreadId ()););
1324         } else {
1325                 g_assert (prev_handle == INTERRUPTION_REQUESTED_HANDLE);
1326                 WAIT_DEBUG (printf ("%p: finished waiting.\n", GetCurrentThreadId ()););
1327         }
1328
1329         _wapi_handle_unref (thread_handle);
1330 }
1331
1332 void _wapi_thread_own_mutex (gpointer mutex)
1333 {
1334         struct _WapiHandle_thread *thread_handle;
1335         gboolean ok;
1336         gpointer thread;
1337         
1338         thread = _wapi_thread_handle_from_id (pthread_self ());
1339         if (thread == NULL) {
1340                 g_warning ("%s: error looking up thread by ID", __func__);
1341                 return;
1342         }
1343
1344         ok = _wapi_lookup_handle (thread, WAPI_HANDLE_THREAD,
1345                                   (gpointer *)&thread_handle);
1346         if (ok == FALSE) {
1347                 g_warning ("%s: error looking up thread handle %p", __func__,
1348                            thread);
1349                 return;
1350         }
1351
1352         _wapi_handle_ref (mutex);
1353         
1354         g_ptr_array_add (thread_handle->owned_mutexes, mutex);
1355 }
1356
1357 void _wapi_thread_disown_mutex (gpointer mutex)
1358 {
1359         struct _WapiHandle_thread *thread_handle;
1360         gboolean ok;
1361         gpointer thread;
1362
1363         thread = _wapi_thread_handle_from_id (pthread_self ());
1364         if (thread == NULL) {
1365                 g_warning ("%s: error looking up thread by ID", __func__);
1366                 return;
1367         }
1368
1369         ok = _wapi_lookup_handle (thread, WAPI_HANDLE_THREAD,
1370                                   (gpointer *)&thread_handle);
1371         if (ok == FALSE) {
1372                 g_warning ("%s: error looking up thread handle %p", __func__,
1373                            thread);
1374                 return;
1375         }
1376
1377         _wapi_handle_unref (mutex);
1378         
1379         g_ptr_array_remove (thread_handle->owned_mutexes, mutex);
1380 }