do not check order sequence if option /order was not used
[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/mono-mutex.h>
29 #include <mono/io-layer/thread-private.h>
30 #include <mono/io-layer/mutex-private.h>
31 #include <mono/io-layer/atomic.h>
32
33 #include <mono/utils/mono-threads.h>
34 #include <mono/utils/gc_wrapper.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         thr_ret = mono_gc_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                 mono_gc_pthread_exit (NULL);
274         }
275
276         DEBUG ("%s: started thread id %ld", __func__, thread->id);
277
278         /* We set it again here since passing &thread->id to pthread_create is racy
279            as the thread can start running before the value is set.*/
280         thread->id = pthread_self ();
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 PTHREAD_STACK_MIN
395         if (stacksize < PTHREAD_STACK_MIN)
396                 stacksize = PTHREAD_STACK_MIN;
397 #endif
398
399 #ifdef HAVE_PTHREAD_ATTR_SETSTACKSIZE
400         thr_ret = pthread_attr_setstacksize(&attr, stacksize);
401         g_assert (thr_ret == 0);
402 #endif
403
404         MONO_SEM_INIT (&thread_handle_p->suspend_sem, 0);
405         thread_handle_p->handle = handle;
406         
407
408         ret = mono_threads_pthread_create (&thread_handle_p->id, &attr,
409                                                                            thread_start_routine, (void *)thread_handle_p);
410
411         if (ret != 0) {
412                 g_warning ("%s: Error creating native thread handle %s (%d)", __func__,
413                            strerror (ret), ret);
414                 SetLastError (ERROR_GEN_FAILURE);
415
416                 /* Two, because of the reference we took above */
417                 unrefs = 2;
418                 
419                 goto cleanup;
420         }
421         ct_ret = handle;
422         
423         DEBUG("%s: Started thread handle %p ID %ld", __func__, handle,
424                   thread_handle_p->id);
425         
426         if (tid != NULL) {
427 #ifdef PTHREAD_POINTER_ID
428                 /* Don't use GPOINTER_TO_UINT here, it can't cope with
429                  * sizeof(void *) > sizeof(uint) when a cast to uint
430                  * would overflow
431                  */
432                 *tid = (gsize)(thread_handle_p->id);
433 #else
434                 *tid = thread_handle_p->id;
435 #endif
436         }
437
438 cleanup:
439         thr_ret = _wapi_handle_unlock_handle (handle);
440         g_assert (thr_ret == 0);
441         pthread_cleanup_pop (0);
442         
443         /* Must not call _wapi_handle_unref() with the shared handles
444          * already locked
445          */
446         for (i = 0; i < unrefs; i++) {
447                 _wapi_handle_unref (handle);
448         }
449         
450         return(ct_ret);
451 }
452
453 /* The only time this function is called when tid != pthread_self ()
454  * is from OpenThread (), so we can fast-path most cases by just
455  * looking up the handle in TLS.  OpenThread () must cope with a NULL
456  * return and do a handle search in that case.
457  */
458 gpointer _wapi_thread_handle_from_id (pthread_t tid)
459 {
460         gpointer ret;
461
462         if (pthread_equal (tid, pthread_self ()) &&
463             (ret = pthread_getspecific (thread_hash_key)) != NULL) {
464                 /* We know the handle */
465
466                 DEBUG ("%s: Returning %p for self thread %ld from TLS",
467                            __func__, ret, tid);
468                 
469                 return(ret);
470         }
471         
472         DEBUG ("%s: Returning NULL for unknown or non-self thread %ld",
473                    __func__, tid);
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                 DEBUG ("%s: looking at thread %ld from process %d", __func__, thread_handle->id, 0);
499
500                 if (pthread_equal (thread_handle->id, tid)) {
501                         DEBUG ("%s: found the thread we are looking for",
502                                    __func__);
503                         return(TRUE);
504                 }
505         }
506         
507         DEBUG ("%s: not found %ld, returning FALSE", __func__, tid);
508         
509         return(FALSE);
510 }
511
512 /* NB tid is 32bit in MS API, but we need 64bit on amd64 and s390x
513  * (and probably others)
514  */
515 gpointer OpenThread (guint32 access G_GNUC_UNUSED, gboolean inherit G_GNUC_UNUSED, gsize tid)
516 {
517         gpointer ret=NULL;
518         
519         mono_once (&thread_hash_once, thread_hash_init);
520         mono_once (&thread_ops_once, thread_ops_init);
521         
522         DEBUG ("%s: looking up thread %"G_GSIZE_FORMAT, __func__, tid);
523
524         ret = _wapi_thread_handle_from_id ((pthread_t)tid);
525         if (ret == NULL) {
526                 /* We need to search for this thread */
527                 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 */
528         } else {
529                 /* if _wapi_search_handle() returns a found handle, it
530                  * refs it itself
531                  */
532                 _wapi_handle_ref (ret);
533         }
534         
535         DEBUG ("%s: returning thread handle %p", __func__, ret);
536         
537         return(ret);
538 }
539
540 /**
541  * ExitThread:
542  * @exitcode: Sets the thread's exit code, which can be read from
543  * another thread with GetExitCodeThread().
544  *
545  * Terminates the calling thread.  A thread can also exit by returning
546  * from its start function. When the last thread in a process
547  * terminates, the process itself terminates.
548  */
549 void ExitThread(guint32 exitcode)
550 {
551         gpointer thread = _wapi_thread_handle_from_id (pthread_self ());
552         
553         if (thread != NULL) {
554                 thread_exit(exitcode, thread);
555         } else {
556                 /* Just blow this thread away */
557                 mono_gc_pthread_exit (NULL);
558         }
559 }
560
561 /**
562  * GetExitCodeThread:
563  * @handle: The thread handle to query
564  * @exitcode: The thread @handle exit code is stored here
565  *
566  * Finds the exit code of @handle, and stores it in @exitcode.  If the
567  * thread @handle is still running, the value stored is %STILL_ACTIVE.
568  *
569  * Return value: %TRUE, or %FALSE on error.
570  */
571 gboolean GetExitCodeThread(gpointer handle, guint32 *exitcode)
572 {
573         struct _WapiHandle_thread *thread_handle;
574         gboolean ok;
575         
576         ok = _wapi_lookup_handle (handle, WAPI_HANDLE_THREAD,
577                                   (gpointer *)&thread_handle);
578         if (ok == FALSE) {
579                 g_warning ("%s: error looking up thread handle %p", __func__,
580                            handle);
581                 return (FALSE);
582         }
583         
584         DEBUG ("%s: Finding exit status for thread handle %p id %ld",
585                    __func__, handle, thread_handle->id);
586
587         if (exitcode == NULL) {
588                 DEBUG ("%s: Nowhere to store exit code", __func__);
589                 return(FALSE);
590         }
591         
592         if (thread_handle->state != THREAD_STATE_EXITED) {
593                 DEBUG ("%s: Thread still active (state %d, exited is %d)",
594                            __func__, thread_handle->state,
595                            THREAD_STATE_EXITED);
596                 *exitcode = STILL_ACTIVE;
597                 return(TRUE);
598         }
599         
600         *exitcode = thread_handle->exitstatus;
601         
602         return(TRUE);
603 }
604
605 /**
606  * GetCurrentThreadId:
607  *
608  * Looks up the thread ID of the current thread.  This ID can be
609  * passed to OpenThread() to create a new handle on this thread.
610  *
611  * Return value: the thread ID.  NB this is defined as DWORD (ie 32
612  * bit) in the MS API, but we need to cope with 64 bit IDs for s390x
613  * and amd64.  This doesn't really break the API, it just embraces and
614  * extends it on 64bit platforms :)
615  */
616 gsize GetCurrentThreadId(void)
617 {
618         pthread_t tid = pthread_self();
619         
620 #ifdef PTHREAD_POINTER_ID
621         /* Don't use GPOINTER_TO_UINT here, it can't cope with
622          * sizeof(void *) > sizeof(uint) when a cast to uint would
623          * overflow
624          */
625         return((gsize)tid);
626 #else
627         return(tid);
628 #endif
629 }
630
631 static gpointer thread_attach(gsize *tid)
632 {
633         struct _WapiHandle_thread thread_handle = {0}, *thread_handle_p;
634         gpointer handle;
635         gboolean ok;
636         int thr_ret;
637         
638         mono_once (&thread_hash_once, thread_hash_init);
639         mono_once (&thread_ops_once, thread_ops_init);
640
641         thread_handle.state = THREAD_STATE_START;
642         thread_handle.owned_mutexes = g_ptr_array_new ();
643
644         handle = _wapi_handle_new (WAPI_HANDLE_THREAD, &thread_handle);
645         if (handle == _WAPI_HANDLE_INVALID) {
646                 g_warning ("%s: error creating thread handle", __func__);
647                 
648                 SetLastError (ERROR_GEN_FAILURE);
649                 return (NULL);
650         }
651
652         pthread_cleanup_push ((void(*)(void *))_wapi_handle_unlock_handle,
653                               handle);
654         thr_ret = _wapi_handle_lock_handle (handle);
655         g_assert (thr_ret == 0);
656         
657         ok = _wapi_lookup_handle (handle, WAPI_HANDLE_THREAD,
658                                   (gpointer *)&thread_handle_p);
659         if (ok == FALSE) {
660                 g_warning ("%s: error looking up thread handle %p", __func__,
661                            handle);
662                 
663                 SetLastError (ERROR_GEN_FAILURE);
664                 goto cleanup;
665         }
666
667         /* Hold a reference while the thread is active, because we use
668          * the handle to store thread exit information
669          */
670         _wapi_handle_ref (handle);
671
672         /* suspend_sem is not used for attached threads, but
673          * thread_exit() might try to destroy it
674          */
675         MONO_SEM_INIT (&thread_handle_p->suspend_sem, 0);
676         thread_handle_p->handle = handle;
677         thread_handle_p->id = pthread_self ();
678
679         thr_ret = pthread_setspecific (thread_hash_key, (void *)handle);
680         g_assert (thr_ret == 0);
681
682         thr_ret = pthread_setspecific (thread_attached_key, (void *)handle);
683         g_assert (thr_ret == 0);
684         
685         DEBUG("%s: Attached thread handle %p ID %ld", __func__, handle,
686                   thread_handle_p->id);
687
688         if (tid != NULL) {
689 #ifdef PTHREAD_POINTER_ID
690                 /* Don't use GPOINTER_TO_UINT here, it can't cope with
691                  * sizeof(void *) > sizeof(uint) when a cast to uint
692                  * would overflow
693                  */
694                 *tid = (gsize)(thread_handle_p->id);
695 #else
696                 *tid = thread_handle_p->id;
697 #endif
698         }
699
700 cleanup:
701         thr_ret = _wapi_handle_unlock_handle (handle);
702         g_assert (thr_ret == 0);
703         pthread_cleanup_pop (0);
704         
705         return(handle);
706 }
707
708 gpointer _wapi_thread_duplicate ()
709 {
710         gpointer ret = NULL;
711         
712         mono_once (&thread_hash_once, thread_hash_init);
713         mono_once (&thread_ops_once, thread_ops_init);
714         
715         ret = _wapi_thread_handle_from_id (pthread_self ());
716         if (!ret) {
717                 ret = thread_attach (NULL);
718         } else {
719                 _wapi_handle_ref (ret);
720         }
721         
722         return(ret);
723 }
724
725 /**
726  * GetCurrentThread:
727  *
728  * Looks up the handle associated with the current thread.  Under
729  * Windows this is a pseudohandle, and must be duplicated with
730  * DuplicateHandle() for some operations.
731  *
732  * Return value: The current thread handle, or %NULL on failure.
733  * (Unknown whether Windows has a possible failure here.  It may be
734  * necessary to implement the pseudohandle-constant behaviour).
735  */
736 gpointer GetCurrentThread(void)
737 {
738         mono_once(&thread_hash_once, thread_hash_init);
739         mono_once (&thread_ops_once, thread_ops_init);
740         
741         return(_WAPI_THREAD_CURRENT);
742 }
743
744 /**
745  * ResumeThread:
746  * @handle: the thread handle to resume
747  *
748  * Decrements the suspend count of thread @handle. A thread can only
749  * run if its suspend count is zero.
750  *
751  * Return value: the previous suspend count, or 0xFFFFFFFF on error.
752  */
753 guint32 ResumeThread(gpointer handle)
754 {
755         struct _WapiHandle_thread *thread_handle;
756         gboolean ok;
757         
758         ok = _wapi_lookup_handle (handle, WAPI_HANDLE_THREAD,
759                                   (gpointer *)&thread_handle);
760         if (ok == FALSE) {
761                 g_warning ("%s: error looking up thread handle %p", __func__,
762                            handle);
763                 
764                 return (0xFFFFFFFF);
765         }
766
767         /* This is still a kludge that only copes with starting a
768          * thread that was suspended on create, so don't bother with
769          * the suspend count crap yet
770          */
771         _wapi_thread_resume (thread_handle);
772         return(0xFFFFFFFF);
773 }
774
775 /**
776  * SuspendThread:
777  * @handle: the thread handle to suspend
778  *
779  * Increments the suspend count of thread @handle. A thread can only
780  * run if its suspend count is zero.
781  *
782  * Return value: the previous suspend count, or 0xFFFFFFFF on error.
783  */
784 guint32 SuspendThread(gpointer handle)
785 {
786         return(0xFFFFFFFF);
787 }
788
789 /**
790  * SleepEx:
791  * @ms: The time in milliseconds to suspend for
792  * @alertable: if TRUE, the wait can be interrupted by an APC call
793  *
794  * Suspends execution of the current thread for @ms milliseconds.  A
795  * value of zero causes the thread to relinquish its time slice.  A
796  * value of %INFINITE causes an infinite delay.
797  */
798 guint32 SleepEx(guint32 ms, gboolean alertable)
799 {
800         struct timespec req, rem;
801         int ms_quot, ms_rem;
802         int ret;
803         gpointer current_thread = NULL;
804         
805         DEBUG("%s: Sleeping for %d ms", __func__, ms);
806
807         if (alertable) {
808                 current_thread = _wapi_thread_handle_from_id (pthread_self ());
809                 if (current_thread == NULL) {
810                         SetLastError (ERROR_INVALID_HANDLE);
811                         return(WAIT_FAILED);
812                 }
813                 
814                 if (_wapi_thread_apc_pending (current_thread)) {
815                         _wapi_thread_dispatch_apc_queue (current_thread);
816                         return WAIT_IO_COMPLETION;
817                 }
818         }
819         
820         if(ms==0) {
821                 sched_yield();
822                 return 0;
823         }
824         
825         /* FIXME: check for INFINITE and sleep forever */
826         ms_quot = ms / 1000;
827         ms_rem = ms % 1000;
828         
829         req.tv_sec=ms_quot;
830         req.tv_nsec=ms_rem*1000000;
831         
832 again:
833         memset (&rem, 0, sizeof (rem));
834         ret=nanosleep(&req, &rem);
835
836         if (alertable && _wapi_thread_apc_pending (current_thread)) {
837                 _wapi_thread_dispatch_apc_queue (current_thread);
838                 return WAIT_IO_COMPLETION;
839         }
840         
841         if(ret==-1) {
842                 /* Sleep interrupted with rem time remaining */
843 #ifdef DEBUG_ENABLED
844                 guint32 rems=rem.tv_sec*1000 + rem.tv_nsec/1000000;
845                 
846                 g_message("%s: Still got %d ms to go", __func__, rems);
847 #endif
848                 req=rem;
849                 goto again;
850         }
851
852         return 0;
853 }
854
855 void Sleep(guint32 ms)
856 {
857         SleepEx(ms, FALSE);
858 }
859
860 gboolean _wapi_thread_cur_apc_pending (void)
861 {
862         gpointer thread = _wapi_thread_handle_from_id (pthread_self ());
863         
864         if (thread == NULL) {
865                 SetLastError (ERROR_INVALID_HANDLE);
866                 return(FALSE);
867         }
868         
869         return(_wapi_thread_apc_pending (thread));
870 }
871
872 gboolean _wapi_thread_apc_pending (gpointer handle)
873 {
874         struct _WapiHandle_thread *thread;
875         gboolean ok;
876         
877         ok = _wapi_lookup_handle (handle, WAPI_HANDLE_THREAD,
878                                   (gpointer *)&thread);
879         if (ok == FALSE) {
880                 /* This might happen at process shutdown, as all
881                  * thread handles are forcibly closed.  If a thread
882                  * still has an alertable wait the final
883                  * _wapi_thread_apc_pending check will probably fail
884                  * to find the handle
885                  */
886                 DEBUG ("%s: error looking up thread handle %p", __func__,
887                            handle);
888                 return (FALSE);
889         }
890         
891         return(thread->has_apc || thread->wait_handle == INTERRUPTION_REQUESTED_HANDLE);
892 }
893
894 gboolean _wapi_thread_dispatch_apc_queue (gpointer handle)
895 {
896         /* We don't support calling APC functions */
897         struct _WapiHandle_thread *thread;
898         gboolean ok;
899         
900         ok = _wapi_lookup_handle (handle, WAPI_HANDLE_THREAD,
901                                   (gpointer *)&thread);
902         g_assert (ok);
903
904         thread->has_apc = FALSE;
905
906         return(TRUE);
907 }
908
909 /*
910  * In this implementation, APC_CALLBACK is ignored.
911  * if HANDLE refers to the current thread, the only effect this function has 
912  * that if called from a signal handler, and the thread was waiting when receiving 
913  * the signal, the wait will be broken after the signal handler returns.
914  * In this case, this function is async-signal-safe.
915  */
916 guint32 QueueUserAPC (WapiApcProc apc_callback, gpointer handle, 
917                       gpointer param)
918 {
919         struct _WapiHandle_thread *thread_handle;
920         gboolean ok;
921         
922         ok = _wapi_lookup_handle (handle, WAPI_HANDLE_THREAD,
923                                   (gpointer *)&thread_handle);
924         if (ok == FALSE) {
925                 g_warning ("%s: error looking up thread handle %p", __func__,
926                            handle);
927                 return (0);
928         }
929
930         g_assert (thread_handle->id == GetCurrentThreadId ());
931         /* No locking/memory barriers are needed here */
932         thread_handle->has_apc = TRUE;
933         return(1);
934 }
935
936 /*
937  * wapi_interrupt_thread:
938  *
939  *   This is not part of the WIN32 API.
940  * The state of the thread handle HANDLE is set to 'interrupted' which means that
941  * if the thread calls one of the WaitFor functions, the function will return with 
942  * WAIT_IO_COMPLETION instead of waiting. Also, if the thread was waiting when
943  * this function was called, the wait will be broken.
944  * It is possible that the wait functions return WAIT_IO_COMPLETION, but the
945  * target thread didn't receive the interrupt signal yet, in this case it should
946  * call the wait function again. This essentially means that the target thread will
947  * busy wait until it is ready to process the interruption.
948  * FIXME: get rid of QueueUserAPC and thread->has_apc, SleepEx seems to require it.
949  */
950 void wapi_interrupt_thread (gpointer thread_handle)
951 {
952         struct _WapiHandle_thread *thread;
953         gboolean ok;
954         gpointer prev_handle, wait_handle;
955         guint32 idx;
956         pthread_cond_t *cond;
957         mono_mutex_t *mutex;
958         
959         ok = _wapi_lookup_handle (thread_handle, WAPI_HANDLE_THREAD,
960                                   (gpointer *)&thread);
961         g_assert (ok);
962
963         while (TRUE) {
964                 wait_handle = thread->wait_handle;
965
966                 /* 
967                  * Atomically obtain the handle the thread is waiting on, and
968                  * change it to a flag value.
969                  */
970                 prev_handle = InterlockedCompareExchangePointer (&thread->wait_handle,
971                                                                                                                  INTERRUPTION_REQUESTED_HANDLE, wait_handle);
972                 if (prev_handle == INTERRUPTION_REQUESTED_HANDLE)
973                         /* Already interrupted */
974                         return;
975                 if (prev_handle == wait_handle)
976                         break;
977
978                 /* Try again */
979         }
980
981         WAIT_DEBUG (printf ("%p: state -> INTERRUPTED.\n", thread_handle->id););
982
983         if (!wait_handle)
984                 /* Not waiting */
985                 return;
986
987         /* If we reach here, then wait_handle is set to the flag value, 
988          * which means that the target thread is either
989          * - before the first CAS in timedwait, which means it won't enter the
990          * wait.
991          * - it is after the first CAS, so it is already waiting, or it will 
992          * enter the wait, and it will be interrupted by the broadcast.
993          */
994         idx = GPOINTER_TO_UINT(wait_handle);
995         cond = &_WAPI_PRIVATE_HANDLES(idx).signal_cond;
996         mutex = &_WAPI_PRIVATE_HANDLES(idx).signal_mutex;
997
998         mono_mutex_lock (mutex);
999         mono_cond_broadcast (cond);
1000         mono_mutex_unlock (mutex);
1001
1002         /* ref added by set_wait_handle */
1003         _wapi_handle_unref (wait_handle);
1004 }
1005
1006
1007 gpointer wapi_prepare_interrupt_thread (gpointer thread_handle)
1008 {
1009         struct _WapiHandle_thread *thread;
1010         gboolean ok;
1011         gpointer prev_handle, wait_handle;
1012         
1013         ok = _wapi_lookup_handle (thread_handle, WAPI_HANDLE_THREAD,
1014                                   (gpointer *)&thread);
1015         g_assert (ok);
1016
1017         while (TRUE) {
1018                 wait_handle = thread->wait_handle;
1019
1020                 /* 
1021                  * Atomically obtain the handle the thread is waiting on, and
1022                  * change it to a flag value.
1023                  */
1024                 prev_handle = InterlockedCompareExchangePointer (&thread->wait_handle,
1025                                                                                                                  INTERRUPTION_REQUESTED_HANDLE, wait_handle);
1026                 if (prev_handle == INTERRUPTION_REQUESTED_HANDLE)
1027                         /* Already interrupted */
1028                         return 0;
1029                 if (prev_handle == wait_handle)
1030                         break;
1031
1032                 /* Try again */
1033         }
1034
1035         WAIT_DEBUG (printf ("%p: state -> INTERRUPTED.\n", thread_handle->id););
1036
1037         return wait_handle;
1038 }
1039
1040 void wapi_finish_interrupt_thread (gpointer wait_handle)
1041 {
1042         pthread_cond_t *cond;
1043         mono_mutex_t *mutex;
1044         guint32 idx;
1045
1046         if (!wait_handle)
1047                 /* Not waiting */
1048                 return;
1049
1050         /* If we reach here, then wait_handle is set to the flag value, 
1051          * which means that the target thread is either
1052          * - before the first CAS in timedwait, which means it won't enter the
1053          * wait.
1054          * - it is after the first CAS, so it is already waiting, or it will 
1055          * enter the wait, and it will be interrupted by the broadcast.
1056          */
1057         idx = GPOINTER_TO_UINT(wait_handle);
1058         cond = &_WAPI_PRIVATE_HANDLES(idx).signal_cond;
1059         mutex = &_WAPI_PRIVATE_HANDLES(idx).signal_mutex;
1060
1061         mono_mutex_lock (mutex);
1062         mono_cond_broadcast (cond);
1063         mono_mutex_unlock (mutex);
1064
1065         /* ref added by set_wait_handle */
1066         _wapi_handle_unref (wait_handle);
1067 }
1068
1069
1070 /*
1071  * wapi_self_interrupt:
1072  *
1073  *   This is not part of the WIN32 API.
1074  * Set the 'interrupted' state of the calling thread if it's NULL.
1075  */
1076 void wapi_self_interrupt (void)
1077 {
1078         struct _WapiHandle_thread *thread;
1079         gboolean ok;
1080         gpointer prev_handle, wait_handle;
1081         gpointer thread_handle;
1082
1083
1084         thread_handle = OpenThread (0, 0, GetCurrentThreadId ());
1085         ok = _wapi_lookup_handle (thread_handle, WAPI_HANDLE_THREAD,
1086                                                           (gpointer *)&thread);
1087         g_assert (ok);
1088
1089         while (TRUE) {
1090                 wait_handle = thread->wait_handle;
1091
1092                 /*
1093                  * Atomically obtain the handle the thread is waiting on, and
1094                  * change it to a flag value.
1095                  */
1096                 prev_handle = InterlockedCompareExchangePointer (&thread->wait_handle,
1097                                                                                                                  INTERRUPTION_REQUESTED_HANDLE, wait_handle);
1098                 if (prev_handle == INTERRUPTION_REQUESTED_HANDLE)
1099                         /* Already interrupted */
1100                         goto cleanup;
1101                 /*We did not get interrupted*/
1102                 if (prev_handle == wait_handle)
1103                         break;
1104
1105                 /* Try again */
1106         }
1107
1108         if (wait_handle) {
1109                 /* ref added by set_wait_handle */
1110                 _wapi_handle_unref (wait_handle);
1111         }
1112
1113 cleanup:
1114         _wapi_handle_unref (thread_handle);
1115 }
1116
1117 /*
1118  * wapi_clear_interruption:
1119  *
1120  *   This is not part of the WIN32 API. 
1121  * Clear the 'interrupted' state of the calling thread.
1122  * This function is signal safe
1123  */
1124 void wapi_clear_interruption (void)
1125 {
1126         struct _WapiHandle_thread *thread;
1127         gboolean ok;
1128         gpointer prev_handle;
1129         gpointer thread_handle;
1130
1131         thread_handle = OpenThread (0, 0, GetCurrentThreadId ());
1132         ok = _wapi_lookup_handle (thread_handle, WAPI_HANDLE_THREAD,
1133                                                           (gpointer *)&thread);
1134         g_assert (ok);
1135
1136         prev_handle = InterlockedCompareExchangePointer (&thread->wait_handle,
1137                                                                                                          NULL, INTERRUPTION_REQUESTED_HANDLE);
1138         if (prev_handle == INTERRUPTION_REQUESTED_HANDLE)
1139                 WAIT_DEBUG (printf ("%p: state -> NORMAL.\n", GetCurrentThreadId ()););
1140
1141         _wapi_handle_unref (thread_handle);
1142 }
1143
1144 char* wapi_current_thread_desc ()
1145 {
1146         struct _WapiHandle_thread *thread;
1147         int i;
1148         gboolean ok;
1149         gpointer handle;
1150         gpointer thread_handle;
1151         GString* text;
1152         char *res;
1153
1154         thread_handle = OpenThread (0, 0, GetCurrentThreadId ());
1155         ok = _wapi_lookup_handle (thread_handle, WAPI_HANDLE_THREAD,
1156                                                           (gpointer *)&thread);
1157         if (!ok)
1158                 return g_strdup_printf ("thread handle %p state : lookup failure", thread_handle);
1159
1160         handle = thread->wait_handle;
1161         text = g_string_new (0);
1162         g_string_append_printf (text, "thread handle %p state : ", thread_handle);
1163
1164         if (!handle)
1165                 g_string_append_printf (text, "not waiting");
1166         else if (handle == INTERRUPTION_REQUESTED_HANDLE)
1167                 g_string_append_printf (text, "interrupted state");
1168         else
1169                 g_string_append_printf (text, "waiting on %p : %s ", handle, _wapi_handle_typename[_wapi_handle_type (handle)]);
1170         g_string_append_printf (text, " owns (");
1171         for (i = 0; i < thread->owned_mutexes->len; i++) {
1172                 gpointer mutex = g_ptr_array_index (thread->owned_mutexes, i);
1173                 if (i > 0)
1174                         g_string_append_printf (text, ", %p", mutex);
1175                 else
1176                         g_string_append_printf (text, "%p", mutex);
1177         }
1178         g_string_append_printf (text, ")");
1179
1180         res = text->str;
1181         g_string_free (text, FALSE);
1182         return res;
1183 }
1184
1185 /**
1186  * wapi_thread_set_wait_handle:
1187  *
1188  *   Set the wait handle for the current thread to HANDLE. Return TRUE on success, FALSE
1189  * if the thread is in interrupted state, and cannot start waiting.
1190  */
1191 gboolean wapi_thread_set_wait_handle (gpointer handle)
1192 {
1193         struct _WapiHandle_thread *thread;
1194         gboolean ok;
1195         gpointer prev_handle;
1196         gpointer thread_handle;
1197
1198         thread_handle = OpenThread (0, 0, GetCurrentThreadId ());
1199         ok = _wapi_lookup_handle (thread_handle, WAPI_HANDLE_THREAD,
1200                                                           (gpointer *)&thread);
1201         g_assert (ok);
1202
1203         prev_handle = InterlockedCompareExchangePointer (&thread->wait_handle,
1204                                                                                                          handle, NULL);
1205         _wapi_handle_unref (thread_handle);
1206
1207         if (prev_handle == NULL) {
1208                 /* thread->wait_handle acts as an additional reference to the handle */
1209                 _wapi_handle_ref (handle);
1210
1211                 WAIT_DEBUG (printf ("%p: state -> WAITING.\n", GetCurrentThreadId ()););
1212         } else {
1213                 g_assert (prev_handle == INTERRUPTION_REQUESTED_HANDLE);
1214                 WAIT_DEBUG (printf ("%p: unable to set state to WAITING.\n", GetCurrentThreadId ()););
1215         }
1216
1217         return prev_handle == NULL;
1218 }
1219
1220 /**
1221  * wapi_thread_clear_wait_handle:
1222  *
1223  *   Clear the wait handle of the current thread.
1224  */
1225 void wapi_thread_clear_wait_handle (gpointer handle)
1226 {
1227         struct _WapiHandle_thread *thread;
1228         gboolean ok;
1229         gpointer prev_handle;
1230         gpointer thread_handle;
1231
1232         thread_handle = OpenThread (0, 0, GetCurrentThreadId ());
1233         ok = _wapi_lookup_handle (thread_handle, WAPI_HANDLE_THREAD,
1234                                                           (gpointer *)&thread);
1235         g_assert (ok);
1236
1237         prev_handle = InterlockedCompareExchangePointer (&thread->wait_handle,
1238                                                                                                          NULL, handle);
1239
1240         if (prev_handle == handle) {
1241                 _wapi_handle_unref (handle);
1242                 WAIT_DEBUG (printf ("%p: state -> NORMAL.\n", GetCurrentThreadId ()););
1243         } else {
1244                 /*It can be NULL if it was asynchronously cleared*/
1245                 g_assert (prev_handle == INTERRUPTION_REQUESTED_HANDLE || prev_handle == NULL);
1246                 WAIT_DEBUG (printf ("%p: finished waiting.\n", GetCurrentThreadId ()););
1247         }
1248
1249         _wapi_handle_unref (thread_handle);
1250 }
1251
1252 void _wapi_thread_own_mutex (gpointer mutex)
1253 {
1254         struct _WapiHandle_thread *thread_handle;
1255         gboolean ok;
1256         gpointer thread;
1257         
1258         thread = _wapi_thread_handle_from_id (pthread_self ());
1259         if (thread == NULL) {
1260                 g_warning ("%s: error looking up thread by ID", __func__);
1261                 return;
1262         }
1263
1264         ok = _wapi_lookup_handle (thread, WAPI_HANDLE_THREAD,
1265                                   (gpointer *)&thread_handle);
1266         if (ok == FALSE) {
1267                 g_warning ("%s: error looking up thread handle %p", __func__,
1268                            thread);
1269                 return;
1270         }
1271
1272         _wapi_handle_ref (mutex);
1273         
1274         g_ptr_array_add (thread_handle->owned_mutexes, mutex);
1275 }
1276
1277 void _wapi_thread_disown_mutex (gpointer mutex)
1278 {
1279         struct _WapiHandle_thread *thread_handle;
1280         gboolean ok;
1281         gpointer thread;
1282
1283         thread = _wapi_thread_handle_from_id (pthread_self ());
1284         if (thread == NULL) {
1285                 g_warning ("%s: error looking up thread by ID", __func__);
1286                 return;
1287         }
1288
1289         ok = _wapi_lookup_handle (thread, WAPI_HANDLE_THREAD,
1290                                   (gpointer *)&thread_handle);
1291         if (ok == FALSE) {
1292                 g_warning ("%s: error looking up thread handle %p", __func__,
1293                            thread);
1294                 return;
1295         }
1296
1297         _wapi_handle_unref (mutex);
1298         
1299         g_ptr_array_remove (thread_handle->owned_mutexes, mutex);
1300 }