Author: dick
Date: 2007-10-15 10:49:11 -0400 (Mon, 15 Oct 2007)
New Revision: 87516

Modified:
   trunk/mono/mono/metadata/ChangeLog
   trunk/mono/mono/metadata/icall-def.h
   trunk/mono/mono/metadata/monitor.c
   trunk/mono/mono/metadata/object-internals.h
   trunk/mono/mono/metadata/socket-io.c
   trunk/mono/mono/metadata/threads-types.h
   trunk/mono/mono/metadata/threads.c
   trunk/mono/mono/metadata/threads.h
Log:

2007-10-15  Dick Porter  <[EMAIL PROTECTED]>

        * monitor.c (mono_monitor_try_enter_internal): Set thread state to
        WaitSleepJoin while it is waiting to acquire a lock.  Fixes bug
        81646.

        * threads.c: Turn the thread synch_lock into a CRITICAL_SECTION,
        instead of a monitor lock.  This means that monitor_try_enter and
        co can set the thread state safely.
        (ves_icall_System_Threading_Thread_Interrupt_internal): Always set
        thread_interrupt_requested, so interrupt actually works.

        * socket-io.c (ves_icall_System_Net_Sockets_Socket_Poll_internal,
        ves_icall_System_Net_Sockets_Socket_Select_internal): Use thread
        state accessor function



Modified: trunk/mono/mono/metadata/ChangeLog
===================================================================
--- trunk/mono/mono/metadata/ChangeLog  2007-10-15 14:49:07 UTC (rev 87515)
+++ trunk/mono/mono/metadata/ChangeLog  2007-10-15 14:49:11 UTC (rev 87516)
@@ -1,3 +1,19 @@
+2007-10-15  Dick Porter  <[EMAIL PROTECTED]>
+
+       * monitor.c (mono_monitor_try_enter_internal): Set thread state to
+       WaitSleepJoin while it is waiting to acquire a lock.  Fixes bug
+       81646.
+
+       * threads.c: Turn the thread synch_lock into a CRITICAL_SECTION,
+       instead of a monitor lock.  This means that monitor_try_enter and
+       co can set the thread state safely.
+       (ves_icall_System_Threading_Thread_Interrupt_internal): Always set
+       thread_interrupt_requested, so interrupt actually works.
+
+       * socket-io.c (ves_icall_System_Net_Sockets_Socket_Poll_internal,
+       ves_icall_System_Net_Sockets_Socket_Select_internal): Use thread
+       state accessor function
+
 2007-10-15  Martin Baulig  <[EMAIL PROTECTED]>
 
        * mono-debug.h

Modified: trunk/mono/mono/metadata/icall-def.h
===================================================================
--- trunk/mono/mono/metadata/icall-def.h        2007-10-15 14:49:07 UTC (rev 
87515)
+++ trunk/mono/mono/metadata/icall-def.h        2007-10-15 14:49:11 UTC (rev 
87516)
@@ -786,6 +786,7 @@
 ICALL(THREAD_54, "SpinWait_internal", 
ves_icall_System_Threading_Thread_SpinWait_internal)
 ICALL(THREAD_23, "Suspend_internal", ves_icall_System_Threading_Thread_Suspend)
 ICALL(THREAD_24, "Thread_free_internal", 
ves_icall_System_Threading_Thread_Thread_free_internal)
+ICALL(THREAD_24a, "Thread_init", ves_icall_System_Threading_Thread_Thread_init)
 ICALL(THREAD_25, "Thread_internal", 
ves_icall_System_Threading_Thread_Thread_internal)
 ICALL(THREAD_26, "VolatileRead(byte&)", 
ves_icall_System_Threading_Thread_VolatileRead1)
 ICALL(THREAD_27, "VolatileRead(double&)", 
ves_icall_System_Threading_Thread_VolatileRead8)

Modified: trunk/mono/mono/metadata/monitor.c
===================================================================
--- trunk/mono/mono/metadata/monitor.c  2007-10-15 14:49:07 UTC (rev 87515)
+++ trunk/mono/mono/metadata/monitor.c  2007-10-15 14:49:11 UTC (rev 87516)
@@ -332,6 +332,7 @@
        guint32 then = 0, now, delta;
        guint32 waitms;
        guint32 ret;
+       MonoThread *thread = mono_thread_current ();
        
        LOCK_DEBUG (g_message(G_GNUC_PRETTY_FUNCTION
                  ": (%d) Trying to lock object %p (%d ms)", id, obj, ms));
@@ -467,7 +468,7 @@
                        CloseHandle (sem);
                }
        }
