2009-01-12 Gonzalo Paniagua Javier <gonzalo@novell.com>
[mono.git] / mono / metadata / threads.c
index 17f56971ac329912fdc2db775c08bd5d491409d4..96bdefc0bdce864fdc243e8a0fa6e131dcc9be0a 100644 (file)
@@ -27,6 +27,9 @@
 #include <mono/metadata/gc-internal.h>
 #include <mono/metadata/marshal.h>
 #include <mono/io-layer/io-layer.h>
+#ifndef PLATFORM_WIN32
+#include <mono/io-layer/threads.h>
+#endif
 #include <mono/metadata/object-internals.h>
 #include <mono/metadata/mono-debug-debugger.h>
 #include <mono/utils/mono-compiler.h>
@@ -1270,8 +1273,9 @@ ves_icall_System_Threading_Thread_SetSerializedCurrentUICulture (MonoThread *thi
 MonoThread *
 mono_thread_current (void)
 {
-       THREAD_DEBUG (g_message ("%s: returning %p", __func__, GET_CURRENT_OBJECT ()));
-       return GET_CURRENT_OBJECT ();
+       MonoThread *res = GET_CURRENT_OBJECT ()
+       THREAD_DEBUG (g_message ("%s: returning %p", __func__, res));
+       return res;
 }
 
 gboolean ves_icall_System_Threading_Thread_Join_internal(MonoThread *this,
@@ -2029,6 +2033,15 @@ static void signal_thread_state_change (MonoThread *thread)
 #else
        pthread_kill (thread->tid, mono_thread_get_abort_signal ());
 #endif
+
+       /* 
+        * This will cause waits to be broken.
+        * It will also prevent the thread from entering a wait, so if the thread returns
+        * from the wait before it receives the abort signal, it will just spin in the wait
+        * functions in the io-layer until the signal handler calls QueueUserAPC which will
+        * make it return.
+        */
+       wapi_interrupt_thread (thread->handle);
 #endif /* PLATFORM_WIN32 */
 }
 
@@ -3457,6 +3470,10 @@ static MonoException* mono_thread_execute_interruption (MonoThread *thread)
                WaitForSingleObjectEx (GetCurrentThread(), 0, TRUE);
                InterlockedDecrement (&thread_interruption_requested);
                thread->interruption_requested = FALSE;
+#ifndef PLATFORM_WIN32
+               /* Clear the interrupted flag of the thread so it can wait again */
+               wapi_clear_interruption ();
+#endif
        }
 
        if ((thread->state & ThreadState_AbortRequested) != 0) {