X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Futils%2Fmono-threads-windows.c;h=9f3581e9a3907848b62de857f26aaa6546f60570;hb=00af1bc3675ef335672a3413a2a8fa3c3ca45bb0;hp=02bd26e0c793988c8fc4f2d15ac766df70c5014d;hpb=c0216739390c37ea05a99a4cbc15e2222aac3f11;p=mono.git diff --git a/mono/utils/mono-threads-windows.c b/mono/utils/mono-threads-windows.c index 02bd26e0c79..9f3581e9a39 100755 --- a/mono/utils/mono-threads-windows.c +++ b/mono/utils/mono-threads-windows.c @@ -7,11 +7,10 @@ * (C) 2011 Novell, Inc */ -#include "config.h" +#include -#if defined(HOST_WIN32) +#if defined(USE_WINDOWS_BACKEND) -#include #include #include @@ -27,7 +26,7 @@ interrupt_apc (ULONG_PTR param) } void -mono_threads_core_interrupt (MonoThreadInfo *info) +mono_threads_core_abort_syscall (MonoThreadInfo *info) { DWORD id = mono_thread_info_get_tid (info); HANDLE handle; @@ -40,53 +39,65 @@ mono_threads_core_interrupt (MonoThreadInfo *info) CloseHandle (handle); } -void -mono_threads_core_abort_syscall (MonoThreadInfo *info) -{ -} - gboolean mono_threads_core_needs_abort_syscall (void) { - return FALSE; -} - -void -mono_threads_core_self_suspend (MonoThreadInfo *info) -{ - g_assert_not_reached (); + return TRUE; } gboolean -mono_threads_core_suspend (MonoThreadInfo *info, gboolean interrupt_kernel) +mono_threads_core_begin_async_suspend (MonoThreadInfo *info, gboolean interrupt_kernel) { DWORD id = mono_thread_info_get_tid (info); HANDLE handle; DWORD result; gboolean res; - g_assert (id != GetCurrentThreadId ()); - handle = OpenThread (THREAD_ALL_ACCESS, FALSE, id); g_assert (handle); result = SuspendThread (handle); + THREADS_SUSPEND_DEBUG ("SUSPEND %p -> %d\n", (void*)id, ret); if (result == (DWORD)-1) { - fprintf (stderr, "could not suspend thread %x (handle %p): %d\n", id, handle, GetLastError ()); fflush (stderr); CloseHandle (handle); return FALSE; } - CloseHandle (handle); + /* We're in the middle of a self-suspend, resume and register */ + if (!mono_threads_transition_finish_async_suspend (info)) { + mono_threads_add_to_pending_operation_set (info); + result = ResumeThread (handle); + g_assert (result == 1); + CloseHandle (handle); + THREADS_SUSPEND_DEBUG ("FAILSAFE RESUME/1 %p -> %d\n", (void*)id, 0); + //XXX interrupt_kernel doesn't make sense in this case as the target is not in a syscall + return TRUE; + } + res = mono_threads_get_runtime_callbacks ()->thread_state_init_from_handle (&info->thread_saved_state [ASYNC_SUSPEND_STATE_INDEX], info); + THREADS_SUSPEND_DEBUG ("thread state %p -> %d\n", (void*)id, res); + if (res) { + //FIXME do we need to QueueUserAPC on this case? + if (interrupt_kernel) + QueueUserAPC ((PAPCFUNC)interrupt_apc, handle, (ULONG_PTR)NULL); + } else { + mono_threads_transition_async_suspend_compensation (info); + result = ResumeThread (handle); + g_assert (result == 1); + THREADS_SUSPEND_DEBUG ("FAILSAFE RESUME/2 %p -> %d\n", (void*)info->native_handle, 0); + } - res = mono_threads_get_runtime_callbacks ()->thread_state_init_from_handle (&info->suspend_state, info); - g_assert (res); + CloseHandle (handle); + return res; +} +gboolean +mono_threads_core_check_suspend_result (MonoThreadInfo *info) +{ return TRUE; } gboolean -mono_threads_core_resume (MonoThreadInfo *info) +mono_threads_core_begin_async_resume (MonoThreadInfo *info) { DWORD id = mono_thread_info_get_tid (info); HANDLE handle; @@ -100,7 +111,7 @@ mono_threads_core_resume (MonoThreadInfo *info) CONTEXT context; gboolean res; - ctx = info->suspend_state.ctx; + ctx = info->thread_saved_state [ASYNC_SUSPEND_STATE_INDEX].ctx; mono_threads_get_runtime_callbacks ()->setup_async_callback (&ctx, info->async_target, info->user_data); info->async_target = info->user_data = NULL; @@ -118,17 +129,19 @@ mono_threads_core_resume (MonoThreadInfo *info) context.ContextFlags = CONTEXT_INTEGER | CONTEXT_CONTROL; res = SetThreadContext (handle, &context); - g_assert (res); + if (!res) { + CloseHandle (handle); + return FALSE; + } } result = ResumeThread (handle); - g_assert (result != (DWORD)-1); - CloseHandle (handle); return result != (DWORD)-1; } + void mono_threads_platform_register (MonoThreadInfo *info) { @@ -139,6 +152,20 @@ mono_threads_platform_free (MonoThreadInfo *info) { } +void +mono_threads_core_begin_global_suspend (void) +{ +} + +void +mono_threads_core_end_global_suspend (void) +{ +} + +#endif + +#if defined (HOST_WIN32) + typedef struct { LPTHREAD_START_ROUTINE start_routine; void *arg; @@ -264,7 +291,7 @@ void mono_threads_core_get_stack_bounds (guint8 **staddr, size_t *stsize) { MEMORY_BASIC_INFORMATION meminfo; -#ifdef TARGET_AMD64 +#ifdef _WIN64 /* win7 apis */ NT_TIB* tib = (NT_TIB*)NtCurrentTeb(); guint8 *stackTop = (guint8*)tib->StackBase; @@ -336,7 +363,7 @@ mono_threads_core_open_thread_handle (HANDLE handle, MonoNativeThreadId tid) return OpenThread (THREAD_ALL_ACCESS, TRUE, tid); } -#if !defined(__GNUC__) +#if defined(_MSC_VER) const DWORD MS_VC_EXCEPTION=0x406D1388; #pragma pack(push,8) typedef struct tagTHREADNAME_INFO @@ -352,7 +379,7 @@ typedef struct tagTHREADNAME_INFO void mono_threads_core_set_name (MonoNativeThreadId tid, const char *name) { -#if !defined(__GNUC__) +#if defined(_MSC_VER) /* http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx */ THREADNAME_INFO info; info.dwType = 0x1000;