-
+       
        /* If we need to time out, record a timestamp and adjust ms,
         * because WaitForSingleObject doesn't tell us how long it
         * waited for.
@@ -490,7 +491,13 @@
        }
        
        InterlockedIncrement (&mon->entry_count);
+
+       mono_thread_set_state (thread, ThreadState_WaitSleepJoin);
+       
        ret = WaitForSingleObjectEx (mon->entry_sem, waitms, 
allow_interruption);
+
+       mono_thread_clr_state (thread, ThreadState_WaitSleepJoin);
+       
        InterlockedDecrement (&mon->entry_count);
 
        if (ms != INFINITE) {
@@ -826,9 +833,9 @@
        LOCK_DEBUG (g_message (G_GNUC_PRETTY_FUNCTION ": (%d) queuing handle 
%p",
                  GetCurrentThreadId (), event));
 
-       mono_monitor_enter (thread->synch_lock);
-       thread->state |= ThreadState_WaitSleepJoin;
-       mono_monitor_exit (thread->synch_lock);
+       mono_thread_current_check_pending_interrupt ();
+       
+       mono_thread_set_state (thread, ThreadState_WaitSleepJoin);
 
        mon->wait_list = g_slist_append (mon->wait_list, event);
        
@@ -850,9 +857,7 @@
        /* 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);
+       mono_thread_clr_state (thread, ThreadState_WaitSleepJoin);
        
        if (mono_thread_interruption_requested ()) {
                CloseHandle (event);

Modified: trunk/mono/mono/metadata/object-internals.h
===================================================================
--- trunk/mono/mono/metadata/object-internals.h 2007-10-15 14:49:07 UTC (rev 
87515)
+++ trunk/mono/mono/metadata/object-internals.h 2007-10-15 14:49:11 UTC (rev 
87516)
@@ -262,7 +262,7 @@
        gpointer suspend_event;
        gpointer suspended_event;
        gpointer resume_event;
-       MonoObject *synch_lock;
+       CRITICAL_SECTION *synch_cs;
        guint8* serialized_culture_info;
        guint32 serialized_culture_info_len;
        guint8* serialized_ui_culture_info;

Modified: trunk/mono/mono/metadata/socket-io.c
===================================================================
--- trunk/mono/mono/metadata/socket-io.c        2007-10-15 14:49:07 UTC (rev 
87515)
+++ trunk/mono/mono/metadata/socket-io.c        2007-10-15 14:49:11 UTC (rev 
87516)
@@ -1156,10 +1156,7 @@
                                thread = mono_thread_current ();
                        }
                        
-                       mono_monitor_enter (thread->synch_lock);
-                       leave = ((thread->state & ThreadState_AbortRequested) 
!= 0 ||
-                                (thread->state & ThreadState_StopRequested) != 
0);
-                       mono_monitor_exit (thread->synch_lock);
+                       leave = mono_thread_test_state (thread, 
ThreadState_AbortRequested | ThreadState_StopRequested);
                        
                        if (leave != 0) {
                                g_free (pfds);
@@ -1550,10 +1547,8 @@
                        if (thread == NULL)
                                thread = mono_thread_current ();
 
-                       mono_monitor_enter (thread->synch_lock);
-                       leave = ((thread->state & ThreadState_AbortRequested) 
!= 0 || 
-                                (thread->state & ThreadState_StopRequested) != 
0);
-                       mono_monitor_exit (thread->synch_lock);
+                       leave = mono_thread_test_state (thread, 
ThreadState_AbortRequested | ThreadState_StopRequested);
+                       
                        if (leave != 0) {
                                g_free (pfds);
                                *sockets = NULL;

Modified: trunk/mono/mono/metadata/threads-types.h
===================================================================
--- trunk/mono/mono/metadata/threads-types.h    2007-10-15 14:49:07 UTC (rev 
87515)
+++ trunk/mono/mono/metadata/threads-types.h    2007-10-15 14:49:11 UTC (rev 
87516)
@@ -43,6 +43,7 @@
 #define SPECIAL_STATIC_CONTEXT 2
 
 extern HANDLE ves_icall_System_Threading_Thread_Thread_internal(MonoThread 
*this_obj, MonoObject *start) MONO_INTERNAL;
+extern void ves_icall_System_Threading_Thread_Thread_init(MonoThread 
*this_obj) MONO_INTERNAL;
 extern void ves_icall_System_Threading_Thread_Thread_free_internal(MonoThread 
*this_obj, HANDLE thread) MONO_INTERNAL;
 extern void ves_icall_System_Threading_Thread_Sleep_internal(int ms) 
MONO_INTERNAL;
 extern gboolean ves_icall_System_Threading_Thread_Join_internal(MonoThread 
*this_obj, int ms, HANDLE thread) MONO_INTERNAL;

Modified: trunk/mono/mono/metadata/threads.c
===================================================================
--- trunk/mono/mono/metadata/threads.c  2007-10-15 14:49:07 UTC (rev 87515)
+++ trunk/mono/mono/metadata/threads.c  2007-10-15 14:49:11 UTC (rev 87516)
@@ -447,13 +447,13 @@
                return;
        mono_release_type_locks (thread);
 
-       if (!mono_monitor_enter (thread->synch_lock))
-               return;
+       EnterCriticalSection (thread->synch_cs);
 
        thread->state |= ThreadState_Stopped;
        thread->state &= ~ThreadState_Background;
-       mono_monitor_exit (thread->synch_lock);
 
+       LeaveCriticalSection (thread->synch_cs);
+       
        mono_profiler_thread_end (thread->tid);
 
        if (thread == mono_thread_current ())
@@ -635,7 +635,8 @@
        thread->apartment_state=ThreadApartmentState_Unknown;
        small_id_alloc (thread);
 
-       MONO_OBJECT_SETREF (thread, synch_lock, mono_object_new (domain, 
mono_defaults.object_class));
+       thread->synch_cs = g_new0 (CRITICAL_SECTION, 1);
+       InitializeCriticalSection (thread->synch_cs);
                                                  
        handle_store(thread);
 
@@ -724,8 +725,10 @@
        thread->apartment_state=ThreadApartmentState_Unknown;
        small_id_alloc (thread);
        thread->stack_ptr = &tid;
-       MONO_OBJECT_SETREF (thread, synch_lock, mono_object_new (domain, 
mono_defaults.object_class));
 
+       thread->synch_cs = g_new0 (CRITICAL_SECTION, 1);
+       InitializeCriticalSection (thread->synch_cs);
+
        THREAD_DEBUG (g_message ("%s: Attached thread ID %"G_GSIZE_FORMAT" 
(handle %p)", __func__, tid, thread_handle));
 
        handle_store(thread);
@@ -792,15 +795,26 @@
        struct StartInfo *start_info;
        HANDLE thread;
        gsize tid;
+       CRITICAL_SECTION *synch_cs;
        
        MONO_ARCH_SAVE_REGS;
 
        THREAD_DEBUG (g_message("%s: Trying to start a new thread: this (%p) 
start (%p)", __func__, this, start));
 
-       mono_monitor_enter (this->synch_lock);
+       synch_cs = g_new0 (CRITICAL_SECTION, 1);
+       InitializeCriticalSection (synch_cs);
 
+       if (InterlockedCompareExchangePointer ((gpointer *)&this->synch_cs,
+                                              synch_cs, NULL) != NULL) {
+               /* This thread must have already been started! */
+               DeleteCriticalSection (synch_cs);
+               g_free (synch_cs);
+       }
+
+       EnterCriticalSection (this->synch_cs);
+
        if ((this->state & ThreadState_Unstarted) == 0) {
-               mono_monitor_exit (this->synch_lock);
+               LeaveCriticalSection (this->synch_cs);
                mono_raise_exception (mono_get_exception_thread_state ("Thread 
has already been started."));
                return NULL;
        }
@@ -808,7 +822,7 @@
        this->small_id = -1;
 
        if ((this->state & ThreadState_Aborted) != 0) {
-               mono_monitor_exit (this->synch_lock);
+               LeaveCriticalSection (this->synch_cs);
                return this;
        }
        start_func = NULL;
@@ -823,7 +837,7 @@
 
                this->start_notify=CreateSemaphore (NULL, 0, 0x7fffffff, NULL);
                if(this->start_notify==NULL) {
-                       mono_monitor_exit (this->synch_lock);
+                       LeaveCriticalSection (this->synch_cs);
                        g_warning ("%s: CreateSemaphore error 0x%x", __func__, 
GetLastError ());
                        return(NULL);
                }
@@ -831,7 +845,7 @@
                thread=CreateThread(NULL, default_stacksize_for_thread (this), 
(LPTHREAD_START_ROUTINE)start_wrapper, start_info,
                                    CREATE_SUSPENDED, &tid);
                if(thread==NULL) {
-                       mono_monitor_exit (this->synch_lock);
+                       LeaveCriticalSection (this->synch_cs);
                        g_warning("%s: CreateThread error 0x%x", __func__, 
GetLastError());
                        return(NULL);
                }
@@ -852,11 +866,19 @@
 
                THREAD_DEBUG (g_message ("%s: Started thread ID 
%"G_GSIZE_FORMAT" (handle %p)", __func__, tid, thread));
 
-               mono_monitor_exit (this->synch_lock);
+               LeaveCriticalSection (this->synch_cs);
                return(thread);
        }
 }
 
+void ves_icall_System_Threading_Thread_Thread_init (MonoThread *this)
+{
+       MONO_ARCH_SAVE_REGS;
+
+       this->synch_cs = g_new0 (CRITICAL_SECTION, 1);
+       InitializeCriticalSection (this->synch_cs);
+}
+
 void ves_icall_System_Threading_Thread_Thread_free_internal (MonoThread *this,
                                                             HANDLE thread)
 {
@@ -865,6 +887,9 @@
        THREAD_DEBUG (g_message ("%s: Closing thread %p, handle %p", __func__, 
this, thread));
 
        CloseHandle (thread);
+
+       DeleteCriticalSection (this->synch_cs);
+       g_free (this->synch_cs);
 }
 
 static void mono_thread_start (MonoThread *thread)
@@ -908,15 +933,11 @@
 
        mono_thread_current_check_pending_interrupt ();
        
-       mono_monitor_enter (thread->synch_lock);
-       thread->state |= ThreadState_WaitSleepJoin;
-       mono_monitor_exit (thread->synch_lock);
+       mono_thread_set_state (thread, ThreadState_WaitSleepJoin);
        
        SleepEx(ms,TRUE);
        
-       mono_monitor_enter (thread->synch_lock);
-       thread->state &= ~ThreadState_WaitSleepJoin;
-       mono_monitor_exit (thread->synch_lock);
+       mono_thread_clr_state (thread, ThreadState_WaitSleepJoin);
 }
 
 void ves_icall_System_Threading_Thread_SpinWait_internal (gint32 iterations)
@@ -943,24 +964,27 @@
 ves_icall_System_Threading_Thread_GetName_internal (MonoThread *this_obj)
 {
        MonoString* str;
-       mono_monitor_enter (this_obj->synch_lock);
+
+       EnterCriticalSection (this_obj->synch_cs);
        
        if (!this_obj->name)
                str = NULL;
        else
                str = mono_string_new_utf16 (mono_domain_get (), 
this_obj->name, this_obj->name_len);
        
-       mono_monitor_exit (this_obj->synch_lock);
+       LeaveCriticalSection (this_obj->synch_cs);
+       
        return str;
 }
 
 void 
 ves_icall_System_Threading_Thread_SetName_internal (MonoThread *this_obj, 
MonoString *name)
 {
-       mono_monitor_enter (this_obj->synch_lock);
+       EnterCriticalSection (this_obj->synch_cs);
        
        if (this_obj->name) {
-               mono_monitor_exit (this_obj->synch_lock);
+               LeaveCriticalSection (this_obj->synch_cs);
+               
                mono_raise_exception (mono_get_exception_invalid_operation 
("Thread.Name can only be set once."));
                return;
        }
@@ -972,7 +996,7 @@
        else
                this_obj->name = NULL;
        
-       mono_monitor_exit (this_obj->synch_lock);
+       LeaveCriticalSection (this_obj->synch_cs);
 }
 
 static MonoObject*
@@ -1004,15 +1028,17 @@
 {
        MonoArray *res;
 
-       mono_monitor_enter (this->synch_lock);
+       EnterCriticalSection (this->synch_cs);
+       
        if (this->serialized_culture_info) {
                res = mono_array_new (mono_domain_get (), 
mono_defaults.byte_class, this->serialized_culture_info_len);
                memcpy (mono_array_addr (res, guint8, 0), 
this->serialized_culture_info, this->serialized_culture_info_len);
        } else {
                res = NULL;
        }
-       mono_monitor_exit (this->synch_lock);
 
+       LeaveCriticalSection (this->synch_cs);
+
        return res;
 }
 
@@ -1025,7 +1051,8 @@
        int free_slot = -1;
        int same_domain_slot = -1;
 
-       mono_monitor_enter (this->synch_lock);
+       EnterCriticalSection (this->synch_cs);
+       
        if (!this->cached_culture_info)
                this->cached_culture_info = mono_array_new (mono_object_domain 
(this), mono_defaults.object_class, NUM_CACHED_CULTURES * 2);
 
@@ -1048,7 +1075,8 @@
        else if (free_slot >= 0)
                mono_array_setref (this->cached_culture_info, free_slot, 
culture);
        /* we may want to replace an existing entry here, even when no suitable 
slot is found */
-       mono_monitor_exit (this->synch_lock);
+
+       LeaveCriticalSection (this->synch_cs);
 }
 
 void
