[sgen] Basic Win32 support.
[mono.git] / mono / utils / mono-threads-windows.c
1 /*
2  * mono-threads-windows.c: Low-level threading, windows version
3  *
4  * Author:
5  *      Rodrigo Kumpera (kumpera@gmail.com)
6  *
7  * (C) 2011 Novell, Inc
8  */
9
10 #include "config.h"
11
12 #if defined(HOST_WIN32)
13
14 #include <mono/utils/mono-threads.h>
15
16
17 void
18 mono_threads_init_platform (void)
19 {
20 }
21
22 void
23 mono_threads_core_interrupt (MonoThreadInfo *info)
24 {
25         g_assert (0);
26 }
27
28 void
29 mono_threads_core_self_suspend (MonoThreadInfo *info)
30 {
31         g_assert (0);
32 }
33
34 gboolean
35 mono_threads_core_suspend (MonoThreadInfo *info)
36 {
37         g_assert (0);
38 }
39
40 gboolean
41 mono_threads_core_resume (MonoThreadInfo *info)
42 {
43         g_assert (0);
44 }
45
46 void
47 mono_threads_platform_register (MonoThreadInfo *info)
48 {
49 }
50
51 void
52 mono_threads_platform_free (MonoThreadInfo *info)
53 {
54 }
55
56 typedef struct {
57         LPTHREAD_START_ROUTINE start_routine;
58         void *arg;
59         MonoSemType registered;
60         gboolean suspend;
61 } ThreadStartInfo;
62
63 static DWORD WINAPI
64 inner_start_thread (LPVOID arg)
65 {
66         ThreadStartInfo *start_info = arg;
67         void *t_arg = start_info->arg;
68         int post_result;
69         LPTHREAD_START_ROUTINE start_func = start_info->start_routine;
70         DWORD result;
71
72         mono_thread_info_attach (&result);
73
74         post_result = MONO_SEM_POST (&(start_info->registered));
75         g_assert (!post_result);
76
77         if (start_info->suspend)
78                 SuspendThread (GetCurrentThread ());
79
80         result = start_func (t_arg);
81
82         g_assert (!mono_domain_get ());
83
84         return result;
85 }
86
87 HANDLE
88 mono_threads_CreateThread (LPSECURITY_ATTRIBUTES attributes, SIZE_T stack_size, LPTHREAD_START_ROUTINE start_routine,
89                 LPVOID arg, DWORD creation_flags, LPDWORD thread_id)
90 {
91         ThreadStartInfo *start_info;
92         HANDLE result;
93
94         start_info = g_malloc0 (sizeof (ThreadStartInfo));
95         if (!start_info)
96                 return NULL;
97         MONO_SEM_INIT (&(start_info->registered), 0);
98         start_info->arg = arg;
99         start_info->start_routine = start_routine;
100         start_info->suspend = creation_flags & CREATE_SUSPENDED;
101         creation_flags &= ~CREATE_SUSPENDED;
102
103         result = CreateThread (attributes, stack_size, inner_start_thread, start_info, creation_flags, thread_id);
104
105         if (result) {
106                 while (MONO_SEM_WAIT (&(start_info->registered)) != 0) {
107                         /*if (EINTR != errno) ABORT("sem_wait failed"); */
108                 }
109         }
110         MONO_SEM_DESTROY (&(start_info->registered));
111         g_free (start_info);
112         return result;
113 }
114
115 #endif