CloseHandle (handle);
}
-gboolean
-mono_threads_suspend_needs_abort_syscall (void)
-{
- return TRUE;
-}
-
gboolean
mono_threads_suspend_begin_async_resume (MonoThreadInfo *info)
{
}
+#if SIZEOF_VOID_P == 4 && G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
+static gboolean is_wow64 = FALSE;
+#endif
+
+/* We do this at init time to avoid potential races with module opening */
+void
+mono_threads_platform_init (void)
+{
+#if SIZEOF_VOID_P == 4 && G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+ LPFN_ISWOW64PROCESS is_wow64_func = (LPFN_ISWOW64PROCESS) GetProcAddress (GetModuleHandle (TEXT ("kernel32")), "IsWow64Process");
+ if (is_wow64_func)
+ is_wow64_func (GetCurrentProcess (), &is_wow64);
+#endif
+}
+
+/*
+ * When running x86 process under x64 system syscalls are done through WoW64. This
+ * needs to do a transition from x86 mode to x64 so it can syscall into the x64 system.
+ * Apparently this transition invalidates the ESP that we would get from calling
+ * GetThreadContext, so we would fail to scan parts of the thread stack. We attempt
+ * to query whether the thread is in such a transition so we try to restart it later.
+ * We check CONTEXT_EXCEPTION_ACTIVE for this, which is highly undocumented.
+ */
+gboolean
+mono_threads_platform_in_critical_region (MonoNativeThreadId tid)
+{
+ gboolean ret = FALSE;
+#if SIZEOF_VOID_P == 4 && G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+/* FIXME On cygwin these are not defined */
+#if defined(CONTEXT_EXCEPTION_REQUEST) && defined(CONTEXT_EXCEPTION_REPORTING) && defined(CONTEXT_EXCEPTION_ACTIVE)
+ if (is_wow64) {
+ HANDLE handle = OpenThread (THREAD_ALL_ACCESS, FALSE, tid);
+ if (handle) {
+ CONTEXT context;
+ ZeroMemory (&context, sizeof (CONTEXT));
+ context.ContextFlags = CONTEXT_EXCEPTION_REQUEST;
+ if (GetThreadContext (handle, &context)) {
+ if ((context.ContextFlags & CONTEXT_EXCEPTION_REPORTING) &&
+ (context.ContextFlags & CONTEXT_EXCEPTION_ACTIVE))
+ ret = TRUE;
+ }
+ CloseHandle (handle);
+ }
+ }
+#endif
+#endif
+ return ret;
+}
+
gboolean
mono_threads_platform_yield (void)
{