@@ -1060,13 +1088,15 @@
 void
 ves_icall_System_Threading_Thread_SetSerializedCurrentCulture (MonoThread 
*this, MonoArray *arr)
 {
-       mono_monitor_enter (this->synch_lock);
+       EnterCriticalSection (this->synch_cs);
+       
        if (this->serialized_culture_info)
                g_free (this->serialized_culture_info);
        this->serialized_culture_info = g_new0 (guint8, mono_array_length 
(arr));
        this->serialized_culture_info_len = mono_array_length (arr);
        memcpy (this->serialized_culture_info, mono_array_addr (arr, guint8, 
0), mono_array_length (arr));
-       mono_monitor_exit (this->synch_lock);
+
+       LeaveCriticalSection (this->synch_cs);
 }
 
 
@@ -1081,15 +1111,17 @@
 {
        MonoArray *res;
 
-       mono_monitor_enter (this->synch_lock);
+       EnterCriticalSection (this->synch_cs);
+       
        if (this->serialized_ui_culture_info) {
                res = mono_array_new (mono_domain_get (), 
mono_defaults.byte_class, this->serialized_ui_culture_info_len);
                memcpy (mono_array_addr (res, guint8, 0), 
this->serialized_ui_culture_info, this->serialized_ui_culture_info_len);
        } else {
                res = NULL;
        }
-       mono_monitor_exit (this->synch_lock);
 
+       LeaveCriticalSection (this->synch_cs);
+
        return res;
 }
 
