static gint32 managed_thread_id_counter = 0;
+/* Class lazy loading functions */
+static GENERATE_GET_CLASS_WITH_CACHE (appdomain_unloaded_exception, System, AppDomainUnloadedException)
+
static void
mono_threads_lock (void)
{
}
/* FIXME: exitContext isnt documented */
-gboolean ves_icall_System_Threading_WaitHandle_WaitAll_internal(MonoArray *mono_handles, gint32 ms, gboolean exitContext)
+gint32 ves_icall_System_Threading_WaitHandle_WaitAll_internal(MonoArray *mono_handles, gint32 ms, gboolean exitContext)
{
HANDLE *handles;
guint32 numhandles;
g_free(handles);
- if(ret==WAIT_FAILED) {
- THREAD_WAIT_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Wait failed", __func__, mono_native_thread_id_get ()));
- return(FALSE);
- } else if(ret==WAIT_TIMEOUT) {
- THREAD_WAIT_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Wait timed out", __func__, mono_native_thread_id_get ()));
- return(FALSE);
- }
-
- return(TRUE);
+ return ret;
}
/* FIXME: exitContext isnt documented */
}
/* FIXME: exitContext isnt documented */
-gboolean ves_icall_System_Threading_WaitHandle_WaitOne_internal(MonoObject *this_obj, HANDLE handle, gint32 ms, gboolean exitContext)
+gint32 ves_icall_System_Threading_WaitHandle_WaitOne_internal(HANDLE handle, gint32 ms, gboolean exitContext)
{
guint32 ret;
MonoInternalThread *thread = mono_thread_internal_current ();
mono_thread_clr_state (thread, ThreadState_WaitSleepJoin);
- if(ret==WAIT_FAILED) {
- THREAD_WAIT_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Wait failed", __func__, mono_native_thread_id_get ()));
- return(FALSE);
- } else if(ret==WAIT_TIMEOUT) {
- THREAD_WAIT_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Wait timed out", __func__, mono_native_thread_id_get ()));
- return(FALSE);
- }
-
- return(TRUE);
+ return ret;
}
-gboolean
+gint32
ves_icall_System_Threading_WaitHandle_SignalAndWait_Internal (HANDLE toSignal, HANDLE toWait, gint32 ms, gboolean exitContext)
{
guint32 ret;
mono_thread_clr_state (thread, ThreadState_WaitSleepJoin);
- return (!(ret == WAIT_TIMEOUT || ret == WAIT_IO_COMPLETION || ret == WAIT_FAILED));
+ return ret;
}
HANDLE ves_icall_System_Threading_Mutex_CreateMutex_internal (MonoBoolean owned, MonoString *name, MonoBoolean *created)
ves_icall_System_Threading_Interlocked_Exchange_T (MonoObject **location, MonoObject *value)
{
MonoObject *res;
+ MONO_CHECK_NULL (location, NULL);
res = (MonoObject *)InterlockedExchangePointer ((volatile gpointer *)location, value);
mono_gc_wbarrier_generic_nostore (location);
return res;
mono_thread_execute_interruption (void)
{
MonoInternalThread *thread = mono_thread_internal_current ();
+ MonoThread *sys_thread = mono_thread_current ();
LOCK_THREAD (thread);
mono_thread_exit ();
return NULL;
- } else if (thread->pending_exception) {
+ } else if (sys_thread->pending_exception) {
MonoException *exc;
- exc = thread->pending_exception;
- thread->pending_exception = NULL;
+ exc = sys_thread->pending_exception;
+ sys_thread->pending_exception = NULL;
UNLOCK_THREAD (thread);
return exc;
mono_thread_get_and_clear_pending_exception (void)
{
MonoInternalThread *thread = mono_thread_internal_current ();
+ MonoThread *sys_thread = mono_thread_current ();
/* The thread may already be stopping */
if (thread == NULL)
return mono_thread_execute_interruption ();
}
- if (thread->pending_exception) {
- MonoException *exc = thread->pending_exception;
+ if (sys_thread->pending_exception) {
+ MonoException *exc = sys_thread->pending_exception;
- thread->pending_exception = NULL;
+ sys_thread->pending_exception = NULL;
return exc;
}
void
mono_set_pending_exception (MonoException *exc)
{
- MonoInternalThread *thread = mono_thread_internal_current ();
+ MonoThread *thread = mono_thread_current ();
/* The thread may already be stopping */
if (thread == NULL)
MonoJitInfo *ji = NULL;
if (!info)
return NULL;
+
+ /*
+ * The suspended thread might be holding runtime locks. Make sure we don't try taking
+ * any runtime locks while unwinding. In coop case we shouldn't safepoint in regions
+ * where we hold runtime locks.
+ */
+ if (!mono_threads_is_coop_enabled ())
+ mono_thread_info_set_is_async_context (TRUE);
mono_get_eh_callbacks ()->mono_walk_stack_with_state (last_managed, mono_thread_info_get_suspend_state (info), MONO_UNWIND_SIGNAL_SAFE, &ji);
+ if (!mono_threads_is_coop_enabled ())
+ mono_thread_info_set_is_async_context (FALSE);
return ji;
}
static inline gboolean
is_appdomainunloaded_exception (MonoClass *klass)
{
- static MonoClass *app_domain_unloaded_exception_klass = NULL;
-
- if (!app_domain_unloaded_exception_klass)
- app_domain_unloaded_exception_klass = mono_class_from_name (mono_defaults.corlib, "System", "AppDomainUnloadedException");
- g_assert (app_domain_unloaded_exception_klass);
-
- return klass == app_domain_unloaded_exception_klass;
+ return klass == mono_class_get_appdomain_unloaded_exception_class ();
}
static inline gboolean