Merge pull request #3707 from lateralusX/jlorenss/win-api-family-support-libmonoutils
[mono.git] / mono / utils / mono-threads-windows.c
index 82b3a37312c97d27224c4dfc34e178761fb2d361..5d6774ed4d7ea1c051365f841939c9d407dcec22 100644 (file)
@@ -132,84 +132,40 @@ mono_threads_suspend_free (MonoThreadInfo *info)
 
 #if defined (HOST_WIN32)
 
-typedef struct {
-       LPTHREAD_START_ROUTINE start_routine;
-       void *arg;
-       MonoCoopSem registered;
-       gboolean suspend;
-       HANDLE suspend_event;
-} ThreadStartInfo;
-
-static DWORD WINAPI
-inner_start_thread (LPVOID arg)
+void
+mono_threads_platform_register (MonoThreadInfo *info)
 {
-       ThreadStartInfo *start_info = arg;
-       void *t_arg = start_info->arg;
-       int post_result;
-       LPTHREAD_START_ROUTINE start_func = start_info->start_routine;
-       DWORD result;
-       gboolean suspend = start_info->suspend;
-       HANDLE suspend_event = start_info->suspend_event;
-       MonoThreadInfo *info;
-
-       info = mono_thread_info_attach (&result);
-       info->runtime_thread = TRUE;
-       info->create_suspended = suspend;
-
-       mono_coop_sem_post (&(start_info->registered));
-
-       if (suspend) {
-               WaitForSingleObject (suspend_event, INFINITE); /* caller will suspend the thread before setting the event. */
-               CloseHandle (suspend_event);
-       }
+       HANDLE thread_handle;
 
-       result = start_func (t_arg);
+       thread_handle = GetCurrentThread ();
+       g_assert (thread_handle);
 
-       mono_thread_info_detach ();
+       /* The handle returned by GetCurrentThread () is a pseudo handle, so it can't
+        * be used to refer to the thread from other threads for things like aborting. */
+       DuplicateHandle (GetCurrentProcess (), thread_handle, GetCurrentProcess (), &thread_handle, THREAD_ALL_ACCESS, TRUE, 0);
 
-       return result;
+       g_assert (!info->handle);
+       info->handle = thread_handle;
 }
 
-HANDLE
-mono_threads_platform_create_thread (LPTHREAD_START_ROUTINE start_routine, gpointer arg, MonoThreadParm *tp, MonoNativeThreadId *out_tid)
+int
+mono_threads_platform_create_thread (MonoThreadStart thread_fn, gpointer thread_data, gsize stack_size, MonoNativeThreadId *out_tid)
 {
-       ThreadStartInfo *start_info;
        HANDLE result;
        DWORD thread_id;
-       guint32 creation_flags = tp->creation_flags;
-       int res;
-
-       start_info = g_malloc0 (sizeof (ThreadStartInfo));
-       if (!start_info)
-               return NULL;
-       mono_coop_sem_init (&(start_info->registered), 0);
-       start_info->arg = arg;
-       start_info->start_routine = start_routine;
-       start_info->suspend = creation_flags & CREATE_SUSPENDED;
-       creation_flags &= ~CREATE_SUSPENDED;
-       if (start_info->suspend) {
-               start_info->suspend_event = CreateEvent (NULL, TRUE, FALSE, NULL);
-               if (!start_info->suspend_event)
-                       return NULL;
-       }
 
-       result = CreateThread (NULL, tp->stack_size, inner_start_thread, start_info, creation_flags, &thread_id);
-       if (result) {
-               res = mono_coop_sem_wait (&(start_info->registered), MONO_SEM_FLAGS_NONE);
-               g_assert (res != -1);
+       result = CreateThread (NULL, stack_size, (LPTHREAD_START_ROUTINE) thread_fn, thread_data, 0, &thread_id);
+       if (!result)
+               return -1;
+
+       /* A new handle is open when attaching
+        * the thread, so we don't need this one */
+       CloseHandle (result);
 
-               if (start_info->suspend) {
-                       g_assert (SuspendThread (result) != (DWORD)-1);
-                       SetEvent (start_info->suspend_event);
-               }
-       } else if (start_info->suspend) {
-               CloseHandle (start_info->suspend_event);
-       }
        if (out_tid)
                *out_tid = thread_id;
-       mono_coop_sem_destroy (&(start_info->registered));
-       g_free (start_info);
-       return result;
+
+       return 0;
 }
 
 