@@ -1102,13 +1134,15 @@
 void
 ves_icall_System_Threading_Thread_SetSerializedCurrentUICulture (MonoThread 
*this, MonoArray *arr)
 {
-       mono_monitor_enter (this->synch_lock);
+       EnterCriticalSection (this->synch_cs);
+       
        if (this->serialized_ui_culture_info)
                g_free (this->serialized_ui_culture_info);
        this->serialized_ui_culture_info = g_new0 (guint8, mono_array_length 
(arr));
        this->serialized_ui_culture_info_len = mono_array_length (arr);
        memcpy (this->serialized_ui_culture_info, mono_array_addr (arr, guint8, 
0), mono_array_length (arr));
-       mono_monitor_exit (this->synch_lock);
+
+       LeaveCriticalSection (this->synch_cs);
 }
 
 /* the jit may read the compiled code of this function */
@@ -1125,20 +1159,22 @@
        gboolean ret;
        
        MONO_ARCH_SAVE_REGS;
+       
+       mono_thread_current_check_pending_interrupt ();
 
-       mono_monitor_enter (this->synch_lock);
+       EnterCriticalSection (this->synch_cs);
        
        if ((this->state & ThreadState_Unstarted) != 0) {
-               mono_monitor_exit (this->synch_lock);
+               LeaveCriticalSection (this->synch_cs);
+               
                mono_raise_exception (mono_get_exception_thread_state ("Thread 
has not been started."));
                return FALSE;
        }
        
-       mono_thread_current_check_pending_interrupt ();
-       
        this->state |= ThreadState_WaitSleepJoin;
-       mono_monitor_exit (this->synch_lock);
 
+       LeaveCriticalSection (this->synch_cs);
+
        if(ms== -1) {
                ms=INFINITE;
        }
@@ -1146,9 +1182,7 @@
        
        ret=WaitForSingleObjectEx (thread, ms, TRUE);
 
-       mono_monitor_enter (this->synch_lock);
-       this->state &= ~ThreadState_WaitSleepJoin;
-       mono_monitor_exit (this->synch_lock);
+       mono_thread_clr_state (this, ThreadState_WaitSleepJoin);
        
        if(ret==WAIT_OBJECT_0) {
                THREAD_DEBUG (g_message ("%s: join successful", __func__));
@@ -1188,15 +1222,11 @@
                ms=INFINITE;
        }
 
-       mono_monitor_enter (thread->synch_lock);
-       thread->state |= ThreadState_WaitSleepJoin;
-       mono_monitor_exit (thread->synch_lock);
+       mono_thread_set_state (thread, ThreadState_WaitSleepJoin);
        
        ret=WaitForMultipleObjectsEx(numhandles, handles, TRUE, ms, TRUE);
 
-       mono_monitor_enter (thread->synch_lock);
-       thread->state &= ~ThreadState_WaitSleepJoin;
-       mono_monitor_exit (thread->synch_lock);
+       mono_thread_clr_state (thread, ThreadState_WaitSleepJoin);
 
        g_free(handles);
 
@@ -1243,16 +1273,12 @@
                ms=INFINITE;
        }
 
-       mono_monitor_enter (thread->synch_lock);
-       thread->state |= ThreadState_WaitSleepJoin;
-       mono_monitor_exit (thread->synch_lock);
-
+       mono_thread_set_state (thread, ThreadState_WaitSleepJoin);
+       
        ret=WaitForMultipleObjectsEx(numhandles, handles, FALSE, ms, TRUE);
 
-       mono_monitor_enter (thread->synch_lock);
-       thread->state &= ~ThreadState_WaitSleepJoin;
-       mono_monitor_exit (thread->synch_lock);
-
+       mono_thread_clr_state (thread, ThreadState_WaitSleepJoin);
+       
        g_free(handles);
 
        THREAD_WAIT_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") returning %d", 
__func__, GetCurrentThreadId (), ret));
@@ -1287,16 +1313,12 @@
        
        mono_thread_current_check_pending_interrupt ();
 
