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
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
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 ();
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 ();
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 ();