pidgin/pidgin

Fix media leaks

8 weeks ago, Elliott Sales de Andrade
efe66edc9676
Parents ca195ffd7206
Children 3844b333df53
Fix media leaks

The global media manager object was never cleaned up, so add a (private)
shutdown function to ensure that happens.

Also, `purple_media_manager_register_element` and
`purple_media_manager_get_element_info` are transfer full, while
`purple_media_manager_set_active_element` is transfer none, so reconcile that
inconsistency.

Testing Done:
Ran with valgrind, and fewer leaks were reported.

Reviewed at https://reviews.imfreedom.org/r/3036/
--- a/finch/gntmedia.c Mon Mar 18 22:06:19 2024 -0500
+++ b/finch/gntmedia.c Mon Mar 18 23:50:39 2024 -0500
@@ -414,6 +414,9 @@
purple_debug_info("gntmedia", "Registering media element types\n");
purple_media_manager_set_active_element(manager, audio_src);
purple_media_manager_set_active_element(manager, audio_sink);
+
+ g_object_unref(audio_src);
+ g_object_unref(audio_sink);
}
void finch_media_manager_uninit(void)
--- a/libpurple/core.c Mon Mar 18 22:06:19 2024 -0500
+++ b/libpurple/core.c Mon Mar 18 23:50:39 2024 -0500
@@ -266,6 +266,7 @@
purple_plugins_uninit();
/* after plugins */
+ purple_media_manager_shutdown();
purple_contact_manager_shutdown();
purple_account_manager_shutdown();
purple_credential_manager_shutdown();
--- a/libpurple/mediamanager.c Mon Mar 18 22:06:19 2024 -0500
+++ b/libpurple/mediamanager.c Mon Mar 18 23:50:39 2024 -0500
@@ -29,6 +29,7 @@
#include "prefs.h"
#include "purpleaccount.h"
#include "purplepath.h"
+#include "purpleprivate.h"
#include "media-gst.h"
@@ -121,6 +122,8 @@
};
static guint signals[N_SIGNALS] = {0, };
+static PurpleMediaManager *default_manager = NULL;
+
G_DEFINE_FINAL_TYPE_WITH_PRIVATE(PurpleMediaManager, purple_media_manager,
G_TYPE_OBJECT);
@@ -189,37 +192,44 @@
}
static void
-purple_media_manager_finalize (GObject *media)
+purple_media_manager_finalize(GObject *obj)
{
- PurpleMediaManagerPrivate *priv =
- purple_media_manager_get_instance_private(
- PURPLE_MEDIA_MANAGER(media));
+ PurpleMediaManager *manager = PURPLE_MEDIA_MANAGER(obj);
+ PurpleMediaManagerPrivate *priv = NULL;
- g_list_free_full(priv->medias, g_object_unref);
- g_list_free_full(priv->private_medias, g_object_unref);
- g_list_free_full(priv->elements, g_object_unref);
- g_clear_pointer(&priv->video_caps, gst_caps_unref);
- g_clear_list(&priv->appdata_info,
- (GDestroyNotify)free_appdata_info_locked);
- g_mutex_clear (&priv->appdata_mutex);
+ priv = purple_media_manager_get_instance_private(manager);
+
if (priv->device_monitor) {
gst_device_monitor_stop(priv->device_monitor);
g_object_unref(priv->device_monitor);
}
- G_OBJECT_CLASS(purple_media_manager_parent_class)->finalize(media);
+ g_clear_list(&priv->medias, g_object_unref);
+ g_clear_list(&priv->private_medias, g_object_unref);
+ g_clear_list(&priv->elements, g_object_unref);
+ g_clear_pointer(&priv->video_caps, gst_caps_unref);
+ g_clear_list(&priv->appdata_info,
+ (GDestroyNotify)free_appdata_info_locked);
+ g_mutex_clear (&priv->appdata_mutex);
+
+ G_OBJECT_CLASS(purple_media_manager_parent_class)->finalize(obj);
}
PurpleMediaManager *
purple_media_manager_get(void)
{
- static PurpleMediaManager *manager = NULL;
-
- if (manager == NULL) {
- manager = g_object_new(PURPLE_TYPE_MEDIA_MANAGER, NULL);
+ if(!PURPLE_IS_MEDIA_MANAGER(default_manager)) {
+ default_manager = g_object_new(PURPLE_TYPE_MEDIA_MANAGER, NULL);
+ g_object_add_weak_pointer(G_OBJECT(default_manager),
+ (gpointer *)&default_manager);
}
- return manager;
+ return default_manager;
+}
+
+void
+purple_media_manager_shutdown(void) {
+ g_clear_object(&default_manager);
}
static gboolean
@@ -1188,6 +1198,7 @@
if (info2 != NULL) {
g_object_unref(info2);
+ g_object_unref(info);
return FALSE;
}
@@ -1213,7 +1224,6 @@
info = purple_media_manager_get_element_info(manager, id);
if (info == NULL) {
- g_object_unref(info);
return FALSE;
}
@@ -1260,7 +1270,7 @@
g_free(id);
if (info2 == NULL) {
- purple_media_manager_register_element(manager, info);
+ purple_media_manager_register_element(manager, g_object_ref(info));
} else {
g_object_unref(info2);
}
--- a/libpurple/purpleprivate.h Mon Mar 18 22:06:19 2024 -0500
+++ b/libpurple/purpleprivate.h Mon Mar 18 23:50:39 2024 -0500
@@ -295,6 +295,16 @@
gboolean purple_history_adapter_deactivate(PurpleHistoryAdapter *adapter, GError **error);
/**
+ * purple_media_manager_shutdown:
+ *
+ * Shuts down the media manager by destroying the default instance.
+ *
+ * Since: 3.0
+ */
+G_GNUC_INTERNAL
+void purple_media_manager_shutdown(void);
+
+/**
* purple_notification_manager_startup:
*
* Starts up the notification manager by creating the default instance.
--- a/pidgin/gtkmedia.c Mon Mar 18 22:06:19 2024 -0500
+++ b/pidgin/gtkmedia.c Mon Mar 18 23:50:39 2024 -0500
@@ -986,4 +986,9 @@
purple_media_manager_set_active_element(manager, video_sink);
purple_media_manager_set_active_element(manager, audio_src);
purple_media_manager_set_active_element(manager, audio_sink);
+
+ g_object_unref(video_src);
+ g_object_unref(video_sink);
+ g_object_unref(audio_src);
+ g_object_unref(audio_sink);
}
--- a/pidgin/prefs/pidginvvprefs.c Mon Mar 18 22:06:19 2024 -0500
+++ b/pidgin/prefs/pidginvvprefs.c Mon Mar 18 23:50:39 2024 -0500
@@ -407,6 +407,7 @@
manager = purple_media_manager_get();
info = purple_media_manager_get_element_info(manager, value);
purple_media_manager_set_active_element(manager, info);
+ g_object_unref(info);
/* Refresh test viewers */
if (strstr(name, "audio") && prefs->voice.pipeline) {