typedef struct DomainFinalizationReq {
MonoDomain *domain;
- mono_mutex_t *done_mutex;
- mono_cond_t *done_cond;
- gboolean done;
+ HANDLE done_event;
} DomainFinalizationReq;
-#ifdef PLATFORM_WINCE /* FIXME: add accessors to gc.dll API */
-extern void (*__imp_GC_finalizer_notifier)(void);
-#define GC_finalizer_notifier __imp_GC_finalizer_notifier
-extern int __imp_GC_finalize_on_demand;
-#define GC_finalize_on_demand __imp_GC_finalize_on_demand
-#endif
-
static gboolean gc_disabled = FALSE;
static gboolean finalizing_root_domain = FALSE;
return result;
}
-static guint32
-guarded_cond_wait (mono_cond_t *cond, mono_mutex_t *mutex, guint32 timeout)
-{
- guint32 result;
-
- MONO_PREPARE_BLOCKING;
- if (timeout == INFINITE)
- result = mono_cond_wait (cond, mutex);
- else
- result = mono_cond_timedwait_ms (cond, mutex, timeout);
- MONO_FINISH_BLOCKING
-
- return result;
-}
-
static void
add_thread_to_finalize (MonoInternalThread *thread)
{
finalizer = mono_class_get_finalizer (o->vtable->klass);
-#ifndef DISABLE_COM
/* If object has a CCW but has no finalizer, it was only
* registered for finalization in order to free the CCW.
* Else it needs the regular finalizer run.
mono_domain_set_internal (caller_domain);
return;
}
-#endif
/*
* To avoid the locking plus the other overhead of mono_runtime_invoke (),
{
DomainFinalizationReq *req;
guint32 res;
- mono_mutex_t done_mutex;
- mono_cond_t done_cond;
+ HANDLE done_event;
+ MonoInternalThread *thread = mono_thread_internal_current ();
#if defined(__native_client__)
return FALSE;
mono_gc_collect (mono_gc_max_generation ());
- mono_mutex_init (&done_mutex);
- mono_cond_init (&done_cond, 0);
+ done_event = CreateEvent (NULL, TRUE, FALSE, NULL);
+ if (done_event == NULL) {
+ return FALSE;
+ }
req = g_new0 (DomainFinalizationReq, 1);
req->domain = domain;
- req->done_mutex = &done_mutex;
- req->done_cond = &done_cond;
- req->done = FALSE;
+ req->done_event = done_event;
if (domain == mono_get_root_domain ())
finalizing_root_domain = TRUE;
timeout = INFINITE;
while (TRUE) {
- res = 0;
- mono_mutex_lock (&done_mutex);
- if (!req->done) {
- res = guarded_cond_wait (&done_cond, &done_mutex, timeout);
- /* printf ("WAIT RES: %d.\n", res); */
- }
- mono_mutex_unlock (&done_mutex);
- if (res)
- /* We leak memory here, since the finalizer thread might still be using it */
+ res = guarded_wait (done_event, timeout, TRUE);
+ /* printf ("WAIT RES: %d.\n", res); */
+
+ if (res == WAIT_IO_COMPLETION) {
+ if ((thread->state & (ThreadState_StopRequested | ThreadState_SuspendRequested)) != 0)
+ return FALSE;
+ } else if (res == WAIT_TIMEOUT) {
+ /* We leak the handle here */
return FALSE;
- if (req->done)
+ } else {
break;
+ }
}
- mono_mutex_destroy (&done_mutex);
- mono_cond_destroy (&done_cond);
- g_free (req);
+ CloseHandle (done_event);
if (domain == mono_get_root_domain ()) {
mono_thread_pool_cleanup ();
return -1;
}
-static void*
+static MonoGCDescriptor
make_root_descr_all_refs (int numbits, gboolean pinned)
{
#ifdef HAVE_SGEN_GC
if (pinned)
- return NULL;
+ return MONO_GC_DESCRIPTOR_NULL;
#endif
return mono_gc_make_root_descr_all_refs (numbits);
}
/* cleanup the reference queue */
reference_queue_clear_for_domain (domain);
-
+
/* printf ("DONE.\n"); */
+ SetEvent (req->done_event);
- mono_mutex_lock (req->done_mutex);
- req->done = TRUE;
- mono_cond_signal (req->done_cond);
- mono_mutex_unlock (req->done_mutex);
+ /* The event is closed in mono_domain_finalize if we get here */
+ g_free (req);
}
static guint32
mono_console_handle_async_ops ();
-#ifndef DISABLE_ATTACH
mono_attach_maybe_start ();
-#endif
if (domains_to_finalize) {
mono_finalizer_lock ();
}
}
gc_thread = NULL;
-#ifdef HAVE_BOEHM_GC
- GC_finalizer_notifier = NULL;
-#endif
+ mono_gc_base_cleanup ();
}
mono_reference_queue_cleanup ();
- mono_mutex_destroy (&handle_section);
mono_mutex_destroy (&allocator_section);
mono_mutex_destroy (&finalizer_mutex);
mono_mutex_destroy (&reference_queue_mutex);
}
+/**
+ * mono_gc_mutex_cleanup:
+ *
+ * Destroy the mutexes that may still be used after the main cleanup routine.
+ */
+void
+mono_gc_mutex_cleanup (void)
+{
+ mono_mutex_destroy (&handle_section);
+}
+
gboolean
mono_gc_is_finalizer_internal_thread (MonoInternalThread *thread)
{