-       mono_monitor_enter (thread->synch_lock);
-       thread->state |= ThreadState_WaitSleepJoin;
-       mono_monitor_exit (thread->synch_lock);
-
+       mono_thread_set_state (thread, ThreadState_WaitSleepJoin);
+       
        ret=WaitForSingleObjectEx (handle, ms, TRUE);
        
-       mono_monitor_enter (thread->synch_lock);
-       thread->state &= ~ThreadState_WaitSleepJoin;
-       mono_monitor_exit (thread->synch_lock);
-
+       mono_thread_clr_state (thread, ThreadState_WaitSleepJoin);
+       
        if(ret==WAIT_FAILED) {
                THREAD_WAIT_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Wait 
failed", __func__, GetCurrentThreadId ()));
                return(FALSE);
@@ -1735,8 +1757,8 @@
 void
 ves_icall_System_Threading_Thread_ClrState (MonoThread* this, guint32 state)
 {
-       mono_monitor_enter (this->synch_lock);
-       this->state &= ~state;
+       mono_thread_clr_state (this, state);
+
        if (state & ThreadState_Background) {
                /* If the thread changes the background mode, the main thread 
has to
                 * be notified, since it has to rebuild the list of threads to
@@ -1744,14 +1766,13 @@
                 */
                SetEvent (background_change_event);
        }
-       mono_monitor_exit (this->synch_lock);
 }
 
 void
 ves_icall_System_Threading_Thread_SetState (MonoThread* this, guint32 state)
 {
-       mono_monitor_enter (this->synch_lock);
-       this->state |= state;
+       mono_thread_set_state (this, state);
+       
        if (state & ThreadState_Background) {
                /* If the thread changes the background mode, the main thread 
has to
                 * be notified, since it has to rebuild the list of threads to
@@ -1759,16 +1780,19 @@
                 */
                SetEvent (background_change_event);
        }
-       mono_monitor_exit (this->synch_lock);
 }
 
 guint32
 ves_icall_System_Threading_Thread_GetState (MonoThread* this)
 {
        guint32 state;
-       mono_monitor_enter (this->synch_lock);
+
+       EnterCriticalSection (this->synch_cs);
+       
        state = this->state;
-       mono_monitor_exit (this->synch_lock);
+
+       LeaveCriticalSection (this->synch_cs);
+       
        return state;
 }
 
@@ -1776,19 +1800,16 @@
 {
        gboolean throw = FALSE;
        
-       mono_monitor_enter (this->synch_lock);
+       EnterCriticalSection (this->synch_cs);
        
-       /* Clear out any previous request */
-       this->thread_interrupt_requested = FALSE;
+       this->thread_interrupt_requested = TRUE;
        
        if (this->state & ThreadState_WaitSleepJoin) {
                throw = TRUE;
-       } else {
-               this->thread_interrupt_requested = TRUE;
        }
        
-       mono_monitor_exit (this->synch_lock);
-
+       LeaveCriticalSection (this->synch_cs);
+       
        if (throw) {
                signal_thread_state_change (this);
        }
@@ -1799,14 +1820,14 @@
        MonoThread *thread = mono_thread_current ();
        gboolean throw = FALSE;
        
-       mono_monitor_enter (thread->synch_lock);
-
+       EnterCriticalSection (thread->synch_cs);
+       
        if (thread->thread_interrupt_requested) {
                throw = TRUE;
                thread->thread_interrupt_requested = FALSE;
        }
        
-       mono_monitor_exit (thread->synch_lock);
+       LeaveCriticalSection (thread->synch_cs);
 
        if (throw) {
                mono_raise_exception (mono_get_exception_thread_interrupted ());
@@ -1881,19 +1902,19 @@
 {
        MONO_ARCH_SAVE_REGS;
 
-       mono_monitor_enter (thread->synch_lock);
-
+       EnterCriticalSection (thread->synch_cs);
+       
        if ((thread->state & ThreadState_AbortRequested) != 0 || 
                (thread->state & ThreadState_StopRequested) != 0 ||
                (thread->state & ThreadState_Stopped) != 0)
        {
-               mono_monitor_exit (thread->synch_lock);
+               LeaveCriticalSection (thread->synch_cs);
                return;
        }
 
        if ((thread->state & ThreadState_Unstarted) != 0) {
                thread->state |= ThreadState_Aborted;
-               mono_monitor_exit (thread->synch_lock);
+               LeaveCriticalSection (thread->synch_cs);
                return;
        }
 
@@ -1901,7 +1922,7 @@
        MONO_OBJECT_SETREF (thread, abort_state, state);
        thread->abort_exc = NULL;
 
-       mono_monitor_exit (thread->synch_lock);
+       LeaveCriticalSection (thread->synch_cs);
 
        THREAD_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Abort requested for 
%p (%"G_GSIZE_FORMAT")", __func__, GetCurrentThreadId (), thread, 
(gsize)thread->tid));
        
@@ -1918,20 +1939,20 @@
 
        MONO_ARCH_SAVE_REGS;
        
-       mono_monitor_enter (thread->synch_lock);
+       EnterCriticalSection (thread->synch_cs);
 
        thread->state &= ~ThreadState_AbortRequested;
        
        if (!thread->abort_exc) {
                const char *msg = "Unable to reset abort because no abort was 
requested";
-               mono_monitor_exit (thread->synch_lock);
+               LeaveCriticalSection (thread->synch_cs);
                mono_raise_exception (mono_get_exception_thread_state (msg));
        } else {
                thread->abort_exc = NULL;
                thread->abort_state = NULL;
        }
        
-       mono_monitor_exit (thread->synch_lock);
+       LeaveCriticalSection (thread->synch_cs);
 }
 
 static gboolean
@@ -1939,13 +1960,13 @@
 {
        MONO_ARCH_SAVE_REGS;
 
-       mono_monitor_enter (thread->synch_lock);
+       EnterCriticalSection (thread->synch_cs);
 
        if ((thread->state & ThreadState_Unstarted) != 0 || 
                (thread->state & ThreadState_Aborted) != 0 || 
                (thread->state & ThreadState_Stopped) != 0)
        {
-               mono_monitor_exit (thread->synch_lock);
+               LeaveCriticalSection (thread->synch_cs);
                return FALSE;
        }
 
@@ -1953,13 +1974,14 @@
                (thread->state & ThreadState_SuspendRequested) != 0 ||
                (thread->state & ThreadState_StopRequested) != 0) 
        {
-               mono_monitor_exit (thread->synch_lock);
+               LeaveCriticalSection (thread->synch_cs);
                return TRUE;
        }
        
        thread->state |= ThreadState_SuspendRequested;
-       mono_monitor_exit (thread->synch_lock);
 
+       LeaveCriticalSection (thread->synch_cs);
+
        signal_thread_state_change (thread);
        return TRUE;
 }
