# HG changeset patch # User Mike Ruprecht # Date 1219040738 0 # Node ID c48f5c9600c38a8b9cc11c0dc77c44d9df0e59d6 # Parent f10e0ac245951f989dcf9b24541a92aa1398e979 Fixed a ton of memory leaks. diff -r f10e0ac24595 -r c48f5c9600c3 libpurple/media.c --- 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(¶m[0].value, G_TYPE_STRING); - g_value_set_string(¶m[0].value, stun_ip); - - g_free(stun_ip); + g_value_take_string(¶m[0].value, stun_ip); param[1].name = "stun-timeout"; g_value_init(¶m[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 * diff -r f10e0ac24595 -r c48f5c9600c3 libpurple/protocols/jabber/jingle.c --- 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); } diff -r f10e0ac24595 -r c48f5c9600c3 pidgin/gtkconv.c --- 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) { diff -r f10e0ac24595 -r c48f5c9600c3 pidgin/gtkmedia.c --- 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); } diff -r f10e0ac24595 -r c48f5c9600c3 pidgin/gtkprefs.c --- 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) {