Beispiel #1
0
/*
 * This is a very specific function whose only purpose is to
 * break a given thread from socket syscalls.
 *
 * This only exists because linux won't fail a call to connect
 * if the underlying is closed.
 *
 * TODO We should cleanup and unify this with the other syscall abort
 * facility.
 */
void
mono_thread_info_abort_socket_syscall_for_close (MonoNativeThreadId tid)
{
	MonoThreadHazardPointers *hp;
	MonoThreadInfo *info;

	if (tid == mono_native_thread_id_get () || !mono_threads_suspend_needs_abort_syscall ())
		return;

	hp = mono_hazard_pointer_get ();
	info = mono_thread_info_lookup (tid);
	if (!info)
		return;

	if (mono_thread_info_run_state (info) == STATE_DETACHED) {
		mono_hazard_pointer_clear (hp, 1);
		return;
	}

	mono_thread_info_suspend_lock ();
	mono_threads_begin_global_suspend ();

	mono_threads_suspend_abort_syscall (info);
	mono_threads_wait_pending_operations ();

	mono_hazard_pointer_clear (hp, 1);

	mono_threads_end_global_suspend ();
	mono_thread_info_suspend_unlock ();
}
Beispiel #2
0
/*
The return value is only valid until a matching mono_thread_info_resume is called
*/
static MonoThreadInfo*
suspend_sync (MonoNativeThreadId tid, gboolean interrupt_kernel)
{
	MonoThreadHazardPointers *hp = mono_hazard_pointer_get ();
	MonoThreadInfo *info = mono_thread_info_lookup (tid); /*info on HP1*/
	if (!info)
		return NULL;

	switch (mono_threads_transition_request_async_suspension (info)) {
	case AsyncSuspendAlreadySuspended:
		mono_hazard_pointer_clear (hp, 1); //XXX this is questionable we got to clean the suspend/resume nonsense of critical sections
		return info;
	case AsyncSuspendWait:
		mono_threads_add_to_pending_operation_set (info);
		break;
	case AsyncSuspendInitSuspend:
		if (!begin_async_suspend (info, interrupt_kernel)) {
			mono_hazard_pointer_clear (hp, 1);
			return NULL;
		}
		break;
	case AsyncSuspendBlocking:
		if (interrupt_kernel && mono_threads_suspend_needs_abort_syscall ())
			mono_threads_suspend_abort_syscall (info);

		break;
	default:
		g_assert_not_reached ();
	}

	//Wait for the pending suspend to finish
	mono_threads_wait_pending_operations ();

	if (!check_async_suspend (info)) {
		mono_thread_info_core_resume (info);
		mono_threads_wait_pending_operations ();
		mono_hazard_pointer_clear (hp, 1);
		return NULL;
	}
	return info;
}