示例#1
0
文件: threadpool.c 项目: mantasp/mono
/* 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;
}
示例#2
0
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;
}
示例#3
0
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);
}
示例#4
0
/* 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;
}