[threads] Remove mono_threads_create_thread (#4411)
[mono.git] / mono / metadata / threads.c
index 1c47c4445871cb0f65d0ddbe6fe9710b52d870bd..5f290cf3dc253021723fcc2acd6496021cb021b8 100644 (file)
@@ -648,7 +648,7 @@ static void
 mono_alloc_static_data (gpointer **static_data_ptr, guint32 offset, gboolean threadlocal);
 
 static gboolean
-mono_thread_attach_internal (MonoThread *thread, gboolean force_attach, gboolean force_domain, gsize *stack_ptr)
+mono_thread_attach_internal (MonoThread *thread, gboolean force_attach, gboolean force_domain)
 {
        MonoThreadInfo *info;
        MonoInternalThread *internal;
@@ -666,7 +666,6 @@ mono_thread_attach_internal (MonoThread *thread, gboolean force_attach, gboolean
        internal->tid = MONO_NATIVE_THREAD_ID_TO_UINT (mono_native_thread_id_get ());
        internal->thread_info = info;
        internal->small_id = info->small_id;
-       internal->stack_ptr = stack_ptr;
 
        THREAD_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Setting current_object_key to %p", __func__, mono_native_thread_id_get (), internal));
 
@@ -734,6 +733,7 @@ typedef struct {
        MonoObject *start_delegate_arg;
        MonoThreadStart start_func;
        gpointer start_func_arg;
+       gboolean force_attach;
        gboolean failed;
        MonoCoopSem registered;
 } StartInfo;
@@ -760,7 +760,7 @@ static guint32 WINAPI start_wrapper_internal(StartInfo *start_info, gsize *stack
 
        THREAD_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Start wrapper", __func__, mono_native_thread_id_get ()));
 
-       if (!mono_thread_attach_internal (thread, FALSE, FALSE, stack_ptr)) {
+       if (!mono_thread_attach_internal (thread, start_info->force_attach, FALSE)) {
                start_info->failed = TRUE;
 
                mono_coop_sem_post (&start_info->registered);
@@ -873,11 +873,25 @@ static guint32 WINAPI start_wrapper_internal(StartInfo *start_info, gsize *stack
        return(0);
 }
 
-static gsize WINAPI start_wrapper(void *data)
+static gsize WINAPI
+start_wrapper (gpointer data)
 {
-       volatile gsize dummy;
+       StartInfo *start_info;
+       MonoThreadInfo *info;
+       gsize res;
+
+       start_info = (StartInfo*) data;
+       g_assert (start_info);
+
+       info = mono_thread_info_attach (&res);
+       info->runtime_thread = TRUE;
+
+       /* Run the actual main function of the thread */
+       res = start_wrapper_internal (start_info, &res);
 
-       return start_wrapper_internal ((StartInfo*) data, (gsize*) &dummy);
+       mono_thread_info_exit (res);
+
+       g_assert_not_reached ();
 }
 
 /*
@@ -888,10 +902,9 @@ static gsize WINAPI start_wrapper(void *data)
  */
 static gboolean
 create_thread (MonoThread *thread, MonoInternalThread *internal, MonoObject *start_delegate, MonoThreadStart start_func, gpointer start_func_arg,
-       gboolean threadpool_thread, guint32 stack_size, MonoError *error)
+       MonoThreadCreateFlags flags, MonoError *error)
 {
        StartInfo *start_info = NULL;
-       MonoThreadHandle *thread_handle;
        MonoNativeThreadId tid;
        gboolean ret;
        gsize stack_set_size;
@@ -901,6 +914,15 @@ create_thread (MonoThread *thread, MonoInternalThread *internal, MonoObject *sta
        if (start_func)
                g_assert (!start_delegate);
 
+       if (flags & MONO_THREAD_CREATE_FLAGS_THREADPOOL) {
+               g_assert (!(flags & MONO_THREAD_CREATE_FLAGS_DEBUGGER));
+               g_assert (!(flags & MONO_THREAD_CREATE_FLAGS_FORCE_CREATE));
+       }
+       if (flags & MONO_THREAD_CREATE_FLAGS_DEBUGGER) {
+               g_assert (!(flags & MONO_THREAD_CREATE_FLAGS_THREADPOOL));
+               g_assert (!(flags & MONO_THREAD_CREATE_FLAGS_FORCE_CREATE));
+       }
+
        /*
         * Join joinable threads to prevent running out of threads since the finalizer
         * thread might be blocked/backlogged.
@@ -910,7 +932,7 @@ create_thread (MonoThread *thread, MonoInternalThread *internal, MonoObject *sta
        error_init (error);
 
        mono_threads_lock ();
-       if (shutting_down) {
+       if (shutting_down && !(flags & MONO_THREAD_CREATE_FLAGS_FORCE_CREATE)) {
                mono_threads_unlock ();
                return FALSE;
        }
@@ -920,10 +942,12 @@ create_thread (MonoThread *thread, MonoInternalThread *internal, MonoObject *sta
        mono_g_hash_table_insert (threads_starting_up, thread, thread);
        mono_threads_unlock ();
 
-       internal->threadpool_thread = threadpool_thread;
-       if (threadpool_thread)
+       internal->threadpool_thread = flags & MONO_THREAD_CREATE_FLAGS_THREADPOOL;
+       if (internal->threadpool_thread)
                mono_thread_set_state (internal, ThreadState_Background);
 
+       internal->debugger_thread = flags & MONO_THREAD_CREATE_FLAGS_DEBUGGER;
+
        start_info = g_new0 (StartInfo, 1);
        start_info->ref = 2;
        start_info->thread = thread;
@@ -931,17 +955,16 @@ create_thread (MonoThread *thread, MonoInternalThread *internal, MonoObject *sta
        start_info->start_delegate_arg = thread->start_obj;
        start_info->start_func = start_func;
        start_info->start_func_arg = start_func_arg;
+       start_info->force_attach = flags & MONO_THREAD_CREATE_FLAGS_FORCE_CREATE;
        start_info->failed = FALSE;
        mono_coop_sem_init (&start_info->registered, 0);
 
-       if (stack_size == 0)
+       if (flags != MONO_THREAD_CREATE_FLAGS_SMALL_STACK)
                stack_set_size = default_stacksize_for_thread (internal);
        else
                stack_set_size = 0;
 
-       thread_handle = mono_threads_create_thread (start_wrapper, start_info, &stack_set_size, &tid);
-
-       if (thread_handle == NULL) {
+       if (!mono_thread_platform_create_thread (start_wrapper, start_info, &stack_set_size, &tid)) {
                /* The thread couldn't be created, so set an exception */
                mono_threads_lock ();
                mono_g_hash_table_remove (threads_starting_up, thread);
@@ -966,8 +989,6 @@ create_thread (MonoThread *thread, MonoInternalThread *internal, MonoObject *sta
 
        mono_coop_sem_wait (&start_info->registered, MONO_SEM_FLAGS_NONE);
 
-       mono_threads_close_thread_handle (thread_handle);
-
        THREAD_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Done launching thread %p (%"G_GSIZE_FORMAT")", __func__, mono_native_thread_id_get (), internal, (gsize)internal->tid));
 
        ret = !start_info->failed;
@@ -1004,7 +1025,7 @@ guint32 mono_threads_get_default_stacksize (void)
  *   ARG should not be a GC reference.
  */
 MonoInternalThread*
-mono_thread_create_internal (MonoDomain *domain, gpointer func, gpointer arg, gboolean threadpool_thread, guint32 stack_size, MonoError *error)
+mono_thread_create_internal (MonoDomain *domain, gpointer func, gpointer arg, MonoThreadCreateFlags flags, MonoError *error)
 {
        MonoThread *thread;
        MonoInternalThread *internal;
@@ -1018,11 +1039,11 @@ mono_thread_create_internal (MonoDomain *domain, gpointer func, gpointer arg, gb
 
        LOCK_THREAD (internal);
 
-       res = create_thread (thread, internal, NULL, (MonoThreadStart) func, arg, threadpool_thread, stack_size, error);
-       return_val_if_nok (error, NULL);
+       res = create_thread (thread, internal, NULL, (MonoThreadStart) func, arg, flags, error);
 
        UNLOCK_THREAD (internal);
 
+       return_val_if_nok (error, NULL);
        return internal;
 }
 
@@ -1037,7 +1058,7 @@ mono_thread_create (MonoDomain *domain, gpointer func, gpointer arg)
 gboolean
 mono_thread_create_checked (MonoDomain *domain, gpointer func, gpointer arg, MonoError *error)
 {
-       return (NULL != mono_thread_create_internal (domain, func, arg, FALSE, 0, error));
+       return (NULL != mono_thread_create_internal (domain, func, arg, MONO_THREAD_CREATE_FLAGS_NONE, error));
 }
 
 MonoThread *
@@ -1053,6 +1074,7 @@ mono_thread_attach_full (MonoDomain *domain, gboolean force_attach)
 {
        MonoInternalThread *internal;
        MonoThread *thread;
+       MonoThreadInfo *info;
        MonoNativeThreadId tid;
        gsize stack_ptr;
 
@@ -1063,9 +1085,8 @@ mono_thread_attach_full (MonoDomain *domain, gboolean force_attach)
                return mono_thread_current ();
        }
 
-       if (!mono_gc_register_thread (&domain)) {
-               g_error ("Thread %"G_GSIZE_FORMAT" calling into managed code is not registered with the GC. On UNIX, this can be fixed by #include-ing <gc.h> before <pthread.h> in the file containing the thread creation code.", mono_native_thread_id_get ());
-       }
+       info = mono_thread_info_attach (&stack_ptr);
+       g_assert (info);
 
        tid=mono_native_thread_id_get ();
 
@@ -1073,7 +1094,7 @@ mono_thread_attach_full (MonoDomain *domain, gboolean force_attach)
 
        thread = create_thread_object (domain, internal);
 
-       if (!mono_thread_attach_internal (thread, force_attach, TRUE, &stack_ptr)) {
+       if (!mono_thread_attach_internal (thread, force_attach, TRUE)) {
                /* Mono is shutting down, so just wait for the end */
                for (;;)
                        mono_thread_info_sleep (10000, NULL);
@@ -1345,7 +1366,7 @@ ves_icall_System_Threading_Thread_Thread_internal (MonoThread *this_obj,
                return this_obj;
        }
 
-       res = create_thread (this_obj, internal, start, NULL, NULL, FALSE, 0, &error);
+       res = create_thread (this_obj, internal, start, NULL, NULL, MONO_THREAD_CREATE_FLAGS_NONE, &error);
        if (!res) {
                mono_error_cleanup (&error);
                UNLOCK_THREAD (internal);