if (!mono_thread_info_lookup (MONO_UINT_TO_NATIVE_THREAD_ID (thread->tid))->tools_thread)
mono_profiler_thread_end (thread->tid);
+ mono_hazard_pointer_clear (mono_hazard_pointer_get (), 1);
+
if (thread == mono_thread_internal_current ()) {
/*
* This will signal async signal handlers that the thread has exited.
mono_profiler_thread_start (tid);
/* if the name was set before starting, we didn't invoke the profiler callback */
- if (internal->name && (internal->flags & MONO_THREAD_FLAG_NAME_SET)) {
+ if (internal->name) {
char *tname = g_utf16_to_utf8 (internal->name, internal->name_len, NULL, NULL, NULL);
mono_profiler_thread_name (internal->tid, tname);
- mono_thread_info_set_name (MONO_UINT_TO_NATIVE_THREAD_ID (internal->tid), tname);
+ mono_native_thread_set_name (MONO_UINT_TO_NATIVE_THREAD_ID (internal->tid), tname);
g_free (tname);
}
+
/* start_func is set only for unmanaged start functions */
if (start_func) {
start_func (start_arg);
*/
THREAD_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") waiting for thread %p (%"G_GSIZE_FORMAT") to start", __func__, mono_native_thread_id_get (), internal, (gsize)internal->tid));
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
WaitForSingleObjectEx (internal->start_notify, INFINITE, FALSE);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
CloseHandle (internal->start_notify);
internal->start_notify = NULL;
}
void
-mono_thread_set_name_internal (MonoInternalThread *this_obj, MonoString *name, gboolean managed, MonoError *error)
+mono_thread_set_name_internal (MonoInternalThread *this_obj, MonoString *name, gboolean permanent, MonoError *error)
{
LOCK_THREAD (this_obj);
mono_error_init (error);
- if ((this_obj->flags & MONO_THREAD_FLAG_NAME_SET) && !this_obj->threadpool_thread) {
+ if ((this_obj->flags & MONO_THREAD_FLAG_NAME_SET)) {
UNLOCK_THREAD (this_obj);
mono_error_set_invalid_operation (error, "Thread.Name can only be set once.");
this_obj->name = g_new (gunichar2, mono_string_length (name));
memcpy (this_obj->name, mono_string_chars (name), mono_string_length (name) * 2);
this_obj->name_len = mono_string_length (name);
+
+ if (permanent)
+ this_obj->flags |= MONO_THREAD_FLAG_NAME_SET;
}
else
this_obj->name = NULL;
- if (managed)
- this_obj->flags |= MONO_THREAD_FLAG_NAME_SET;
UNLOCK_THREAD (this_obj);
if (this_obj->name && this_obj->tid) {
char *tname = mono_string_to_utf8 (name);
mono_profiler_thread_name (this_obj->tid, tname);
- mono_thread_info_set_name (thread_get_tid (this_obj), tname);
+ mono_native_thread_set_name (thread_get_tid (this_obj), tname);
mono_free (tname);
}
}
mono_thread_set_state (cur_thread, ThreadState_WaitSleepJoin);
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
ret=WaitForSingleObjectEx (handle, ms, TRUE);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
mono_thread_clr_state (cur_thread, ThreadState_WaitSleepJoin);
start = (ms == -1) ? 0 : mono_100ns_ticks ();
do {
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
if (multiple)
ret = WaitForMultipleObjectsEx (numhandles, handles, waitall, wait, alertable);
else
ret = WaitForSingleObjectEx (handles [0], ms, alertable);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
if (ret != WAIT_IO_COMPLETION)
break;
mono_thread_set_state (thread, ThreadState_WaitSleepJoin);
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
ret = SignalObjectAndWait (toSignal, toWait, ms, TRUE);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
mono_thread_clr_state (thread, ThreadState_WaitSleepJoin);
THREAD_DEBUG (g_message("%s: %d threads to wait for in this batch", __func__, wait->num));
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
ret=WaitForMultipleObjectsEx(wait->num, wait->handles, TRUE, timeout, TRUE);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
if(ret==WAIT_FAILED) {
/* See the comment in build_wait_tids() */
count++;
}
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
ret=WaitForMultipleObjectsEx (count, wait->handles, FALSE, timeout, TRUE);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
if(ret==WAIT_FAILED) {
/* See the comment in build_wait_tids() */
#endif
abort_appdomain_data user_data;
- guint32 start_time;
+ gint64 start_time;
int orig_timeout = timeout;
int i;
mono_thread_info_clear_self_interrupt ();
}
- if ((thread->state & ThreadState_AbortRequested) != 0) {
+ /* If there's a pending exception and an AbortRequested, the pending exception takes precedence */
+ if (sys_thread->pending_exception) {
+ MonoException *exc;
+
+ exc = sys_thread->pending_exception;
+ sys_thread->pending_exception = NULL;
+
+ UNLOCK_THREAD (thread);
+ return exc;
+ } else if ((thread->state & ThreadState_AbortRequested) != 0) {
UNLOCK_THREAD (thread);
+ g_assert (sys_thread->pending_exception == NULL);
if (thread->abort_exc == NULL) {
/*
* This might be racy, but it has to be called outside the lock
mono_thread_exit ();
return NULL;
- } else if (sys_thread->pending_exception) {
- MonoException *exc;
-
- exc = sys_thread->pending_exception;
- sys_thread->pending_exception = NULL;
-
- UNLOCK_THREAD (thread);
- return exc;
} else if (thread->thread_interrupt_requested) {
thread->thread_interrupt_requested = FALSE;