Revert "[runtime] Use condvars instead of events for notifying the finalizer thread."
authorZoltan Varga <vargaz@gmail.com>
Sat, 16 May 2015 09:46:59 +0000 (11:46 +0200)
committerZoltan Varga <vargaz@gmail.com>
Sat, 16 May 2015 09:46:59 +0000 (11:46 +0200)
This reverts commit c84508b6f33af3853e676102903edac3ed278fd5.

Revert this until issues with interrupts can be sorted out.

mono/metadata/gc.c

index 8013a957dff01992d5e48dd5bb0f2a2a7b39d712..58aa546c1375f7f094a9690ba07f64931630c3f2 100644 (file)
@@ -1012,10 +1012,10 @@ mono_gc_GCHandle_CheckCurrentDomain (guint32 gchandle)
        return mono_gchandle_is_in_domain (gchandle, mono_domain_get ());
 }
 
-/* Uses finalizer_mutex */
-static mono_cond_t finalizer_cond;
-static int num_to_finalize;
-
+#ifdef MONO_HAS_SEMAPHORES
+static MonoSemType finalizer_sem;
+#endif
+static HANDLE finalizer_event;
 static volatile gboolean finished=FALSE;
 
 void
@@ -1028,10 +1028,11 @@ mono_gc_finalize_notify (void)
        if (mono_gc_is_null ())
                return;
 
-       mono_mutex_lock (&finalizer_mutex);
-       num_to_finalize ++;
-       mono_cond_signal (&finalizer_cond);
-       mono_mutex_unlock (&finalizer_mutex);
+#ifdef MONO_HAS_SEMAPHORES
+       MONO_SEM_POST (&finalizer_sem);
+#else
+       SetEvent (finalizer_event);
+#endif
 }
 
 #ifdef HAVE_BOEHM_GC
@@ -1108,20 +1109,27 @@ finalize_domain_objects (DomainFinalizationReq *req)
 static guint32
 finalizer_thread (gpointer unused)
 {
+       gboolean wait = TRUE;
+
        while (!finished) {
-               /*
-                * Wait to be notified that there's at least one
+               /* Wait to be notified that there's at least one
                 * finaliser to run
                 */
-               g_assert (mono_domain_get () == mono_get_root_domain ());
 
+               g_assert (mono_domain_get () == mono_get_root_domain ());
                mono_gc_set_skip_thread (TRUE);
-               MONO_PREPARE_BLOCKING;
-               mono_mutex_lock (&finalizer_mutex);
-               if (!num_to_finalize)
-                       mono_cond_wait (&finalizer_cond, &finalizer_mutex);
-               mono_mutex_unlock (&finalizer_mutex);
-               MONO_FINISH_BLOCKING;
+               MONO_PREPARE_BLOCKING
+
+               if (wait) {
+               /* An alertable wait is required so this thread can be suspended on windows */
+#ifdef MONO_HAS_SEMAPHORES
+                       MONO_SEM_WAIT_ALERTABLE (&finalizer_sem, TRUE);
+#else
+                       WaitForSingleObjectEx (finalizer_event, INFINITE, TRUE);
+#endif
+               }
+               wait = TRUE;
+               MONO_FINISH_BLOCKING
                mono_gc_set_skip_thread (FALSE);
 
                mono_threads_perform_thread_dump ();
@@ -1154,12 +1162,16 @@ finalizer_thread (gpointer unused)
 
                reference_queue_proccess_all ();
 
+#ifdef MONO_HAS_SEMAPHORES
                /* Avoid posting the pending done event until there are pending finalizers */
-               mono_mutex_lock (&finalizer_mutex);
-               num_to_finalize --;
-               if (num_to_finalize == 0)
+               if (MONO_SEM_TIMEDWAIT (&finalizer_sem, 0) == 0)
+                       /* Don't wait again at the start of the loop */
+                       wait = FALSE;
+               else
+                       SetEvent (pending_done_event);
+#else
                        SetEvent (pending_done_event);
-               mono_mutex_unlock (&finalizer_mutex);
+#endif
        }
 
        mono_finalizer_lock ();
@@ -1204,11 +1216,15 @@ mono_gc_init (void)
                gc_disabled = TRUE;
                return;
        }
-
-       mono_cond_init (&finalizer_cond, 0);
+       
+       finalizer_event = CreateEvent (NULL, FALSE, FALSE, NULL);
+       g_assert (finalizer_event);
        pending_done_event = CreateEvent (NULL, TRUE, FALSE, NULL);
        g_assert (pending_done_event);
        mono_cond_init (&exited_cond, 0);
+#ifdef MONO_HAS_SEMAPHORES
+       MONO_SEM_INIT (&finalizer_sem, 0);
+#endif
 
 #ifndef LAZY_GC_THREAD_CREATION
        mono_gc_init_finalizer_thread ();