Author: miguel
Date: 2005-04-19 15:09:37 -0400 (Tue, 19 Apr 2005)
New Revision: 43282

Modified:
   trunk/mono/mono/metadata/object-internals.h
   trunk/mono/mono/metadata/threads.c
Log:
First part of commit of patch from Zoltan Varga from bug:

http://bugzilla.ximian.com/show_bug.cgi?id=71274




Modified: trunk/mono/mono/metadata/object-internals.h
===================================================================
--- trunk/mono/mono/metadata/object-internals.h 2005-04-19 18:58:24 UTC (rev 
43281)
+++ trunk/mono/mono/metadata/object-internals.h 2005-04-19 19:09:37 UTC (rev 
43282)
@@ -239,6 +239,7 @@
        GSList *appdomain_refs;
        MonoBoolean interruption_requested;
        gpointer suspend_event;
+       gpointer suspended_event;
        gpointer resume_event;
        MonoObject *synch_lock;
        guint8* serialized_culture_info;

Modified: trunk/mono/mono/metadata/threads.c
===================================================================
--- trunk/mono/mono/metadata/threads.c  2005-04-19 18:58:24 UTC (rev 43281)
+++ trunk/mono/mono/metadata/threads.c  2005-04-19 19:09:37 UTC (rev 43282)
@@ -1797,13 +1797,22 @@
        LeaveCriticalSection (&threads_mutex);
 }
 
-static void suspend_thread (gpointer key, gpointer value, gpointer user)
+static void
+collect_threads (gpointer key, gpointer value, gpointer user_data)
 {
-       MonoThread *thread=(MonoThread *)value;
-       guint32 self=GPOINTER_TO_UINT (user);
-       
-       if ((thread->tid!=self) && !mono_gc_is_finalizer_thread (thread))
-               SuspendThread (thread->handle);
+       MonoThread *thread = (MonoThread*)value;
+       struct wait_data *wait = (struct wait_data*)user_data;
+       HANDLE handle;
+
+       if (wait->num<MAXIMUM_WAIT_OBJECTS) {
+               handle = OpenThread (THREAD_ALL_ACCESS, TRUE, thread->tid);
+               if (handle == NULL)
+                       return;
+
+               wait->handles [wait->num] = handle;
+               wait->threads [wait->num] = thread;
+               wait->num++;
+       }
 }
 
 /*
@@ -1813,12 +1822,64 @@
  */
 void mono_thread_suspend_all_other_threads (void)
 {
-       guint32 self=GetCurrentThreadId ();
+       struct wait_data *wait = g_new0 (struct wait_data, 1);
+       int i, waitnum;
+       guint32 self = GetCurrentThreadId ();
 
-       EnterCriticalSection (&threads_mutex);
-       mono_g_hash_table_foreach (threads, suspend_thread,
-                                  GUINT_TO_POINTER (self));
-       LeaveCriticalSection (&threads_mutex);
+       do {
+               /* 
+                * Make a copy of the hashtable since we can't do anything with
+                * threads while threads_mutex is held.
+                */
+               EnterCriticalSection (&threads_mutex);
+               mono_g_hash_table_foreach (threads, collect_threads, wait);
+               LeaveCriticalSection (&threads_mutex);
+
+               waitnum = 0;
+               for (i = 0; i < wait->num; ++i) {
+                       MonoThread *thread = wait->threads [i];
+
+                       if ((thread->tid == self) || 
mono_gc_is_finalizer_thread (thread)) {
+                               //CloseHandle (wait->handles [i]);
+                               continue;
+                       }
+
+                       mono_monitor_enter (thread->synch_lock);
+
+                       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);
+                               CloseHandle (wait->handles [i]);
+                               continue;
+                       }
+       
+                       thread->state |= ThreadState_SuspendRequested;
+
+                       //printf ("S: %d\n", thread->state);
+                       thread->suspended_event = CreateEvent (NULL, TRUE, 
FALSE, NULL);
+
+                       mono_monitor_exit (thread->synch_lock);
+
+                       /* Signal the thread to suspend */
+                       signal_thread_state_change (thread);
+
+                       /* Wait for it to become suspended */
+                       //printf ("W1\n");
+                       WaitForSingleObject (thread->suspended_event, INFINITE);
+                       //printf ("W2\n");
+
+                       CloseHandle (thread->suspended_event);
+                       thread->suspended_event = NULL;
+
+                       CloseHandle (wait->handles [i]);
+                       
+                       waitnum ++;
+               }
+       } while (waitnum > 0);
+
+       g_free (wait);
 }
 
 /*
@@ -2266,6 +2327,8 @@
                thread->state &= ~ThreadState_SuspendRequested;
                thread->state |= ThreadState_Suspended;
                thread->suspend_event = CreateEvent (NULL, TRUE, FALSE, NULL);
+               if (thread->suspended_event)
+                       SetEvent (thread->suspended_event);
                mono_monitor_exit (thread->synch_lock);
                
                WaitForSingleObject (thread->suspend_event, INFINITE);
@@ -2327,7 +2390,7 @@
                
                thread->interruption_requested = TRUE;
                mono_monitor_exit (thread->synch_lock);
-               
+
                /* this will awake the thread if it is in WaitForSingleObject 
               or similar */
                QueueUserAPC ((PAPCFUNC)dummy_apc, thread->handle, NULL);
@@ -2356,7 +2419,7 @@
        MonoThread *thread = mono_thread_current ();
 
        /* The thread may already be stopping */
-       if (thread == NULL) 
+       if (thread == NULL)
                return;
        
        if (thread->interruption_requested && (bypass_abort_protection || 
!is_running_protected_wrapper ())) {

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

Reply via email to