From: Alex Rønne Petersen Date: Sat, 5 Aug 2017 16:49:56 +0000 (+0200) Subject: [profiler] Properly clean up the resources used by the profiler API on shutdown. X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=f35875568b88959ce72184fd69d5c7ee0bfbb86e;p=mono.git [profiler] Properly clean up the resources used by the profiler API on shutdown. Also introduce mono_profiler_set_cleanup_callback (). --- diff --git a/mono/metadata/profiler-private.h b/mono/metadata/profiler-private.h index 340a70d3059..976f309ee87 100644 --- a/mono/metadata/profiler-private.h +++ b/mono/metadata/profiler-private.h @@ -16,6 +16,7 @@ struct _MonoProfilerDesc { MonoProfilerHandle next; MonoProfiler *prof; + volatile gpointer cleanup_callback; volatile gpointer coverage_filter; volatile gpointer call_instrumentation_filter; diff --git a/mono/metadata/profiler.c b/mono/metadata/profiler.c index 0f429f607ff..23f65469c81 100644 --- a/mono/metadata/profiler.c +++ b/mono/metadata/profiler.c @@ -157,6 +157,12 @@ mono_profiler_create (MonoProfiler *prof) return handle; } +void +mono_profiler_set_cleanup_callback (MonoProfilerHandle handle, MonoProfilerCleanupCallback cb) +{ + InterlockedWritePointer (&handle->cleanup_callback, (gpointer) cb); +} + void mono_profiler_set_coverage_filter_callback (MonoProfilerHandle handle, MonoProfilerCoverageFilterCallback cb) { @@ -478,6 +484,38 @@ mono_profiler_cleanup (void) #undef MONO_PROFILER_EVENT_3 #undef MONO_PROFILER_EVENT_4 #undef _MONO_PROFILER_EVENT + + MonoProfilerHandle head = mono_profiler_state.profilers; + + while (head) { + MonoProfilerCleanupCallback cb = head->cleanup_callback; + + if (cb) + cb (head->prof); + + MonoProfilerHandle cur = head; + head = head->next; + + g_free (cur); + } + + if (mono_profiler_state.code_coverage) { + mono_os_mutex_destroy (&mono_profiler_state.coverage_mutex); + + GHashTableIter iter; + + g_hash_table_iter_init (&iter, mono_profiler_state.coverage_hash); + + MonoProfilerCoverageInfo *info; + + while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &info)) + g_free (info); + + g_hash_table_destroy (mono_profiler_state.coverage_hash); + } + + if (mono_profiler_state.sampling_owner) + mono_os_sem_destroy (&mono_profiler_state.sampling_semaphore); } static void diff --git a/mono/metadata/profiler.h b/mono/metadata/profiler.h index 76759d9f845..e20dc34c854 100644 --- a/mono/metadata/profiler.h +++ b/mono/metadata/profiler.h @@ -63,6 +63,18 @@ typedef struct _MonoProfilerDesc *MonoProfilerHandle; */ MONO_API MonoProfilerHandle mono_profiler_create (MonoProfiler *prof); +typedef void (*MonoProfilerCleanupCallback) (MonoProfiler *prof); + +/* + * Sets a profiler cleanup function. This function will be invoked at shutdown + * when the profiler API is cleaning up its internal structures. It's mainly + * intended for a profiler to free the structure pointer that was passed to + * mono_profiler_create, if necessary. + * + * This function is async safe. + */ +MONO_API void mono_profiler_set_cleanup_callback (MonoProfilerHandle handle, MonoProfilerCleanupCallback cb); + /* * Enables support for code coverage instrumentation. At the moment, this means * enabling the debug info subsystem. If you do not call this function, you