[runtime] Fix a crash on Windows during the cleanup phase caused by using a destroyed...
[mono.git] / mono / metadata / gc.c
index 05e440cff6474a8493a80d175c329895d640745c..03273531193a1f042d36fb185ca99ead3f019565 100644 (file)
@@ -48,13 +48,6 @@ typedef struct DomainFinalizationReq {
        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;
@@ -83,9 +76,7 @@ static void mono_gchandle_set_target (guint32 gchandle, MonoObject *obj);
 static void reference_queue_proccess_all (void);
 static void mono_reference_queue_cleanup (void);
 static void reference_queue_clear_for_domain (MonoDomain *domain);
-#ifndef HAVE_NULL_GC
 static HANDLE pending_done_event;
-#endif
 
 static guint32
 guarded_wait (HANDLE handle, guint32 timeout, gboolean alertable)
@@ -208,7 +199,6 @@ mono_gc_run_finalize (void *obj, void *data)
 
        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.
@@ -219,7 +209,6 @@ mono_gc_run_finalize (void *obj, void *data)
                mono_domain_set_internal (caller_domain);
                return;
        }
-#endif
 
        /* 
         * To avoid the locking plus the other overhead of mono_runtime_invoke (),
@@ -381,10 +370,13 @@ mono_domain_finalize (MonoDomain *domain, guint32 timeout)
         * is still working and will take care of running the finalizers
         */ 
        
-#ifndef HAVE_NULL_GC
        if (gc_disabled)
                return TRUE;
 
+       /* We don't support domain finalization without a GC */
+       if (mono_gc_is_null ())
+               return FALSE;
+
        mono_gc_collect (mono_gc_max_generation ());
 
        done_event = CreateEvent (NULL, TRUE, FALSE, NULL);
@@ -434,10 +426,6 @@ mono_domain_finalize (MonoDomain *domain, guint32 timeout)
        }
 
        return TRUE;
-#else
-       /* We don't support domain finalization without a GC */
-       return FALSE;
-#endif
 }
 
 void
@@ -492,7 +480,9 @@ ves_icall_System_GC_SuppressFinalize (MonoObject *obj)
 void
 ves_icall_System_GC_WaitForPendingFinalizers (void)
 {
-#ifndef HAVE_NULL_GC
+       if (mono_gc_is_null ())
+               return;
+
        if (!mono_gc_pending_finalizers ())
                return;
 
@@ -512,7 +502,6 @@ ves_icall_System_GC_WaitForPendingFinalizers (void)
        /* g_print ("Waiting for pending finalizers....\n"); */
        guarded_wait (pending_done_event, INFINITE, TRUE);
        /* g_print ("Done pending....\n"); */
-#endif
 }
 
 void
@@ -649,12 +638,12 @@ find_first_unset (guint32 bitmap)
        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);
 }
@@ -995,8 +984,6 @@ mono_gc_GCHandle_CheckCurrentDomain (guint32 gchandle)
        return mono_gchandle_is_in_domain (gchandle, mono_domain_get ());
 }
 
-#ifndef HAVE_NULL_GC
-
 #ifdef MONO_HAS_SEMAPHORES
 static MonoSemType finalizer_sem;
 #endif
@@ -1010,6 +997,9 @@ mono_gc_finalize_notify (void)
        g_message ( "%s: prodding finalizer", __func__);
 #endif
 
+       if (mono_gc_is_null ())
+               return;
+
 #ifdef MONO_HAS_SEMAPHORES
        MONO_SEM_POST (&finalizer_sem);
 #else
@@ -1117,9 +1107,7 @@ finalizer_thread (gpointer unused)
 
                mono_console_handle_async_ops ();
 
-#ifndef DISABLE_ATTACH
                mono_attach_maybe_start ();
-#endif
 
                if (domains_to_finalize) {
                        mono_finalizer_lock ();
@@ -1219,6 +1207,9 @@ mono_gc_cleanup (void)
        g_message ("%s: cleaning up finalizer", __func__);
 #endif
 
+       if (mono_gc_is_null ())
+               return;
+
        if (!gc_disabled) {
                finished = TRUE;
                if (mono_thread_internal_current () != gc_thread) {
@@ -1279,38 +1270,27 @@ mono_gc_cleanup (void)
                        }
                }
                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);
 }
 
-#else
-
-/* Null GC dummy functions */
+/**
+ * mono_gc_mutex_cleanup:
+ *
+ * Destroy the mutexes that may still be used after the main cleanup routine.
+ */
 void
-mono_gc_finalize_notify (void)
-{
-}
-
-void mono_gc_init (void)
-{
-       mono_mutex_init_recursive (&handle_section);
-}
-
-void mono_gc_cleanup (void)
+mono_gc_mutex_cleanup (void)
 {
+       mono_mutex_destroy (&handle_section);
 }
 
-#endif
-
 gboolean
 mono_gc_is_finalizer_internal_thread (MonoInternalThread *thread)
 {