@@ -231,15 +187,19 @@ mono_native_thread_create (MonoNativeThreadId *tid, gpointer func, gpointer arg)
        return CreateThread (NULL, 0, (func), (arg), 0, (tid)) != NULL;
 }
 
-void
-mono_threads_platform_resume_created (MonoThreadInfo *info, MonoNativeThreadId tid)
+gboolean
+mono_native_thread_join (MonoNativeThreadId tid)
 {
        HANDLE handle;
 
-       handle = OpenThread (THREAD_ALL_ACCESS, TRUE, tid);
-       g_assert (handle);
-       ResumeThread (handle);
+       if (!(handle = OpenThread (THREAD_ALL_ACCESS, TRUE, tid)))
+               return FALSE;
+
+       DWORD res = WaitForSingleObject (handle, INFINITE);
+
        CloseHandle (handle);
+
+       return res != WAIT_FAILED;
 }
 
 #if HAVE_DECL___READFSDWORD==0
@@ -291,30 +251,17 @@ mono_threads_platform_yield (void)
 void
 mono_threads_platform_exit (int exit_code)
 {
+       mono_thread_info_detach ();
        ExitThread (exit_code);
 }
 
 void
 mono_threads_platform_unregister (MonoThreadInfo *info)
 {
-}
-
-HANDLE
-mono_threads_platform_open_handle (void)
-{
-       HANDLE thread_handle;
-
-       thread_handle = GetCurrentThread ();
-       g_assert (thread_handle);
+       g_assert (info->handle);
 
-       /*
-        * The handle returned by GetCurrentThread () is a pseudo handle, so it can't be used to
-        * refer to the thread from other threads for things like aborting.
-        */
-       DuplicateHandle (GetCurrentProcess (), thread_handle, GetCurrentProcess (), &thread_handle,
-                                        THREAD_ALL_ACCESS, TRUE, 0);
-
-       return thread_handle;
+       CloseHandle (info->handle);
+       info->handle = NULL;
 }
 
 int
@@ -324,12 +271,29 @@ mono_threads_get_max_stack_size (void)
        return INT_MAX;
 }
 
+gpointer
+mono_threads_platform_duplicate_handle (MonoThreadInfo *info)
+{
+       HANDLE thread_handle;
+
+       g_assert (info->handle);
+       DuplicateHandle (GetCurrentProcess (), info->handle, GetCurrentProcess (), &thread_handle, THREAD_ALL_ACCESS, TRUE, 0);
+
+       return thread_handle;
+}
+
 HANDLE
 mono_threads_platform_open_thread_handle (HANDLE handle, MonoNativeThreadId tid)
 {
        return OpenThread (THREAD_ALL_ACCESS, TRUE, tid);
 }
 
+void
+mono_threads_platform_close_thread_handle (HANDLE handle)
+{
+       CloseHandle (handle);
+}
+
 #if defined(_MSC_VER)
 const DWORD MS_VC_EXCEPTION=0x406D1388;
 #pragma pack(push,8)
@@ -363,7 +327,12 @@ mono_native_thread_set_name (MonoNativeThreadId tid, const char *name)
 }
 
 void
-mono_threads_platform_set_exited (MonoThreadInfo *info)
+mono_threads_platform_set_exited (gpointer handle)
+{
+}
+
+void
+mono_threads_platform_init (void)
 {
 }