@@ -1976,11 +1998,11 @@
 {
        MONO_ARCH_SAVE_REGS;
 
-       mono_monitor_enter (thread->synch_lock);
+       EnterCriticalSection (thread->synch_cs);
 
        if ((thread->state & ThreadState_SuspendRequested) != 0) {
                thread->state &= ~ThreadState_SuspendRequested;
-               mono_monitor_exit (thread->synch_lock);
+               LeaveCriticalSection (thread->synch_cs);
                return TRUE;
        }
 
@@ -1989,20 +2011,20 @@
                (thread->state & ThreadState_Aborted) != 0 || 
                (thread->state & ThreadState_Stopped) != 0)
        {
-               mono_monitor_exit (thread->synch_lock);
+               LeaveCriticalSection (thread->synch_cs);
                return FALSE;
        }
        
        thread->resume_event = CreateEvent (NULL, TRUE, FALSE, NULL);
        if (thread->resume_event == NULL) {
-               mono_monitor_exit (thread->synch_lock);
+               LeaveCriticalSection (thread->synch_cs);
                return(FALSE);
        }
        
        /* Awake the thread */
        SetEvent (thread->suspend_event);
 
-       mono_monitor_exit (thread->synch_lock);
+       LeaveCriticalSection (thread->synch_cs);
 
        /* Wait for the thread to awake */
        WaitForSingleObject (thread->resume_event, INFINITE);
