/* Returns the exception thrown when invoking, if any */ static MonoObject * mono_async_invoke (ThreadPool *tp, MonoAsyncResult *ares) { ASyncCall *ac = (ASyncCall *)ares->object_data; MonoObject *res, *exc = NULL; MonoArray *out_args = NULL; HANDLE wait_event = NULL; if (ares->execution_context) { /* use captured ExecutionContext (if available) */ MONO_OBJECT_SETREF (ares, original_context, mono_thread_get_execution_context ()); mono_thread_set_execution_context (ares->execution_context); } else { ares->original_context = NULL; } if (ac == NULL) { /* Fast path from ThreadPool.*QueueUserWorkItem */ void *pa = ares->async_state; mono_runtime_delegate_invoke (ares->async_delegate, &pa, &exc); } else { MonoObject *cb_exc = NULL; ac->msg->exc = NULL; res = mono_message_invoke (ares->async_delegate, ac->msg, &exc, &out_args); MONO_OBJECT_SETREF (ac, res, res); MONO_OBJECT_SETREF (ac, msg->exc, exc); MONO_OBJECT_SETREF (ac, out_args, out_args); mono_monitor_enter ((MonoObject *) ares); ares->completed = 1; if (ares->handle != NULL) wait_event = mono_wait_handle_get_handle ((MonoWaitHandle *) ares->handle); mono_monitor_exit ((MonoObject *) ares); /* notify listeners */ if (wait_event != NULL) SetEvent (wait_event); /* call async callback if cb_method != null*/ if (ac != NULL && ac->cb_method) { void *pa = &ares; cb_exc = NULL; mono_runtime_invoke (ac->cb_method, ac->cb_target, pa, &cb_exc); MONO_OBJECT_SETREF (ac->msg, exc, cb_exc); exc = cb_exc; } else { exc = NULL; } } /* restore original thread execution context if flow isn't suppressed, i.e. non null */ if (ares->original_context) { mono_thread_set_execution_context (ares->original_context); ares->original_context = NULL; } return exc; }
MonoObject* ml_delegate_invoke(MonoObject *method, void **params) { MonoObject *ret, *exception; ret = mono_runtime_delegate_invoke(method, params, &exception); if (exception) { purple_debug(PURPLE_DEBUG_ERROR, "mono", "caught exception: %s\n", mono_class_get_name(mono_object_get_class(exception))); } return ret; }
static void fire_process_exit_event (MonoDomain *domain, gpointer user_data) { MonoClassField *field; gpointer pa [2]; MonoObject *delegate, *exc; field = mono_class_get_field_from_name (mono_defaults.appdomain_class, "ProcessExit"); g_assert (field); delegate = *(MonoObject **)(((char *)domain->domain) + field->offset); if (delegate == NULL) return; pa [0] = domain; pa [1] = NULL; mono_runtime_delegate_invoke (delegate, pa, &exc); }
/* Returns the exception thrown when invoking, if any */ static MonoObject * mono_async_invoke (ThreadPool *tp, MonoAsyncResult *ares) { ASyncCall *ac = (ASyncCall *)ares->object_data; MonoObject *res, *exc = NULL; MonoArray *out_args = NULL; HANDLE wait_event = NULL; MonoInternalThread *thread = mono_thread_internal_current (); if (ares->execution_context) { /* use captured ExecutionContext (if available) */ MONO_OBJECT_SETREF (ares, original_context, mono_thread_get_execution_context ()); mono_thread_set_execution_context (ares->execution_context); } else { ares->original_context = NULL; } if (ac == NULL) { /* Fast path from ThreadPool.*QueueUserWorkItem */ void *pa = ares->async_state; /* The debugger needs this */ thread->async_invoke_method = ((MonoDelegate*)ares->async_delegate)->method; res = mono_runtime_delegate_invoke (ares->async_delegate, &pa, &exc); thread->async_invoke_method = NULL; } else { MonoObject *cb_exc = NULL; ac->msg->exc = NULL; res = mono_message_invoke (ares->async_delegate, ac->msg, &exc, &out_args); MONO_OBJECT_SETREF (ac, res, res); MONO_OBJECT_SETREF (ac, msg->exc, exc); MONO_OBJECT_SETREF (ac, out_args, out_args); mono_monitor_enter ((MonoObject *) ares); ares->completed = 1; if (ares->handle != NULL) wait_event = mono_wait_handle_get_handle ((MonoWaitHandle *) ares->handle); mono_monitor_exit ((MonoObject *) ares); /* notify listeners */ if (wait_event != NULL) SetEvent (wait_event); /* call async callback if cb_method != null*/ if (ac != NULL && ac->cb_method) { void *pa = &ares; cb_exc = NULL; thread->async_invoke_method = ac->cb_method; mono_runtime_invoke (ac->cb_method, ac->cb_target, pa, &cb_exc); thread->async_invoke_method = NULL; exc = cb_exc; } else { exc = NULL; } } /* restore original thread execution context if flow isn't suppressed, i.e. non null */ if (ares->original_context) { mono_thread_set_execution_context (ares->original_context); ares->original_context = NULL; } #if DEBUG InterlockedDecrement (&tp->njobs); #endif if (!tp->is_io) InterlockedIncrement (&tp->nexecuted); if (InterlockedDecrement (&monitor_njobs) == 0) monitor_state = MONITOR_STATE_FALLING_ASLEEP; return exc; }