[coop] Add missing coop checks for WFSO and WFMO.
authorRodrigo Kumpera <kumpera@gmail.com>
Fri, 17 Apr 2015 00:13:11 +0000 (20:13 -0400)
committerRodrigo Kumpera <kumpera@gmail.com>
Fri, 17 Apr 2015 19:20:54 +0000 (15:20 -0400)
mono/metadata/appdomain.c
mono/metadata/gc.c
mono/metadata/monitor.c
mono/metadata/process.c
mono/metadata/threadpool-ms.c
mono/metadata/threadpool.c
mono/metadata/threads.c

index d3441ba140ff778c3a97a600427c2c4fb4838ad4..b010c10b5d7dcaf289b98933f0096c65915917d1 100644 (file)
@@ -2360,6 +2360,18 @@ mono_domain_unload (MonoDomain *domain)
                mono_raise_exception ((MonoException*)exc);
 }
 
+static guint32
+guarded_wait (HANDLE handle, guint32 timeout, gboolean alertable)
+{
+       guint32 result;
+
+       MONO_PREPARE_BLOCKING
+       result = WaitForSingleObjectEx (handle, timeout, alertable);
+       MONO_FINISH_BLOCKING
+
+       return result;
+}
+
 /*
  * mono_domain_unload:
  * @domain: The domain to unload
@@ -2446,7 +2458,7 @@ mono_domain_try_unload (MonoDomain *domain, MonoObject **exc)
        g_free (name);
 
        /* Wait for the thread */       