@@ -2045,12 +2067,12 @@
 
 void mono_thread_stop (MonoThread *thread)
 {
-       mono_monitor_enter (thread->synch_lock);
+       EnterCriticalSection (thread->synch_cs);
 
        if ((thread->state & ThreadState_StopRequested) != 0 ||
                (thread->state & ThreadState_Stopped) != 0)
        {
-               mono_monitor_exit (thread->synch_lock);
+               LeaveCriticalSection (thread->synch_cs);
                return;
        }
        
@@ -2060,7 +2082,7 @@
        thread->state |= ThreadState_StopRequested;
        thread->state &= ~ThreadState_AbortRequested;
        
-       mono_monitor_exit (thread->synch_lock);
+       LeaveCriticalSection (thread->synch_cs);
        
        signal_thread_state_change (thread);
 }
@@ -2134,6 +2156,7 @@
        InitializeCriticalSection(&contexts_mutex);
        InitializeCriticalSection(&delayed_free_table_mutex);
        InitializeCriticalSection(&small_id_mutex);
+       
        background_change_event = CreateEvent (NULL, TRUE, FALSE, NULL);
        g_assert(background_change_event != NULL);
        
@@ -2528,13 +2551,13 @@
                        continue;
                }
 
-               mono_monitor_enter (thread->synch_lock);
+               EnterCriticalSection (thread->synch_cs);
 
                if ((thread->state & ThreadState_Suspended) != 0 || 
                        (thread->state & ThreadState_SuspendRequested) != 0 ||
                        (thread->state & ThreadState_StopRequested) != 0 ||
                        (thread->state & ThreadState_Stopped) != 0) {
-                       mono_monitor_exit (thread->synch_lock);
+                       LeaveCriticalSection (thread->synch_cs);
                        CloseHandle (wait->handles [i]);
                        wait->threads [i] = NULL; /* ignore this thread in next 
loop */
                        continue;
@@ -2550,13 +2573,13 @@
                        thread->suspended_event = CreateEvent (NULL, TRUE, 
FALSE, NULL);
                        if (thread->suspended_event == NULL) {
                                /* Forget this one and go on to the next */
-                               mono_monitor_exit (thread->synch_lock);
+                               LeaveCriticalSection (thread->synch_cs);
                                continue;
                        }
                }
 
                events [eventidx++] = thread->suspended_event;
-               mono_monitor_exit (thread->synch_lock);
+               LeaveCriticalSection (thread->synch_cs);
 
                /* Signal the thread to suspend */
                signal_thread_state_change (thread);
@@ -2569,10 +2592,10 @@
                if (thread == NULL)
                        continue;
 
-               mono_monitor_enter (thread->synch_lock);
+               EnterCriticalSection (thread->synch_cs);
                CloseHandle (thread->suspended_event);
                thread->suspended_event = NULL;
-               mono_monitor_exit (thread->synch_lock);
+               LeaveCriticalSection (thread->synch_cs);
        }
 
        g_free (events);
@@ -2739,7 +2762,7 @@
        int i;
 
        /* No locking needed here */
