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