changeset 23877:c48f5c9600c3

Fixed a ton of memory leaks.
author Mike Ruprecht <maiku@soc.pidgin.im>
date Mon, 18 Aug 2008 06:25:38 +0000
parents f10e0ac24595
children e22bcca9f2b2
files libpurple/media.c libpurple/protocols/jabber/jingle.c pidgin/gtkconv.c pidgin/gtkmedia.c pidgin/gtkprefs.c
diffstat 5 files changed, 104 insertions(+), 37 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/media.c	Sun Aug 17 07:55:38 2008 +0000
+++ b/libpurple/media.c	Mon Aug 18 06:25:38 2008 +0000
@@ -47,9 +47,11 @@
 	GstElement *src;
 	GstElement *sink;
 	FsSession *session;
-	GHashTable *streams;		/* FsStream list map to participant's name */
+	/* FsStream table. Mapped by participant's name */
+	GHashTable *streams;
 	PurpleMediaSessionType type;
-	GHashTable *local_candidates;	/* map to participant's name? */
+	/* GList of FsCandidates table. Mapped by participant's name */
+	GHashTable *local_candidates;
 
 	/*
 	 * These will need to be per stream when sessions with multiple
@@ -221,7 +223,6 @@
 purple_media_finalize (GObject *media)
 {
 	PurpleMediaPrivate *priv = PURPLE_MEDIA_GET_PRIVATE(media);
-	GList *sessions = g_hash_table_get_values(priv->sessions);
 	purple_debug_info("media","purple_media_finalize\n");
 
 	purple_media_manager_remove_media(purple_media_manager_get(),
@@ -229,15 +230,42 @@
 
 	g_free(priv->name);
 
-	for (; sessions; sessions = g_list_delete_link(sessions, sessions)) {
-		PurpleMediaSession *session = sessions->data;
-		GList *streams = g_hash_table_get_values(session->streams);
+	if (priv->sessions) {
+		GList *sessions = g_hash_table_get_values(priv->sessions);
+		for (; sessions; sessions = g_list_delete_link(sessions, sessions)) {
+			PurpleMediaSession *session = sessions->data;
+			g_free(session->id);
+
+			if (session->streams) {
+				GList *streams = g_hash_table_get_values(session->streams);
+				for (; streams; streams = g_list_delete_link(streams, streams))
+					g_object_unref(streams->data);
+				g_hash_table_destroy(session->streams);
+			}
 
-		for (; streams; streams = g_list_delete_link(streams, streams)) {
-			g_object_unref(streams->data);
+			if (session->local_candidates) {
+				GList *candidates = g_hash_table_get_values(session->local_candidates);
+				for (; candidates; candidates =
+						g_list_delete_link(candidates, candidates))
+					fs_candidate_list_destroy(candidates->data);
+				g_hash_table_destroy(session->local_candidates);
+			}
+
+			if (session->local_candidate)
+				fs_candidate_destroy(session->local_candidate);
+			if (session->remote_candidate)
+				fs_candidate_destroy(session->remote_candidate);
+
+			g_free(session);
 		}
+		g_hash_table_destroy(priv->sessions);
+	}
 
-		g_object_unref(session->session);
+	if (priv->participants) {
+		GList *participants = g_hash_table_get_values(priv->participants);
+		for (; participants; participants = g_list_delete_link(participants, participants))
+			g_object_unref(participants->data);
+		g_hash_table_destroy(priv->participants);
 	}
 
 	if (priv->pipeline) {
@@ -416,7 +444,7 @@
 		return participant;
 
 	participant = fs_conference_new_participant(media->priv->conference,
-						    g_strdup(name), &err);
+						    (gchar*)name, &err);
 
 	if (err) {
 		purple_debug_error("media", "Error creating participant: %s\n",
@@ -427,7 +455,8 @@
 
 	if (!media->priv->participants) {
 		purple_debug_info("media", "Creating hash table for participants\n");
-		media->priv->participants = g_hash_table_new(g_str_hash, g_str_equal);
+		media->priv->participants = g_hash_table_new_full(g_str_hash,
+				g_str_equal, g_free, NULL);
 	}
 
 	g_hash_table_insert(media->priv->participants, g_strdup(name), participant);
@@ -440,7 +469,8 @@
 {
 	if (!session->streams) {
 		purple_debug_info("media", "Creating hash table for streams\n");
-		session->streams = g_hash_table_new(g_str_hash, g_str_equal);
+		session->streams = g_hash_table_new_full(g_str_hash,
+				g_str_equal, g_free, NULL);
 	}
 
 	g_hash_table_insert(session->streams, g_strdup(name), stream);
@@ -456,7 +486,8 @@
 
 	if (!session->local_candidates) {
 		purple_debug_info("media", "Creating hash table for local candidates\n");
-		session->local_candidates = g_hash_table_new(g_str_hash, g_str_equal);
+		session->local_candidates = g_hash_table_new_full(g_str_hash,
+				g_str_equal, g_free, NULL);
 	}
 
 	g_hash_table_insert(session->local_candidates, g_strdup(name), candidates);
@@ -716,12 +747,14 @@
 
 		array = gst_property_probe_probe_and_get_values (probe, pspec);
 		if (array != NULL) {
-
 			for (n = 0 ; n < array->n_values ; n++) {
 				GValue *device = g_value_array_get_nth (array, n);
+				GValue *location = g_new0(GValue, 1);
 				gst_element_set_state (element, GST_STATE_NULL);
+				location = g_value_init(location, G_TYPE_STRING);
 
-				ret = g_list_append(ret, device);
+				g_value_copy(device, location);
+				ret = g_list_append(ret, location);
 
 				name = purple_media_get_device_name(GST_ELEMENT(element), device);
 				purple_debug_info("media", "Found source '%s' (%s) - device '%s' (%s)\n",
@@ -729,6 +762,7 @@
 						  name, g_value_get_string(device));
 				g_free(name);
 			}
+			g_value_array_free(array);
 		}
 	}
 
@@ -916,6 +950,7 @@
 {
 	gchar *name;
 	FsParticipant *participant;
+	FsCandidate *candidate;
 	purple_debug_info("media", "got new local candidate: %s\n", local_candidate->candidate_id);
 	g_object_get(stream, "participant", &participant, NULL);
 	g_object_get(participant, "cname", &name, NULL);
@@ -923,8 +958,10 @@
 
 	purple_media_insert_local_candidate(session, name, fs_candidate_copy(local_candidate));
 
+	candidate = fs_candidate_copy(local_candidate);
 	g_signal_emit(session->media, purple_media_signals[NEW_CANDIDATE],
-		      0, session->id, name, fs_candidate_copy(local_candidate));
+		      0, session->id, name, candidate);
+	fs_candidate_destroy(candidate);
 
 	g_free(name);
 }
@@ -949,13 +986,18 @@
 					   FsCandidate *remote_candidate,
 					   PurpleMediaSession *session)
 {
+	FsCandidate *local = fs_candidate_copy(native_candidate);
+	FsCandidate *remote = fs_candidate_copy(remote_candidate);
+
 	session->local_candidate = fs_candidate_copy(native_candidate);
 	session->remote_candidate = fs_candidate_copy(remote_candidate);
 
 	purple_debug_info("media", "candidate pair established\n");
 	g_signal_emit(session->media, purple_media_signals[CANDIDATE_PAIR], 0,
-		      session->local_candidate,
-		      session->remote_candidate);
+		      local, remote);
+
+	fs_candidate_destroy(local);
+	fs_candidate_destroy(remote);
 }
 
 static void
@@ -1077,9 +1119,7 @@
 
 			param[0].name = "stun-ip";
 			g_value_init(&param[0].value, G_TYPE_STRING);
-			g_value_set_string(&param[0].value, stun_ip);
-
-			g_free(stun_ip);
+			g_value_take_string(&param[0].value, stun_ip);
 
 			param[1].name = "stun-timeout";
 			g_value_init(&param[1].value, G_TYPE_UINT);
@@ -1088,6 +1128,7 @@
 			stream = fs_session_new_stream(session->session,
 					participant, type_direction,
 					transmitter, 2, param, &err);
+			g_free(stun_ip);
 		} else {
 			stream = fs_session_new_stream(session->session,
 					participant, type_direction,
@@ -1181,7 +1222,8 @@
 purple_media_get_local_candidates(PurpleMedia *media, const gchar *sess_id, const gchar *name)
 {
 	PurpleMediaSession *session = purple_media_get_session(media, sess_id);
-	return purple_media_session_get_local_candidates(session, name);
+	return fs_candidate_list_copy(
+			purple_media_session_get_local_candidates(session, name));
 }
 
 GList *
--- a/libpurple/protocols/jabber/jingle.c	Sun Aug 17 07:55:38 2008 +0000
+++ b/libpurple/protocols/jabber/jingle.c	Mon Aug 18 06:25:38 2008 +0000
@@ -253,6 +253,8 @@
 	GList *contents;
 	g_hash_table_remove(sess->js->sessions, sess->id);
 	g_free(sess->id);
+	g_free(sess->remote_jid);
+	g_free(sess->initiator);
 
 	if (sess->media)
 		g_object_unref(sess->media);
@@ -395,9 +397,11 @@
 
 static void
 jabber_jingle_session_set_remote_jid(JingleSession *sess, 
-									 const char *remote_jid)
+				     const char *remote_jid)
 {
-	sess->remote_jid = strdup(remote_jid);
+	if (sess->remote_jid)
+		g_free(sess->remote_jid);
+	sess->remote_jid = g_strdup(remote_jid);
 }
 
 static JingleSessionState
@@ -422,8 +426,10 @@
 
 static void
 jabber_jingle_session_set_initiator(JingleSession *sess,
-									const char *initiator)
+				    const char *initiator)
 {
+	if (sess->initiator)
+		g_free(sess->initiator);
 	sess->initiator = g_strdup(initiator);
 }
 
--- a/pidgin/gtkconv.c	Sun Aug 17 07:55:38 2008 +0000
+++ b/pidgin/gtkconv.c	Mon Aug 18 06:25:38 2008 +0000
@@ -7745,10 +7745,13 @@
 	GtkWidget *gtkmedia;
 	PurpleConversation *conv;
 	PidginConversation *gtkconv;
+	gchar *name = purple_media_get_screenname(media);
 
 	conv = purple_conversation_new(PURPLE_CONV_TYPE_IM,
-				       purple_connection_get_account(purple_media_get_connection(media)),
-				       purple_media_get_screenname(media));
+			purple_connection_get_account(
+			purple_media_get_connection(media)), name);
+	g_free(name);
+
 	gtkconv = PIDGIN_CONVERSATION(conv);
 
 	if (gtkconv->gtkmedia) {
--- a/pidgin/gtkmedia.c	Sun Aug 17 07:55:38 2008 +0000
+++ b/pidgin/gtkmedia.c	Mon Aug 18 06:25:38 2008 +0000
@@ -194,7 +194,7 @@
 level_message_cb(GstBus *bus, GstMessage *message, PidginMedia *gtkmedia)
 {
 	const GstStructure *s;
-	const gchar *name;
+	gchar *name;
 
 	gdouble rms_db;
 	gdouble percent;
@@ -207,9 +207,8 @@
 		return TRUE;
 
 	s = gst_message_get_structure(message);
-	name = gst_structure_get_name(s);
 
-	if (strcmp(name, "level"))
+	if (strcmp(gst_structure_get_name(s), "level"))
 		return TRUE;
 
 	list = gst_structure_get_value(s, "rms");
@@ -223,11 +222,13 @@
 	if(percent > 1.0)
 		percent = 1.0;
 
-	if (!strcmp(gst_element_get_name(src), "sendlevel"))	
+	name = gst_element_get_name(src);
+	if (!strcmp(name, "sendlevel"))	
 		gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(gtkmedia->priv->send_progress), percent);
 	else
 		gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(gtkmedia->priv->recv_progress), percent);
 
+	g_free(name);
 	return TRUE;
 }
 
@@ -465,20 +466,23 @@
 {
 	PurpleMediaSessionType type = purple_media_get_overall_type(media);
 	gchar *message;
+	gchar *name = purple_media_get_screenname(media);
 
 	if (type & PURPLE_MEDIA_AUDIO && type & PURPLE_MEDIA_VIDEO) {
 		message = g_strdup_printf(_("%s wishes to start an audio/video session with you."),
-					  purple_media_get_screenname(media));
+					  name);
 	} else if (type & PURPLE_MEDIA_AUDIO) {
 		message = g_strdup_printf(_("%s wishes to start an audio session with you."),
-					  purple_media_get_screenname(media));
+					  name);
 	} else if (type & PURPLE_MEDIA_VIDEO) {
 		message = g_strdup_printf(_("%s wishes to start a video session with you."),
-					  purple_media_get_screenname(media));
+					  name);
 	} else {
+		g_free(name);
 		return;
 	}
 
+	g_free(name);
 	pidgin_media_emit_message(gtkmedia, message);
 	g_free(message);
 }
--- a/pidgin/gtkprefs.c	Sun Aug 17 07:55:38 2008 +0000
+++ b/pidgin/gtkprefs.c	Mon Aug 18 06:25:38 2008 +0000
@@ -2121,7 +2121,11 @@
 	if (video != NULL) {
 		GList *video_devices = purple_media_get_devices(video);
 		video_items = get_device_items(video, video_devices);
-		g_list_free(video_devices);
+		for(; video_devices; video_devices = g_list_delete_link(
+				video_devices, video_devices)) {
+			g_value_unset(video_devices->data);
+			g_free(video_devices->data);
+		}
 	}
 
 	if (video_items == NULL) {
@@ -2227,13 +2231,21 @@
 	if (video != NULL) {
 		GList *video_devices = purple_media_get_devices(video);
 		video_items = get_device_items(video, video_devices);
-		g_list_free(video_devices);
+		for(; video_devices; video_devices = g_list_delete_link(
+				video_devices, video_devices)) {
+			g_value_unset(video_devices->data);
+			g_free(video_devices->data);
+		}
 	}
 
 	if (audio != NULL) {		
 		GList *audio_devices = purple_media_get_devices(audio);
 		audio_items = get_device_items(audio, audio_devices);
-		g_list_free(audio_devices);
+		for(; audio_devices; audio_devices = g_list_delete_link(
+				audio_devices, audio_devices)) {
+			g_value_unset(audio_devices->data);
+			g_free(audio_devices->data);
+		}
 	}
 
 	if (video_items == NULL) {