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