#include <mono/utils/mono-time.h>
#include <mono/utils/dtrace.h>
#include <mono/utils/mono-threads.h>
+#include <mono/utils/mono-threads-coop.h>
#include <mono/utils/atomic.h>
#include <mono/utils/mono-coop-semaphore.h>
#include <mono/utils/hazard-pointer.h>
gboolean log_finalizers = FALSE;
gboolean mono_do_not_finalize = FALSE;
+volatile gboolean suspend_finalizers = FALSE;
gchar **mono_do_not_finalize_class_names = NULL;
#define mono_finalizer_lock() mono_coop_mutex_lock (&finalizer_mutex)
return is_ok (error);
}
-static gboolean suspend_finalizers = FALSE;
/*
* actually, we might want to queue the finalize requests in a separate thread,
* but we need to be careful about the execution domain of the thread...
{
MonoDomain *domain = req->domain;
-#if HAVE_SGEN_GC
-#define NUM_FOBJECTS 64
- MonoObject *to_finalize [NUM_FOBJECTS];
- int count;
-#endif
-
/* Process finalizers which are already in the queue */
mono_gc_invoke_finalizers ();
g_ptr_array_free (objs, TRUE);
}
#elif defined(HAVE_SGEN_GC)
- while ((count = mono_gc_finalizers_for_domain (domain, to_finalize, NUM_FOBJECTS))) {
- int i;
- for (i = 0; i < count; ++i) {
- mono_gc_run_finalize (to_finalize [i], 0);
- }
- }
+ mono_gc_finalize_domain (domain);
+ mono_gc_invoke_finalizers ();
#endif
/* cleanup the reference queue */
if (!gc_disabled) {
finished = TRUE;
if (mono_thread_internal_current () != gc_thread) {
- gboolean timed_out = FALSE;
gint64 start_ticks = mono_msec_ticks ();
gint64 end_ticks = start_ticks + 2000;
/* Set a flag which the finalizer thread can check */
suspend_finalizers = TRUE;
+ mono_gc_suspend_finalizers ();
/* Try to abort the thread, in the hope that it is running managed code */
- mono_thread_internal_stop (gc_thread);
+ mono_thread_internal_abort (gc_thread);
/* Wait for it to stop */
ret = guarded_wait (gc_thread->handle, 100, TRUE);
if (ret == WAIT_TIMEOUT) {
- /*
- * The finalizer thread refused to die. There is not much we
- * can do here, since the runtime is shutting down so the
- * state the finalizer thread depends on will vanish.
+ /*
+ * The finalizer thread refused to exit. Make it stop.
*/
- g_warning ("Shutting down finalizer thread timed out.");
- timed_out = TRUE;
+ mono_thread_internal_stop (gc_thread);
+ ret = guarded_wait (gc_thread->handle, 100, TRUE);
+ g_assert (ret != WAIT_TIMEOUT);
+ /* The thread can't set this flag */
+ finalizer_thread_exited = TRUE;
}
}
- if (!timed_out) {
- int ret;
+ int ret;
- /* Wait for the thread to actually exit */
- ret = guarded_wait (gc_thread->handle, INFINITE, TRUE);
- g_assert (ret == WAIT_OBJECT_0);
+ /* Wait for the thread to actually exit */
+ ret = guarded_wait (gc_thread->handle, INFINITE, TRUE);
+ g_assert (ret == WAIT_OBJECT_0);
- mono_thread_join (GUINT_TO_POINTER (gc_thread->tid));
- }
+ mono_thread_join (GUINT_TO_POINTER (gc_thread->tid));
g_assert (finalizer_thread_exited);
}
gc_thread = NULL;