-       /* FIXME: why no locking? writes to the cache are protected with 
synch_lock above */
+       /* FIXME: why no locking? writes to the cache are protected with 
synch_cs above */
 
        if (thread->cached_culture_info) {
                for (i = 0; i < NUM_CACHED_CULTURES * 2; ++i) {
@@ -3116,7 +3139,7 @@
  */
 static MonoException* mono_thread_execute_interruption (MonoThread *thread)
 {
-       mono_monitor_enter (thread->synch_lock);
+       EnterCriticalSection (thread->synch_cs);
 
        if (thread->interruption_requested) {
                /* this will consume pending APC calls */
@@ -3128,7 +3151,7 @@
        if ((thread->state & ThreadState_AbortRequested) != 0) {
                if (thread->abort_exc == NULL)
                        MONO_OBJECT_SETREF (thread, abort_exc, 
mono_get_exception_thread_abort ());
-               mono_monitor_exit (thread->synch_lock);
+               LeaveCriticalSection (thread->synch_cs);
                return thread->abort_exc;
        }
        else if ((thread->state & ThreadState_SuspendRequested) != 0) {
@@ -3136,16 +3159,18 @@
                thread->state |= ThreadState_Suspended;
                thread->suspend_event = CreateEvent (NULL, TRUE, FALSE, NULL);
                if (thread->suspend_event == NULL) {
-                       mono_monitor_exit (thread->synch_lock);
+                       LeaveCriticalSection (thread->synch_cs);
                        return(NULL);
                }
                if (thread->suspended_event)
                        SetEvent (thread->suspended_event);
-               mono_monitor_exit (thread->synch_lock);
+
+               LeaveCriticalSection (thread->synch_cs);
                
                WaitForSingleObject (thread->suspend_event, INFINITE);
                
-               mono_monitor_enter (thread->synch_lock);
+               EnterCriticalSection (thread->synch_cs);
+
                CloseHandle (thread->suspend_event);
                thread->suspend_event = NULL;
                thread->state &= ~ThreadState_Suspended;
@@ -3154,20 +3179,27 @@
                 * and will be waiting for it
                 */
                SetEvent (thread->resume_event);
-               mono_monitor_exit (thread->synch_lock);
+
+               LeaveCriticalSection (thread->synch_cs);
+               
                return NULL;
        }
        else if ((thread->state & ThreadState_StopRequested) != 0) {
                /* FIXME: do this through the JIT? */
-               mono_monitor_exit (thread->synch_lock);
+
+               LeaveCriticalSection (thread->synch_cs);
+               
                mono_thread_exit ();
                return NULL;
        } else if (thread->thread_interrupt_requested) {
-               mono_monitor_exit (thread->synch_lock);
+
+               LeaveCriticalSection (thread->synch_cs);
+               
                return(mono_get_exception_thread_interrupted ());
        }
        
-       mono_monitor_exit (thread->synch_lock);
+       LeaveCriticalSection (thread->synch_cs);
+       
        return NULL;
 }
 
@@ -3187,10 +3219,11 @@
        if (thread == NULL) 
                return NULL;
        
-       mono_monitor_enter (thread->synch_lock);
+       EnterCriticalSection (thread->synch_cs);
        
        if (thread->interruption_requested) {
-               mono_monitor_exit (thread->synch_lock);
+               LeaveCriticalSection (thread->synch_cs);
+               
                return NULL;
        }
 
@@ -3201,15 +3234,17 @@
 
                InterlockedIncrement (&thread_interruption_requested);
                thread->interruption_requested = TRUE;
-               mono_monitor_exit (thread->synch_lock);
 
+               LeaveCriticalSection (thread->synch_cs);
+
                /* this will awake the thread if it is in WaitForSingleObject 
                   or similar */
                QueueUserAPC ((PAPCFUNC)dummy_apc, thread->handle, NULL);
                return NULL;
        }
        else {
-               mono_monitor_exit (thread->synch_lock);
+               LeaveCriticalSection (thread->synch_cs);
+               
                return mono_thread_execute_interruption (thread);
        }
 }
@@ -3303,3 +3338,35 @@
        }
 #endif
 }
+
+void
+mono_thread_set_state (MonoThread *thread, MonoThreadState state)
+{
+       EnterCriticalSection (thread->synch_cs);
+       thread->state |= state;
+       LeaveCriticalSection (thread->synch_cs);
+}
+
+void
+mono_thread_clr_state (MonoThread *thread, MonoThreadState state)
+{
+       EnterCriticalSection (thread->synch_cs);
+       thread->state &= ~state;
+       LeaveCriticalSection (thread->synch_cs);
+}
+
+gboolean
+mono_thread_test_state (MonoThread *thread, MonoThreadState test)
+{
+       gboolean ret = FALSE;
+
+       EnterCriticalSection (thread->synch_cs);
+
+       if ((thread->state & test) != 0) {
+               ret = TRUE;
+       }
+       
+       LeaveCriticalSection (thread->synch_cs);
+       
+       return ret;
+}

Modified: trunk/mono/mono/metadata/threads.h
===================================================================
--- trunk/mono/mono/metadata/threads.h  2007-10-15 14:49:07 UTC (rev 87515)
+++ trunk/mono/mono/metadata/threads.h  2007-10-15 14:49:11 UTC (rev 87516)
@@ -14,6 +14,7 @@
 #include <mono/utils/mono-membar.h>
 #include <mono/metadata/object.h>
 #include <mono/metadata/appdomain.h>
+#include <mono/metadata/threads-types.h>
 
 G_BEGIN_DECLS
 
@@ -66,6 +67,10 @@
 extern void mono_thread_force_interruption_checkpoint (void);
 extern gint32* mono_thread_interruption_request_flag (void);
 
+extern void mono_thread_set_state (MonoThread *thread, MonoThreadState state);
+extern void mono_thread_clr_state (MonoThread *thread, MonoThreadState state);
+extern gboolean mono_thread_test_state (MonoThread *thread, MonoThreadState 
test);
+
 G_END_DECLS
 
 #endif /* _MONO_METADATA_THREADS_H_ */

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to