Merge pull request #3395 from lambdageek/dev/handles-strings
[mono.git] / mono / metadata / gc.c
index 350d439bee3e05e6e64e6afd62b9f5a12f5c5578..46eaf5e224af7ad3bd1ac05a365d4415ad0d910b 100644 (file)
@@ -116,6 +116,8 @@ break_coop_alertable_wait (gpointer user_data)
        mono_coop_mutex_lock (ud->mutex);
        mono_coop_cond_signal (ud->cond);
        mono_coop_mutex_unlock (ud->mutex);
+
+       g_free (ud);
 }
 
 /*
@@ -127,23 +129,30 @@ break_coop_alertable_wait (gpointer user_data)
 static inline gint
 coop_cond_timedwait_alertable (MonoCoopCond *cond, MonoCoopMutex *mutex, guint32 timeout_ms, gboolean *alertable)
 {
+       BreakCoopAlertableWaitUD *ud;
        int res;
 
        if (alertable) {
-               BreakCoopAlertableWaitUD ud;
+               ud = g_new0 (BreakCoopAlertableWaitUD, 1);
+               ud->cond = cond;
+               ud->mutex = mutex;
 
-               *alertable = FALSE;
-               ud.cond = cond;
-               ud.mutex = mutex;
-               mono_thread_info_install_interrupt (break_coop_alertable_wait, &ud, alertable);
-               if (*alertable)
+               mono_thread_info_install_interrupt (break_coop_alertable_wait, ud, alertable);
+               if (*alertable) {
+                       g_free (ud);
                        return 0;
+               }
        }
        res = mono_coop_cond_timedwait (cond, mutex, timeout_ms);
        if (alertable) {
                mono_thread_info_uninstall_interrupt (alertable);
                if (*alertable)
                        return 0;
+               else {
+                       /* the interrupt token has not been taken by another
+                        * thread, so it's our responsability to free it up. */
+                       g_free (ud);
+               }
        }
        return res;
 }
@@ -317,8 +326,12 @@ mono_gc_run_finalize (void *obj, void *data)
        if (log_finalizers)
                g_log ("mono-gc-finalizers", G_LOG_LEVEL_MESSAGE, "<%s at %p> Calling finalizer.", o->vtable->klass->name, o);
 
+       mono_profiler_gc_finalize_object_begin (o);
+
        runtime_invoke (o, NULL, &exc, NULL);
 
+       mono_profiler_gc_finalize_object_end (o);
+
        if (log_finalizers)
                g_log ("mono-gc-finalizers", G_LOG_LEVEL_MESSAGE, "<%s at %p> Returned from finalizer.", o->vtable->klass->name, o);
 
@@ -905,11 +918,15 @@ finalizer_thread (gpointer unused)
 
                finalize_domain_objects ();
 
+               mono_profiler_gc_finalize_begin ();
+
                /* If finished == TRUE, mono_gc_cleanup has been called (from mono_runtime_cleanup),
                 * before the domain is unloaded.
                 */
                mono_gc_invoke_finalizers ();
 
+               mono_profiler_gc_finalize_end ();
+
                mono_threads_join_threads ();
 
                reference_queue_proccess_all ();