Merge pull request #2524 from lambdageek/monoerror-mono_string_new_utf16_checked
[mono.git] / mono / metadata / threads.c
index 35f8f22a8bfbd75746b9f62a1bb3ad4281c56519..07374817bd85d116fab962c9bc05af6e5dea3334 100644 (file)
@@ -42,6 +42,7 @@
 #include <mono/utils/mono-memory-model.h>
 
 #include <mono/metadata/gc-internals.h>
+#include <mono/metadata/reflection-internals.h>
 
 #ifdef HAVE_SIGNAL_H
 #include <signal.h>
@@ -1272,19 +1273,71 @@ mono_thread_get_name (MonoInternalThread *this_obj, guint32 *name_len)
        return res;
 }
 
+/*
+ * mono_thread_get_name_utf8:
+ *
+ * Return the name of the thread in UTF-8.
+ * Return NULL if the thread has no name.
+ * The returned memory is owned by the caller.
+ */
+char *
+mono_thread_get_name_utf8 (MonoThread *thread)
+{
+       if (thread == NULL)
+               return NULL;
+
+       MonoInternalThread *internal = thread->internal_thread;
+       if (internal == NULL)
+               return NULL;
+
+       LOCK_THREAD (internal);
+
+       char *tname = g_utf16_to_utf8 (internal->name, internal->name_len, NULL, NULL, NULL);
+
+       UNLOCK_THREAD (internal);
+
+       return tname;
+}
+
+/*
+ * mono_thread_get_managed_id:
+ *
+ * Return the Thread.ManagedThreadId value of `thread`.
+ * Returns -1 if `thread` is NULL.
+ */
+int32_t
+mono_thread_get_managed_id (MonoThread *thread)
+{
+       if (thread == NULL)
+               return -1;
+
+       MonoInternalThread *internal = thread->internal_thread;
+       if (internal == NULL)
+               return -1;
+
+       int32_t id = internal->managed_id;
+
+       return id;
+}
+
 MonoString* 
 ves_icall_System_Threading_Thread_GetName_internal (MonoInternalThread *this_obj)
 {
+       MonoError error;
        MonoString* str;
 
+       mono_error_init (&error);
+
        LOCK_THREAD (this_obj);
        
        if (!this_obj->name)
                str = NULL;
        else
-               str = mono_string_new_utf16 (mono_domain_get (), this_obj->name, this_obj->name_len);
+               str = mono_string_new_utf16_checked (mono_domain_get (), this_obj->name, this_obj->name_len, &error);
        
        UNLOCK_THREAD (this_obj);
+
+       mono_error_raise_exception (&error);
        
        return str;
 }
@@ -2259,9 +2312,6 @@ mono_thread_suspend (MonoInternalThread *thread)
        }
        
        thread->state |= ThreadState_SuspendRequested;
-
-       UNLOCK_THREAD (thread);
-
        suspend_thread_internal (thread, FALSE);
        return TRUE;
 }
@@ -3243,9 +3293,6 @@ void mono_thread_suspend_all_other_threads (void)
                                thread->state &= ~ThreadState_AbortRequested;
                        
                        thread->state |= ThreadState_SuspendRequested;
-
-                       UNLOCK_THREAD (thread);
-
                        /* Signal the thread to suspend */
                        suspend_thread_internal (thread, TRUE);
                }
@@ -3445,12 +3492,16 @@ mono_threads_perform_thread_dump (void)
 static void
 mono_threads_get_thread_dump (MonoArray **out_threads, MonoArray **out_stack_frames)
 {
+       MonoError error;
+
        ThreadDumpUserData ud;
        MonoInternalThread *thread_array [128];
        MonoDomain *domain = mono_domain_get ();
        MonoDebugSourceLocation *location;
        int tindex, nthreads;
 
+       mono_error_init (&error);
+       
        *out_threads = NULL;
        *out_stack_frames = NULL;
 
@@ -3487,7 +3538,9 @@ mono_threads_get_thread_dump (MonoArray **out_threads, MonoArray **out_stack_fra
                for (i = 0; i < ud.nframes; ++i) {
                        MonoStackFrameInfo *frame = &ud.frames [i];
                        MonoMethod *method = NULL;
-                       MonoStackFrame *sf = (MonoStackFrame *)mono_object_new (domain, mono_defaults.stack_frame_class);
+                       MonoStackFrame *sf = (MonoStackFrame *)mono_object_new_checked (domain, mono_defaults.stack_frame_class, &error);
+                       if (!mono_error_ok (&error))
+                               goto leave;
 
                        sf->native_offset = frame->native_offset;
 
@@ -3497,7 +3550,9 @@ mono_threads_get_thread_dump (MonoArray **out_threads, MonoArray **out_stack_fra
                        if (method) {
                                sf->method_address = (gsize) frame->ji->code_start;
 
-                               MONO_OBJECT_SETREF (sf, method, mono_method_get_object (domain, method, NULL));
+                               MonoReflectionMethod *rm = mono_method_get_object_checked (domain, method, NULL, &error);
+                               mono_error_raise_exception (&error); /* FIXME don't raise here */
+                               MONO_OBJECT_SETREF (sf, method, rm);
 
                                location = mono_debug_lookup_source_location (method, frame->native_offset, domain);
                                if (location) {
@@ -3517,7 +3572,9 @@ 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 */
 }
 
 /**
@@ -4449,20 +4506,6 @@ mono_thread_force_interruption_checkpoint_noraise (void)
        return mono_thread_interruption_checkpoint_request (TRUE);
 }
 
-/*
- * Performs the interruption of the current thread, if one has been requested.
- * Throw the exception which needs to be thrown, if any.
- */
-void
-mono_thread_force_interruption_checkpoint (void)
-{
-       MonoException *ex;
-
-       ex = mono_thread_interruption_checkpoint_request (TRUE);
-       if (ex)
-               mono_raise_exception (ex);
-}
-
 /*
  * mono_thread_get_and_clear_pending_exception:
  *
@@ -4758,7 +4801,6 @@ suspend_thread_critical (MonoThreadInfo *info, gpointer ud)
 static void
 suspend_thread_internal (MonoInternalThread *thread, gboolean interrupt)
 {
-       LOCK_THREAD (thread);
        if (thread == mono_thread_internal_current ()) {
                mono_thread_info_begin_self_suspend ();
                //XXX replace this with better named functions