2005-01-07 Dick Porter <dick@ximian.com>
authorDick Porter <dick@acm.org>
Fri, 7 Jan 2005 15:01:01 +0000 (15:01 -0000)
committerDick Porter <dick@acm.org>
Fri, 7 Jan 2005 15:01:01 +0000 (15:01 -0000)
        * threads.c:
        * monitor.c: Update thread state during Monitor and WaitHandle
        waits.  Fixes bug 71031.

svn path=/trunk/mono/; revision=38491

mono/metadata/ChangeLog
mono/metadata/monitor.c
mono/metadata/threads.c

index 7d50639f00188e89b81db9a54a3173eacd1fba70..9d4319e7cfc30154b652dd2634a02bf7317c9168 100644 (file)
@@ -1,3 +1,9 @@
+2005-01-07  Dick Porter  <dick@ximian.com>
+
+       * threads.c: 
+       * monitor.c: Update thread state during Monitor and WaitHandle
+       waits.  Fixes bug 71031.
+
 2005-01-07  Zoltan Varga  <vargaz@freemail.hu>
 
        * reflection.c (property_encode_signature): Correctly handle when the
index 0d17fb50a02c1b49f79a193a2f51bd71cb567359..a6dc46f4bb4b0a20685d4c78c3a9ac82f8cec9aa 100644 (file)
@@ -15,6 +15,7 @@
 #include <mono/metadata/exception.h>
 #include <mono/metadata/threads.h>
 #include <mono/io-layer/io-layer.h>
+#include <mono/metadata/object-internals.h>
 
 #include <mono/os/gc_wrapper.h>
 
@@ -480,6 +481,7 @@ gboolean ves_icall_System_Threading_Monitor_Monitor_wait(MonoObject *obj,
        guint32 ret;
        gboolean success=FALSE;
        gint32 regain;
+       MonoThread *thread = mono_thread_current ();
        
        MONO_ARCH_SAVE_REGS;
 
@@ -510,6 +512,10 @@ gboolean ves_icall_System_Threading_Monitor_Monitor_wait(MonoObject *obj,
                  GetCurrentThreadId (), event);
 #endif
 
+       mono_monitor_enter (thread->synch_lock);
+       thread->state |= ThreadState_WaitSleepJoin;
+       mono_monitor_exit (thread->synch_lock);
+
        mon->wait_list=g_slist_append (mon->wait_list, event);
        
        /* Save the nest count, and release the lock */
@@ -528,6 +534,13 @@ gboolean ves_icall_System_Threading_Monitor_Monitor_wait(MonoObject *obj,
         * signalled before we wait, we still succeed.
         */
        ret=WaitForSingleObjectEx (event, ms, TRUE);
+
+       /* Reset the thread state fairly early, so we don't have to worry
+        * about the monitor error checking
+        */
+       mono_monitor_enter (thread->synch_lock);
+       thread->state &= ~ThreadState_WaitSleepJoin;
+       mono_monitor_exit (thread->synch_lock);
        
        if (mono_thread_interruption_requested ()) {
                CloseHandle (event);
index 04d9037c8c366a5d4676c4d122f287e169fb6273..b67527cec68e3fe531d3d686c75f6bc35958446b 100644 (file)
@@ -886,6 +886,7 @@ gboolean ves_icall_System_Threading_WaitHandle_WaitAll_internal(MonoArray *mono_
        guint32 i;
        MonoObject *waitHandle;
        MonoClass *klass;
+       MonoThread *thread = mono_thread_current ();
                
        MONO_ARCH_SAVE_REGS;
 
@@ -906,9 +907,17 @@ gboolean ves_icall_System_Threading_WaitHandle_WaitAll_internal(MonoArray *mono_
        if(ms== -1) {
                ms=INFINITE;
        }
+
+       mono_monitor_enter (thread->synch_lock);
+       thread->state |= ThreadState_WaitSleepJoin;
+       mono_monitor_exit (thread->synch_lock);
        
        ret=WaitForMultipleObjectsEx(numhandles, handles, TRUE, ms, TRUE);
 
+       mono_monitor_enter (thread->synch_lock);
+       thread->state &= ~ThreadState_WaitSleepJoin;
+       mono_monitor_exit (thread->synch_lock);
+
        g_free(handles);
 
        if(ret==WAIT_FAILED) {
@@ -942,6 +951,7 @@ gint32 ves_icall_System_Threading_WaitHandle_WaitAny_internal(MonoArray *mono_ha
        guint32 i;
        MonoObject *waitHandle;
        MonoClass *klass;
+       MonoThread *thread = mono_thread_current ();
                
        MONO_ARCH_SAVE_REGS;
 
@@ -963,8 +973,16 @@ gint32 ves_icall_System_Threading_WaitHandle_WaitAny_internal(MonoArray *mono_ha
                ms=INFINITE;
        }
 
+       mono_monitor_enter (thread->synch_lock);
+       thread->state |= ThreadState_WaitSleepJoin;
+       mono_monitor_exit (thread->synch_lock);
+
        ret=WaitForMultipleObjectsEx(numhandles, handles, FALSE, ms, TRUE);
 
+       mono_monitor_enter (thread->synch_lock);
+       thread->state &= ~ThreadState_WaitSleepJoin;
+       mono_monitor_exit (thread->synch_lock);
+
        g_free(handles);
 
 #ifdef THREAD_WAIT_DEBUG
@@ -990,6 +1008,7 @@ gint32 ves_icall_System_Threading_WaitHandle_WaitAny_internal(MonoArray *mono_ha
 gboolean ves_icall_System_Threading_WaitHandle_WaitOne_internal(MonoObject *this, HANDLE handle, gint32 ms, gboolean exitContext)
 {
        guint32 ret;
+       MonoThread *thread = mono_thread_current ();
        
        MONO_ARCH_SAVE_REGS;
 
@@ -1002,7 +1021,15 @@ gboolean ves_icall_System_Threading_WaitHandle_WaitOne_internal(MonoObject *this
                ms=INFINITE;
        }
        
+       mono_monitor_enter (thread->synch_lock);
+       thread->state |= ThreadState_WaitSleepJoin;
+       mono_monitor_exit (thread->synch_lock);
+
        ret=WaitForSingleObjectEx (handle, ms, TRUE);
+       
+       mono_monitor_enter (thread->synch_lock);
+       thread->state &= ~ThreadState_WaitSleepJoin;
+       mono_monitor_exit (thread->synch_lock);
 
        if(ret==WAIT_FAILED) {
 #ifdef THREAD_WAIT_DEBUG