Add [Category ("NotWorking")] to failing test.
[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_abort_syscall (MonoThreadInfo *info)
30 {
31 }
32
33 gboolean
34 mono_threads_core_needs_abort_syscall (void)
35 {
36         return FALSE;
37 }
38
39 void
40 mono_threads_core_self_suspend (MonoThreadInfo *info)
41 {
42         g_assert (0);
43 }
44
45 gboolean
46 mono_threads_core_suspend (MonoThreadInfo *info)
47 {
48         g_assert (0);
49 }
50
51 gboolean
52 mono_threads_core_resume (MonoThreadInfo *info)
53 {
54         g_assert (0);
55 }
56
57 void
58 mono_threads_platform_register (MonoThreadInfo *info)
59 {
60 }
61
62 void
63 mono_threads_platform_free (MonoThreadInfo *info)
64 {
65 }
66
67 typedef struct {
68         LPTHREAD_START_ROUTINE start_routine;
69         void *arg;
70         MonoSemType registered;
71         gboolean suspend;
72         HANDLE suspend_event;
73 } ThreadStartInfo;
74
75 static DWORD WINAPI
76 inner_start_thread (LPVOID arg)
77 {
78         ThreadStartInfo *start_info = arg;
79         void *t_arg = start_info->arg;
80         int post_result;
81         LPTHREAD_START_ROUTINE start_func = start_info->start_routine;
82         DWORD result;
83         gboolean suspend = start_info->suspend;
84         HANDLE suspend_event = start_info->suspend_event;
85
86         mono_thread_info_attach (&result)->runtime_thread = TRUE;
87
88         post_result = MONO_SEM_POST (&(start_info->registered));
89         g_assert (!post_result);
90
91         if (suspend)
92         {
93                 WaitForSingleObject (suspend_event, INFINITE); /* caller will suspend the thread before setting the event. */
94                 CloseHandle (suspend_event);
95         }
96
97         result = start_func (t_arg);
98
99         g_assert (!mono_domain_get ());
100
101         mono_thread_info_dettach ();
102
103         return result;
104 }
105
106 HANDLE
107 mono_threads_CreateThread (LPSECURITY_ATTRIBUTES attributes, SIZE_T stack_size, LPTHREAD_START_ROUTINE start_routine,
108                 LPVOID arg, DWORD creation_flags, LPDWORD thread_id)
109 {
110         ThreadStartInfo *start_info;
111         HANDLE result;
112
113         start_info = g_malloc0 (sizeof (ThreadStartInfo));
114         if (!start_info)
115                 return NULL;
116         MONO_SEM_INIT (&(start_info->registered), 0);
117         start_info->arg = arg;
118         start_info->start_routine = start_routine;
119         start_info->suspend = creation_flags & CREATE_SUSPENDED;
120         creation_flags &= ~CREATE_SUSPENDED;
121         if (start_info->suspend)
122         {
123                 start_info->suspend_event = CreateEvent (NULL, TRUE, FALSE, NULL);
124                 if (!start_info->suspend_event)
125                         return NULL;
126         }
127
128         result = CreateThread (attributes, stack_size, inner_start_thread, start_info, creation_flags, thread_id);
129
130         if (result) {
131                 while (MONO_SEM_WAIT (&(start_info->registered)) != 0) {
132                         /*if (EINTR != errno) ABORT("sem_wait failed"); */
133                 }
134                 if (start_info->suspend)
135                 {
136                         g_assert (SuspendThread (result) != (DWORD)-1);
137                         SetEvent (start_info->suspend_event);
138                 }
139         }
140         else if (start_info->suspend)
141                 CloseHandle (start_info->suspend_event);
142         MONO_SEM_DESTROY (&(start_info->registered));
143         g_free (start_info);
144         return result;
145 }
146
147
148 MonoNativeThreadId
149 mono_native_thread_id_get (void)
150 {
151         return GetCurrentThreadId ();
152 }
153
154 gboolean
155 mono_native_thread_id_equals (MonoNativeThreadId id1, MonoNativeThreadId id2)
156 {
157         return id1 == id2;
158 }
159
160 gboolean
161 mono_native_thread_create (MonoNativeThreadId *tid, gpointer func, gpointer arg)
162 {
163         return CreateThread (NULL, 0, (func), (arg), 0, (tid)) != NULL;
164 }
165
166 #endif