Merge pull request #3038 from lambdageek/dev/monoerror-threads
[mono.git] / mono / metadata / threads.c
index d00b01f812933a860cf15b16c87f58d57ca87714..cc6bbad33f8a8cf735194172a87deda93ebc1002 100644 (file)
@@ -574,21 +574,22 @@ set_current_thread_for_domain (MonoDomain *domain, MonoInternalThread *thread, M
 }
 
 static MonoThread*
-create_thread_object (MonoDomain *domain, MonoError *error)
+create_thread_object (MonoDomain *domain)
 {
+       MonoError error;
        MonoVTable *vt = mono_class_vtable (domain, mono_defaults.thread_class);
-       MonoThread *t = (MonoThread*)mono_object_new_mature (vt, error);
+       MonoThread *t = (MonoThread*)mono_object_new_mature (vt, &error);
+       /* only possible failure mode is OOM, from which we don't expect to recover. */
+       mono_error_assert_ok (&error);
        return t;
 }
 
 static MonoThread*
-new_thread_with_internal (MonoDomain *domain, MonoInternalThread *internal, MonoError *error)
+new_thread_with_internal (MonoDomain *domain, MonoInternalThread *internal)
 {
        MonoThread *thread;
 
-       thread = create_thread_object (domain, error);
-       if (!mono_error_ok (error))
-               return NULL;
+       thread = create_thread_object (domain);
 
        MONO_OBJECT_SETREF (thread, internal_thread, internal);
 
@@ -596,15 +597,16 @@ new_thread_with_internal (MonoDomain *domain, MonoInternalThread *internal, Mono
 }
 
 static MonoInternalThread*
-create_internal_thread (MonoError *error)
+create_internal_thread (void)
 {
+       MonoError error;
        MonoInternalThread *thread;
        MonoVTable *vt;
 
        vt = mono_class_vtable (mono_get_root_domain (), mono_defaults.internal_thread_class);
-       thread = (MonoInternalThread*) mono_object_new_mature (vt, error);
-       if (!mono_error_ok (error))
-               return NULL;
+       thread = (MonoInternalThread*) mono_object_new_mature (vt, &error);
+       /* only possible failure mode is OOM, from which we don't exect to recover */
+       mono_error_assert_ok (&error);
 
        thread->synch_cs = g_new0 (MonoCoopMutex, 1);
        mono_coop_mutex_init_recursive (thread->synch_cs);
@@ -620,14 +622,12 @@ create_internal_thread (MonoError *error)
 }
 
 static gboolean
-init_root_domain_thread (MonoInternalThread *thread, MonoThread *candidate, MonoError *error)
+init_root_domain_thread (MonoInternalThread *thread, MonoThread *candidate)
 {
        MonoDomain *domain = mono_get_root_domain ();
 
-       mono_error_init (error);
        if (!candidate || candidate->obj.vtable->domain != domain) {
-               candidate = new_thread_with_internal (domain, thread, error);
-               return_val_if_nok (error, FALSE);
+               candidate = new_thread_with_internal (domain, thread);
        }
        set_current_thread_for_domain (domain, thread, candidate);
        g_assert (!thread->root_domain_thread);
@@ -686,8 +686,7 @@ static guint32 WINAPI start_wrapper_internal(void *data)
        /* We have to do this here because mono_thread_new_init()
           requires that root_domain_thread is set up. */
        thread_adjust_static_data (internal);
-       init_root_domain_thread (internal, start_info->obj, &error);
-       mono_error_raise_exception (&error); /* FIXME don't raise here */
+       init_root_domain_thread (internal, start_info->obj);
 
        /* This MUST be called before any managed code can be
         * executed, as it calls the callback function that (for the
@@ -927,11 +926,9 @@ mono_thread_create_internal (MonoDomain *domain, gpointer func, gpointer arg, gb
 
        mono_error_init (error);
 
-       thread = create_thread_object (domain, error);
-       return_val_if_nok (error, NULL);
+       thread = create_thread_object (domain);
 
-       internal = create_internal_thread (error);
-       return_val_if_nok (error, NULL);
+       internal = create_internal_thread ();
 
        MONO_OBJECT_SETREF (thread, internal_thread, internal);
 
@@ -969,15 +966,13 @@ mono_thread_create_checked (MonoDomain *domain, gpointer func, gpointer arg, Mon
 MonoThread *
 mono_thread_attach (MonoDomain *domain)
 {
-       MonoError error;
-       MonoThread *thread = mono_thread_attach_full (domain, FALSE, &error);
-       mono_error_raise_exception (&error);
+       MonoThread *thread = mono_thread_attach_full (domain, FALSE);
 
        return thread;
 }
 
 MonoThread *
-mono_thread_attach_full (MonoDomain *domain, gboolean force_attach, MonoError *error)
+mono_thread_attach_full (MonoDomain *domain, gboolean force_attach)
 {
        MonoThreadInfo *info;
        MonoInternalThread *thread;
@@ -985,8 +980,6 @@ mono_thread_attach_full (MonoDomain *domain, gboolean force_attach, MonoError *e
        HANDLE thread_handle;
        MonoNativeThreadId tid;
 
-       mono_error_init (error);
-
        if ((thread = mono_thread_internal_current ())) {
                if (domain != mono_domain_get ())
                        mono_domain_set (domain, TRUE);
@@ -998,9 +991,7 @@ mono_thread_attach_full (MonoDomain *domain, gboolean force_attach, MonoError *e
                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 ());
        }
 
-       thread = create_internal_thread (error);
-       if (!mono_error_ok (error))
-               return NULL;
+       thread = create_internal_thread ();
 
        thread_handle = mono_thread_info_open_handle ();
        g_assert (thread_handle);
@@ -1018,9 +1009,7 @@ mono_thread_attach_full (MonoDomain *domain, gboolean force_attach, MonoError *e
        thread->thread_info = info;
        thread->small_id = info->small_id;
 
-       current_thread = new_thread_with_internal (domain, thread, error);
-       if (!mono_error_ok (error))
-               return NULL;
+       current_thread = new_thread_with_internal (domain, thread);
 
        if (!handle_store (current_thread, force_attach)) {
                /* Mono is shutting down, so just wait for the end */
@@ -1035,8 +1024,7 @@ mono_thread_attach_full (MonoDomain *domain, gboolean force_attach, MonoError *e
 
        thread_adjust_static_data (thread);
 
-       init_root_domain_thread (thread, current_thread, error);
-       return_val_if_nok (error, NULL);
+       init_root_domain_thread (thread, current_thread);
 
        if (domain != mono_get_root_domain ())
                set_current_thread_for_domain (domain, thread, current_thread);
@@ -1128,12 +1116,9 @@ mono_thread_exit ()
 void
 ves_icall_System_Threading_Thread_ConstructInternalThread (MonoThread *this_obj)
 {
-       MonoError error;
        MonoInternalThread *internal;
 
-       internal = create_internal_thread (&error);
-       if (mono_error_set_pending_exception (&error))
-               return;
+       internal = create_internal_thread ();
 
        internal->state = ThreadState_Unstarted;
 
@@ -1492,7 +1477,6 @@ ves_icall_System_Threading_Thread_ByteArrayToCurrentDomain (MonoArray *arr)
 MonoThread *
 mono_thread_current (void)
 {
-       MonoError error;
        MonoDomain *domain = mono_domain_get ();
        MonoInternalThread *internal = mono_thread_internal_current ();
        MonoThread **current_thread_ptr;
@@ -1502,8 +1486,7 @@ mono_thread_current (void)
 
        if (!*current_thread_ptr) {
                g_assert (domain != mono_get_root_domain ());
-               *current_thread_ptr = new_thread_with_internal (domain, internal, &error);
-               mono_error_raise_exception (&error); /* FIXME don't raise here */
+               *current_thread_ptr = new_thread_with_internal (domain, internal);
        }
        return *current_thread_ptr;
 }
@@ -1512,7 +1495,6 @@ mono_thread_current (void)
 static MonoThread *
 mono_thread_current_for_thread (MonoInternalThread *internal)
 {
-       MonoError error;
        MonoDomain *domain = mono_domain_get ();
        MonoThread **current_thread_ptr;
 
@@ -1521,8 +1503,7 @@ mono_thread_current_for_thread (MonoInternalThread *internal)
 
        if (!*current_thread_ptr) {
                g_assert (domain != mono_get_root_domain ());
-               *current_thread_ptr = new_thread_with_internal (domain, internal, &error);
-               mono_error_raise_exception (&error); /* FIXME don't raise here */
+               *current_thread_ptr = new_thread_with_internal (domain, internal);
        }
        return *current_thread_ptr;
 }
@@ -3615,10 +3596,9 @@ mono_threads_perform_thread_dump (void)
 }
 
 /* Obtain the thread dump of all threads */
-static void
-mono_threads_get_thread_dump (MonoArray **out_threads, MonoArray **out_stack_frames)
+static gboolean
+mono_threads_get_thread_dump (MonoArray **out_threads, MonoArray **out_stack_frames, MonoError *error)
 {
-       MonoError error;
 
        ThreadDumpUserData ud;
        MonoInternalThread *thread_array [128];
@@ -3626,7 +3606,7 @@ mono_threads_get_thread_dump (MonoArray **out_threads, MonoArray **out_stack_fra
        MonoDebugSourceLocation *location;
        int tindex, nthreads;
 
-       mono_error_init (&error);
+       mono_error_init (error);
        
        *out_threads = NULL;
        *out_stack_frames = NULL;
@@ -3638,11 +3618,11 @@ mono_threads_get_thread_dump (MonoArray **out_threads, MonoArray **out_stack_fra
        ud.frames = g_new0 (MonoStackFrameInfo, 256);
        ud.max_frames = 256;
 
-       *out_threads = mono_array_new_checked (domain, mono_defaults.thread_class, nthreads, &error);
-       if (!is_ok (&error))
+       *out_threads = mono_array_new_checked (domain, mono_defaults.thread_class, nthreads, error);
+       if (!is_ok (error))
                goto leave;
-       *out_stack_frames = mono_array_new_checked (domain, mono_defaults.array_class, nthreads, &error);
-       if (!is_ok (&error))
+       *out_stack_frames = mono_array_new_checked (domain, mono_defaults.array_class, nthreads, error);
+       if (!is_ok (error))
                goto leave;
 
        for (tindex = 0; tindex < nthreads; ++tindex) {
@@ -3662,16 +3642,16 @@ mono_threads_get_thread_dump (MonoArray **out_threads, MonoArray **out_stack_fra
 
                mono_array_setref_fast (*out_threads, tindex, mono_thread_current_for_thread (thread));
 
-               thread_frames = mono_array_new_checked (domain, mono_defaults.stack_frame_class, ud.nframes, &error);
-               if (!is_ok (&error))
+               thread_frames = mono_array_new_checked (domain, mono_defaults.stack_frame_class, ud.nframes, error);
+               if (!is_ok (error))
                        goto leave;
                mono_array_setref_fast (*out_stack_frames, tindex, thread_frames);
 
                for (i = 0; i < ud.nframes; ++i) {
                        MonoStackFrameInfo *frame = &ud.frames [i];
                        MonoMethod *method = NULL;
-                       MonoStackFrame *sf = (MonoStackFrame *)mono_object_new_checked (domain, mono_defaults.stack_frame_class, &error);
-                       if (!mono_error_ok (&error))
+                       MonoStackFrame *sf = (MonoStackFrame *)mono_object_new_checked (domain, mono_defaults.stack_frame_class, error);
+                       if (!is_ok (error))
                                goto leave;
 
                        sf->native_offset = frame->native_offset;
@@ -3682,8 +3662,9 @@ mono_threads_get_thread_dump (MonoArray **out_threads, MonoArray **out_stack_fra
                        if (method) {
                                sf->method_address = (gsize) frame->ji->code_start;
 
-                               MonoReflectionMethod *rm = mono_method_get_object_checked (domain, method, NULL, &error);
-                               mono_error_raise_exception (&error); /* FIXME don't raise here */
+                               MonoReflectionMethod *rm = mono_method_get_object_checked (domain, method, NULL, error);
+                               if (!is_ok (error))
+                                       goto leave;
                                MONO_OBJECT_SETREF (sf, method, rm);
 
                                location = mono_debug_lookup_source_location (method, frame->native_offset, domain);
@@ -3706,7 +3687,7 @@ mono_threads_get_thread_dump (MonoArray **out_threads, MonoArray **out_stack_fra
 
 leave:
        g_free (ud.frames);
-       mono_error_raise_exception (&error); /* FIXME don't raise here */
+       return is_ok (error);
 }
 
 /**
@@ -4422,17 +4403,6 @@ mono_alloc_special_static_data_free (GHashTable *special_static_fields)
        mono_threads_unlock ();
 }
 
-static void
-mono_special_static_data_free_slot (guint32 offset, guint32 size)
-{
-       /* Only ever called for ThreadLocal instances */
-       g_assert (ACCESS_SPECIAL_STATIC_OFFSET (offset, type) == SPECIAL_STATIC_OFFSET_TYPE_THREAD);
-
-       mono_threads_lock ();
-       do_free_special_slot (offset, size);
-       mono_threads_unlock ();
-}
-
 #ifdef HOST_WIN32
 static void CALLBACK dummy_apc (ULONG_PTR param)
 {
@@ -5097,7 +5067,9 @@ mono_thread_internal_unhandled_exception (MonoObject* exc)
 void
 ves_icall_System_Threading_Thread_GetStackTraces (MonoArray **out_threads, MonoArray **out_stack_traces)
 {
-       mono_threads_get_thread_dump (out_threads, out_stack_traces);
+       MonoError error;
+       mono_threads_get_thread_dump (out_threads, out_stack_traces, &error);
+       mono_error_set_pending_exception (&error);
 }
 
 /*
@@ -5114,7 +5086,6 @@ ves_icall_System_Threading_Thread_GetStackTraces (MonoArray **out_threads, MonoA
 gpointer
 mono_threads_attach_coop (MonoDomain *domain, gpointer *dummy)
 {
-       MonoError error;
        MonoDomain *orig;
        gboolean fresh_thread;
 
@@ -5135,8 +5106,7 @@ mono_threads_attach_coop (MonoDomain *domain, gpointer *dummy)
        }
 
        if (!mono_thread_internal_current ()) {
-               mono_thread_attach_full (domain, FALSE, &error);
-               mono_error_assert_ok (&error);
+               mono_thread_attach_full (domain, FALSE);
 
                // #678164
                mono_thread_set_state (mono_thread_internal_current (), ThreadState_Background);