-       while (!thread_data->done && WaitForSingleObjectEx (thread_handle, INFINITE, TRUE) == WAIT_IO_COMPLETION) {
+       while (!thread_data->done && guarded_wait (thread_handle, INFINITE, TRUE) == WAIT_IO_COMPLETION) {
                if (mono_thread_internal_has_appdomain_ref (mono_thread_internal_current (), domain) && (mono_thread_interruption_requested ())) {
                        /* The unload thread tries to abort us */
                        /* The icall wrapper will execute the abort */
index 30179bd9fbaa61bd00f982b0db376fcd16b1ebbd..c942c0ecebd08facfee099919bc950bd7cd9f3da 100644 (file)
@@ -86,6 +86,18 @@ static HANDLE shutdown_event;
 
 GCStats gc_stats;
 
+static guint32
+guarded_wait (HANDLE handle, guint32 timeout, gboolean alertable)
+{
+       guint32 result;
+
+       MONO_PREPARE_BLOCKING
+       result = WaitForSingleObjectEx (handle, timeout, alertable);
+       MONO_FINISH_BLOCKING
+
+       return result;
+}
+
 static void
 add_thread_to_finalize (MonoInternalThread *thread)
 {
@@ -399,7 +411,7 @@ mono_domain_finalize (MonoDomain *domain, guint32 timeout)
                timeout = INFINITE;
 
        while (TRUE) {
-               res = WaitForSingleObjectEx (done_event, timeout, TRUE);
+               res = guarded_wait (done_event, timeout, TRUE);
                /* printf ("WAIT RES: %d.\n", res); */
 
                if (res == WAIT_IO_COMPLETION) {
@@ -497,7 +509,7 @@ ves_icall_System_GC_WaitForPendingFinalizers (void)
        ResetEvent (pending_done_event);
        mono_gc_finalize_notify ();
        /* g_print ("Waiting for pending finalizers....\n"); */
-       WaitForSingleObjectEx (pending_done_event, INFINITE, TRUE);
+       guarded_wait (pending_done_event, INFINITE, TRUE);
        /* g_print ("Done pending....\n"); */
 #endif
 }
@@ -1210,7 +1222,7 @@ mono_gc_cleanup (void)
                        mono_gc_finalize_notify ();
                        /* Finishing the finalizer thread, so wait a little bit... */
                        /* MS seems to wait for about 2 seconds */
-                       if (WaitForSingleObjectEx (shutdown_event, 2000, FALSE) == WAIT_TIMEOUT) {
+                       if (guarded_wait (shutdown_event, 2000, FALSE) == WAIT_TIMEOUT) {
                                int ret;
 
                                /* Set a flag which the finalizer thread can check */
@@ -1220,7 +1232,7 @@ mono_gc_cleanup (void)
                                mono_thread_internal_stop (gc_thread);
 
                                /* Wait for it to stop */
-                               ret = WaitForSingleObjectEx (gc_thread->handle, 100, TRUE);
+                               ret = guarded_wait (gc_thread->handle, 100, TRUE);
 
                                if (ret == WAIT_TIMEOUT) {
                                        /* 
@@ -1237,7 +1249,7 @@ mono_gc_cleanup (void)
                                int ret;
 
                                /* Wait for the thread to actually exit */
-                               ret = WaitForSingleObjectEx (gc_thread->handle, INFINITE, TRUE);
+                               ret = guarded_wait (gc_thread->handle, INFINITE, TRUE);
                                g_assert (ret == WAIT_OBJECT_0);
 
                                mono_thread_join (GUINT_TO_POINTER (gc_thread->tid));
index f75606c501039317808607c7bdfaccbfe8930a97..0c457acace4b420feaceac597cdd94b3ce684981 100644 (file)
@@ -1133,7 +1133,9 @@ ves_icall_System_Threading_Monitor_Monitor_wait (MonoObject *obj, guint32 ms)
                /* Poll the event again, just in case it was signalled
                 * while we were trying to regain the monitor lock
                 */
+               MONO_PREPARE_BLOCKING
                ret = WaitForSingleObjectEx (event, 0, FALSE);
+               MONO_FINISH_BLOCKING
        }
 
        /* Pulse will have popped our event from the queue if it signalled
index f4d4e3044d3cb534194740d93bf2da54933b5bc4..86e7d187d34121735941b9dd30b33119254bad86 100644 (file)
@@ -692,12 +692,15 @@ MonoBoolean ves_icall_System_Diagnostics_Process_WaitForExit_internal (MonoObjec
 {
        guint32 ret;
        
+       MONO_PREPARE_BLOCKING
        if(ms<0) {
                /* Wait forever */
                ret=WaitForSingleObjectEx (process, INFINITE, TRUE);
        } else {
                ret=WaitForSingleObjectEx (process, ms, TRUE);
        }
+       MONO_FINISH_BLOCKING
+
        if(ret==WAIT_OBJECT_0) {
                return(TRUE);
        } else {
index 9becfd03d1e10797c1882aba55692d62907e602f..6793ca7b045897fd9fe9ea8a54e3ef312e989849 100644 (file)
@@ -1324,7 +1324,9 @@ mono_threadpool_ms_finish (MonoAsyncResult *ares, MonoArray **out_args, MonoObje
                        MONO_OBJECT_SETREF (ares, handle, (MonoObject*) mono_wait_handle_new (mono_object_domain (ares), wait_event));
                }
                mono_monitor_exit ((MonoObject*) ares);
+               MONO_PREPARE_BLOCKING
                WaitForSingleObjectEx (wait_event, INFINITE, TRUE);
+               MONO_FINISH_BLOCKING
        }
 
        ac = (MonoAsyncCall*) ares->object_data;
@@ -1370,7 +1372,9 @@ mono_threadpool_ms_remove_domain_jobs (MonoDomain *domain, int timeout)
        mono_memory_write_barrier ();
 
        while (domain->threadpool_jobs) {
+               MONO_PREPARE_BLOCKING
                WaitForSingleObject (sem, timeout);
+               MONO_FINISH_BLOCKING
                if (timeout != -1) {
                        timeout -= mono_msec_ticks () - start;
                        if (timeout <= 0) {
index 507d7be88c70bd3f2f7e645e8a5e110d7ac497e5..8f9ce57f149eca6ee934c6429ecabdf356a08f57 100644 (file)
@@ -1074,7 +1074,9 @@ mono_thread_pool_finish (MonoAsyncResult *ares, MonoArray **out_args, MonoObject
                        wait_event = mono_wait_handle_get_handle ((MonoWaitHandle *) ares->handle);
                }
                mono_monitor_exit ((MonoObject *) ares);
+               MONO_PREPARE_BLOCKING
                WaitForSingleObjectEx (wait_event, INFINITE, TRUE);
+               MONO_FINISH_BLOCKING
        } else {
                mono_monitor_exit ((MonoObject *) ares);
        }
@@ -1349,7 +1351,9 @@ mono_thread_pool_remove_domain_jobs (MonoDomain *domain, int timeout)
        if (domain->threadpool_jobs && timeout != -1)
                start_time = mono_msec_ticks ();
        while (domain->threadpool_jobs) {
+               MONO_PREPARE_BLOCKING
                WaitForSingleObject (sem_handle, timeout);
+               MONO_FINISH_BLOCKING
                if (timeout != -1 && (mono_msec_ticks () - start_time) > timeout) {
                        result = FALSE;
                        break;
index 99c71b0f4cbc309f859be405062d0c74a6a9fd22..a2b1a03ec3b2b469ddcda236d91167285cbe4ed1 100644 (file)
@@ -2723,7 +2723,9 @@ static void wait_for_tids (struct wait_data *wait, guint32 timeout)
        
        THREAD_DEBUG (g_message("%s: %d threads to wait for in this batch", __func__, wait->num));
 
+       MONO_PREPARE_BLOCKING
        ret=WaitForMultipleObjectsEx(wait->num, wait->handles, TRUE, timeout, TRUE);
+       MONO_FINISH_BLOCKING
 
        if(ret==WAIT_FAILED) {
                /* See the comment in build_wait_tids() */
@@ -2784,7 +2786,9 @@ static void wait_for_tids_or_state_change (struct wait_data *wait, guint32 timeo
                count++;
        }
 
+       MONO_PREPARE_BLOCKING
        ret=WaitForMultipleObjectsEx (count, wait->handles, FALSE, timeout, TRUE);
+       MONO_FINISH_BLOCKING
 
        if(ret==WAIT_FAILED) {
                /* See the comment in build_wait_tids() */
@@ -3182,7 +3186,10 @@ void mono_thread_suspend_all_other_threads (void)
 
                /*Only wait on the suspend event if we are using the old path */
                if (eventidx > 0 && !mono_thread_info_new_interrupt_enabled ()) {
+                       MONO_PREPARE_BLOCKING
                        WaitForMultipleObjectsEx (eventidx, events, TRUE, 100, FALSE);
+                       MONO_FINISH_BLOCKING
+
                        for (i = 0; i < wait->num; ++i) {
                                MonoInternalThread *thread = wait->threads [i];
 
@@ -4793,8 +4800,10 @@ self_suspend_internal (MonoInternalThread *thread)
                        for (;;)
                                Sleep (1000);
                }
-               
+
+               MONO_PREPARE_BLOCKING
                WaitForSingleObject (thread->suspend_event, INFINITE);
+               MONO_FINISH_BLOCKING
                
                LOCK_THREAD (thread);
 
@@ -4835,7 +4844,10 @@ resume_thread_internal (MonoInternalThread *thread)
                UNLOCK_THREAD (thread);
 
                /* Wait for the thread to awake */
+               MONO_PREPARE_BLOCKING
                WaitForSingleObject (thread->resume_event, INFINITE);
+               MONO_FINISH_BLOCKING
+
                CloseHandle (thread->resume_event);
                thread->resume_event = NULL;
                return TRUE;