X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fthreads.c;h=07374817bd85d116fab962c9bc05af6e5dea3334;hb=50fe4789db79ab2254bff768406b4a8dee4cfe54;hp=08136dc7d07031489dd5daf7848ad219b0cf7124;hpb=71c1a8ad9befbc7391018c74e4e771fb3dfb1ee9;p=mono.git diff --git a/mono/metadata/threads.c b/mono/metadata/threads.c index 08136dc7d07..07374817bd8 100644 --- a/mono/metadata/threads.c +++ b/mono/metadata/threads.c @@ -42,6 +42,7 @@ #include #include +#include #ifdef HAVE_SIGNAL_H #include @@ -576,13 +577,13 @@ create_thread_object (MonoDomain *domain, MonoError *error) } static MonoThread* -new_thread_with_internal (MonoDomain *domain, MonoInternalThread *internal) +new_thread_with_internal (MonoDomain *domain, MonoInternalThread *internal, MonoError *error) { - MonoError error; MonoThread *thread; - thread = create_thread_object (domain, &error); - mono_error_raise_exception (&error); /* FIXME don't raise here */ + thread = create_thread_object (domain, error); + if (!mono_error_ok (error)) + return NULL; MONO_OBJECT_SETREF (thread, internal_thread, internal); @@ -616,10 +617,13 @@ create_internal_thread (MonoError *error) static void init_root_domain_thread (MonoInternalThread *thread, MonoThread *candidate) { + MonoError error; MonoDomain *domain = mono_get_root_domain (); - if (!candidate || candidate->obj.vtable->domain != domain) - candidate = new_thread_with_internal (domain, thread); + if (!candidate || candidate->obj.vtable->domain != domain) { + candidate = new_thread_with_internal (domain, thread, &error); + mono_error_raise_exception (&error); /* FIXME don't raise here */ + } set_current_thread_for_domain (domain, thread, candidate); g_assert (!thread->root_domain_thread); MONO_OBJECT_SETREF (thread, root_domain_thread, candidate); @@ -947,19 +951,24 @@ mono_thread_create (MonoDomain *domain, gpointer func, gpointer arg) MonoThread * mono_thread_attach (MonoDomain *domain) { - return mono_thread_attach_full (domain, FALSE); + MonoError error; + MonoThread *thread = mono_thread_attach_full (domain, FALSE, &error); + mono_error_raise_exception (&error); + + return thread; } MonoThread * -mono_thread_attach_full (MonoDomain *domain, gboolean force_attach) +mono_thread_attach_full (MonoDomain *domain, gboolean force_attach, MonoError *error) { - MonoError error; MonoThreadInfo *info; MonoInternalThread *thread; MonoThread *current_thread; 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); @@ -971,8 +980,9 @@ mono_thread_attach_full (MonoDomain *domain, gboolean force_attach) 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 before in the file containing the thread creation code.", mono_native_thread_id_get ()); } - thread = create_internal_thread (&error); - mono_error_raise_exception (&error); /* FIXME don't raise here */ + thread = create_internal_thread (error); + if (!mono_error_ok (error)) + return NULL; thread_handle = mono_thread_info_open_handle (); g_assert (thread_handle); @@ -990,7 +1000,9 @@ mono_thread_attach_full (MonoDomain *domain, gboolean force_attach) thread->thread_info = info; thread->small_id = info->small_id; - current_thread = new_thread_with_internal (domain, thread); + current_thread = new_thread_with_internal (domain, thread, error); + if (!mono_error_ok (error)) + return NULL; if (!handle_store (current_thread, force_attach)) { /* Mono is shutting down, so just wait for the end */ @@ -1261,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; } @@ -1389,6 +1453,7 @@ 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; @@ -1398,7 +1463,8 @@ mono_thread_current (void) if (!*current_thread_ptr) { g_assert (domain != mono_get_root_domain ()); - *current_thread_ptr = new_thread_with_internal (domain, internal); + *current_thread_ptr = new_thread_with_internal (domain, internal, &error); + mono_error_raise_exception (&error); /* FIXME don't raise here */ } return *current_thread_ptr; } @@ -1407,6 +1473,7 @@ mono_thread_current (void) static MonoThread * mono_thread_current_for_thread (MonoInternalThread *internal) { + MonoError error; MonoDomain *domain = mono_domain_get (); MonoThread **current_thread_ptr; @@ -1415,7 +1482,8 @@ 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); + *current_thread_ptr = new_thread_with_internal (domain, internal, &error); + mono_error_raise_exception (&error); /* FIXME don't raise here */ } return *current_thread_ptr; } @@ -2244,9 +2312,6 @@ mono_thread_suspend (MonoInternalThread *thread) } thread->state |= ThreadState_SuspendRequested; - - UNLOCK_THREAD (thread); - suspend_thread_internal (thread, FALSE); return TRUE; } @@ -3228,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); } @@ -3430,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; @@ -3472,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; @@ -3482,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) { @@ -3502,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 */ } /** @@ -4434,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: * @@ -4743,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