mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 20:21:24 +00:00
validate: reporter: break cyclic references with reports
My patch fixing monitor leak (15e7f1bbfd
)
introduced a ref cycle between GstValidateReporter and
GstValidateReport.
The reports uses its reporter so it needs a ref on it
to ensure it's stay alive. But reports are owned by GstValidateReporter and/or
GstValidateRunner.
The best way I found to break this cycle is to introduce this purge
method. It's not great but the design is a bit tricky.
Reviewed-by: Thibault Saunier <tsaunier@gnome.org>
Differential Revision: https://phabricator.freedesktop.org/D1029
This commit is contained in:
parent
b8c821dff4
commit
dc7382017d
8 changed files with 53 additions and 5 deletions
|
@ -116,6 +116,15 @@ gst_validate_bin_monitor_get_property (GObject * object, guint prop_id,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
purge_and_unref_reporter (gpointer data)
|
||||
{
|
||||
GstValidateReporter *reporter = data;
|
||||
|
||||
gst_validate_reporter_purge_reports (reporter);
|
||||
g_object_unref (reporter);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_validate_bin_monitor_dispose (GObject * object)
|
||||
{
|
||||
|
@ -125,10 +134,13 @@ gst_validate_bin_monitor_dispose (GObject * object)
|
|||
if (bin && monitor->element_added_id)
|
||||
g_signal_handler_disconnect (bin, monitor->element_added_id);
|
||||
|
||||
if (monitor->scenario)
|
||||
if (monitor->scenario) {
|
||||
gst_validate_reporter_purge_reports (GST_VALIDATE_REPORTER
|
||||
(monitor->scenario));
|
||||
g_object_unref (monitor->scenario);
|
||||
}
|
||||
|
||||
g_list_free_full (monitor->element_monitors, g_object_unref);
|
||||
g_list_free_full (monitor->element_monitors, purge_and_unref_reporter);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->dispose (object);
|
||||
}
|
||||
|
|
|
@ -98,6 +98,14 @@ gst_validate_element_set_media_descriptor (GstValidateMonitor * monitor,
|
|||
gst_iterator_free (iterator);
|
||||
}
|
||||
|
||||
static void
|
||||
purge_and_unref_reporter (gpointer data)
|
||||
{
|
||||
GstValidateReporter *reporter = data;
|
||||
|
||||
gst_validate_reporter_purge_reports (reporter);
|
||||
g_object_unref (reporter);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_validate_element_monitor_dispose (GObject * object)
|
||||
|
@ -109,7 +117,7 @@ gst_validate_element_monitor_dispose (GObject * object)
|
|||
g_signal_handler_disconnect (GST_VALIDATE_MONITOR_GET_OBJECT (monitor),
|
||||
monitor->pad_added_id);
|
||||
|
||||
g_list_free_full (monitor->pad_monitors, g_object_unref);
|
||||
g_list_free_full (monitor->pad_monitors, purge_and_unref_reporter);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->dispose (object);
|
||||
}
|
||||
|
|
|
@ -436,3 +436,22 @@ gst_validate_reporter_get_reports_count (GstValidateReporter * reporter)
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_validate_reporter_purge_reports:
|
||||
* @reporter: a #GstValidateReporter
|
||||
*
|
||||
* Remove all the #GstValidateReport from @reporter. This should be called
|
||||
* before unreffing the reporter to break cyclic references.
|
||||
*/
|
||||
void
|
||||
gst_validate_reporter_purge_reports (GstValidateReporter * reporter)
|
||||
{
|
||||
GstValidateReporterPrivate *priv;
|
||||
|
||||
priv = g_object_get_data (G_OBJECT (reporter), REPORTER_PRIVATE);
|
||||
|
||||
GST_VALIDATE_REPORTER_REPORTS_LOCK (reporter);
|
||||
g_hash_table_remove_all (priv->reports);
|
||||
GST_VALIDATE_REPORTER_REPORTS_UNLOCK (reporter);
|
||||
}
|
||||
|
|
|
@ -115,5 +115,7 @@ GList * gst_validate_reporter_get_reports (GstValidateReporter * reporter);
|
|||
gint gst_validate_reporter_get_reports_count (GstValidateReporter *reporter);
|
||||
GstValidateReportingDetails gst_validate_reporter_get_reporting_level (GstValidateReporter *reporter);
|
||||
|
||||
void gst_validate_reporter_purge_reports (GstValidateReporter * reporter);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* _GST_VALIDATE_REPORTER_ */
|
||||
|
|
|
@ -557,6 +557,7 @@ _run_frame_analysis (GstValidateMediaDescriptorWriter * writer,
|
|||
writer->priv->loop = NULL;
|
||||
gst_bus_remove_signal_watch (bus);
|
||||
gst_object_unref (bus);
|
||||
gst_validate_reporter_purge_reports (GST_VALIDATE_REPORTER (monitor));
|
||||
g_object_unref (monitor);
|
||||
|
||||
return TRUE;
|
||||
|
|
|
@ -155,10 +155,14 @@ out:
|
|||
g_free (output_file);
|
||||
g_free (expected_file);
|
||||
|
||||
if (reference)
|
||||
if (reference) {
|
||||
gst_validate_reporter_purge_reports (GST_VALIDATE_REPORTER (reference));
|
||||
gst_object_unref (reference);
|
||||
if (writer)
|
||||
}
|
||||
if (writer) {
|
||||
gst_validate_reporter_purge_reports (GST_VALIDATE_REPORTER (writer));
|
||||
gst_object_unref (writer);
|
||||
}
|
||||
if (runner)
|
||||
gst_object_unref (runner);
|
||||
gst_deinit ();
|
||||
|
|
|
@ -978,6 +978,7 @@ exit:
|
|||
g_main_loop_unref (mainloop);
|
||||
g_clear_object (&encoding_profile);
|
||||
g_object_unref (pipeline);
|
||||
gst_validate_reporter_purge_reports (GST_VALIDATE_REPORTER (monitor));
|
||||
g_object_unref (monitor);
|
||||
g_object_unref (runner);
|
||||
|
||||
|
|
|
@ -657,6 +657,7 @@ exit:
|
|||
g_main_loop_unref (mainloop);
|
||||
g_object_unref (pipeline);
|
||||
g_object_unref (runner);
|
||||
gst_validate_reporter_purge_reports (GST_VALIDATE_REPORTER (monitor));
|
||||
g_object_unref (monitor);
|
||||
g_clear_error (&err);
|
||||
#ifdef G_OS_UNIX
|
||||
|
|
Loading…
Reference in a new issue