pidgin: b3ac8324: Add purple_{buddy,chat,group,contact}_de...
elb at pidgin.im
elb at pidgin.im
Thu Apr 9 14:10:45 EDT 2009
-----------------------------------------------------------------
Revision: b3ac8324be2c3d155c50216ff7522ec7319984b1
Ancestor: 3c568b43fb4447b65a2b06e6767340edd7763c53
Author: hebnern at gmail.com
Date: 2009-04-09T17:33:20
Branch: im.pidgin.pidgin
URL: http://d.pidgin.im/viewmtn/revision/info/b3ac8324be2c3d155c50216ff7522ec7319984b1
Modified files:
ChangeLog ChangeLog.API libpurple/blist.c libpurple/blist.h
ChangeLog:
Add purple_{buddy,chat,group,contact}_destroy to the blist API, free
blist data on libpurple unload. Thanks to Nick Hebner for this.
References #8683
-------------- next part --------------
============================================================
--- ChangeLog 0d73d8f31689920d271ad056dad78384aba1a429
+++ ChangeLog b899615cdebcbb5504177c480a4281bf62742fea
@@ -9,6 +9,9 @@ version 2.6.0 (??/??/2009):
* Removed the unmaintained and unneeded toc protocol plugin.
* Fixed NTLM authentication on big-endian systems.
+ libpurple:
+ * Various memory cleanups when unloading libpurple. (Nick Hebner)
+
XMPP:
* Add voice & video support with Jingle (XEP-0166, 0167, 0176, & 0177),
and voice support with GTalk and GMail. (Mike "Maiku" Ruprecht)
============================================================
--- ChangeLog.API c4516b9a52728841169223a990807bebf1942b0c
+++ ChangeLog.API bec918fce75f383e5e5c0a38ed5b7cc48cc9457b
@@ -9,6 +9,7 @@ version 2.6.0 (??/??/2009):
* PURPLE_CONTACT
* PURPLE_BUDDY
* PURPLE_CHAT
+ * purple_buddy_destroy
* purple_buddy_get_protocol_data
* purple_buddy_set_protocol_data
* purple_buddy_get_local_buddy_alias
@@ -17,9 +18,12 @@ version 2.6.0 (??/??/2009):
* purple_blist_set_ui_data
* purple_blist_node_get_ui_data
* purple_blist_node_set_ui_data
+ * purple_chat_destroy
* purple_connection_get_protocol_data
* purple_connection_set_protocol_data
+ * purple_contact_destroy
* purple_global_proxy_set_info
+ * purple_group_destroy
* purple_log_get_activity_score
* purple_network_force_online
* purple_network_set_stun_server
============================================================
--- libpurple/blist.c ba2294dc081c1a8f1d5ba8bfd5d19768869d90f1
+++ libpurple/blist.c 11e434ee9e713dc54b4f5affb7e5e6d1e03a8750
@@ -1202,6 +1202,16 @@ PurpleChat *purple_chat_new(PurpleAccoun
return chat;
}
+void
+purple_chat_destroy(PurpleChat *chat)
+{
+ g_hash_table_destroy(chat->components);
+ g_hash_table_destroy(chat->node.settings);
+ g_free(chat->alias);
+ PURPLE_DBUS_UNREGISTER_POINTER(chat);
+ g_free(chat);
+}
+
PurpleBuddy *purple_buddy_new(PurpleAccount *account, const char *name, const char *alias)
{
PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
@@ -1229,6 +1239,40 @@ void
}
void
+purple_buddy_destroy(PurpleBuddy *buddy)
+{
+ PurplePlugin *prpl;
+ PurplePluginProtocolInfo *prpl_info;
+
+ /*
+ * Tell the owner PRPL that we're about to free the buddy so it
+ * can free proto_data
+ */
+ prpl = purple_find_prpl(purple_account_get_protocol_id(buddy->account));
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
+ if (prpl_info && prpl_info->buddy_free)
+ prpl_info->buddy_free(buddy);
+
+ /* Delete the node */
+ purple_buddy_icon_unref(buddy->icon);
+ g_hash_table_destroy(buddy->node.settings);
+ purple_presence_destroy(buddy->presence);
+ g_free(buddy->name);
+ g_free(buddy->alias);
+ g_free(buddy->server_alias);
+
+ PURPLE_DBUS_UNREGISTER_POINTER(buddy);
+ g_free(buddy);
+
+ /* FIXME: Once PurpleBuddy is a GObject, timeout callbacks can
+ * g_object_ref() it when connecting the callback and
+ * g_object_unref() it in the handler. That way, it won't
+ * get freed while the timeout is pending and this line can
+ * be removed. */
+ while (g_source_remove_by_user_data((gpointer *)buddy));
+}
+
+void
purple_buddy_set_icon(PurpleBuddy *buddy, PurpleBuddyIcon *icon)
{
g_return_if_fail(buddy != NULL);
@@ -1519,6 +1563,14 @@ PurpleContact *purple_contact_new()
return contact;
}
+void
+purple_contact_destroy(PurpleContact *contact)
+{
+ g_hash_table_destroy(contact->node.settings);
+ PURPLE_DBUS_UNREGISTER_POINTER(contact);
+ g_free(contact);
+}
+
void purple_contact_set_alias(PurpleContact *contact, const char *alias)
{
purple_blist_alias_contact(contact,alias);
@@ -1588,6 +1640,15 @@ PurpleGroup *purple_group_new(const char
return group;
}
+void
+purple_group_destroy(PurpleGroup *group)
+{
+ g_hash_table_destroy(group->node.settings);
+ g_free(group->name);
+ PURPLE_DBUS_UNREGISTER_POINTER(group);
+ g_free(group);
+}
+
void purple_blist_add_contact(PurpleContact *contact, PurpleGroup *group, PurpleBlistNode *node)
{
PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
@@ -1848,9 +1909,7 @@ void purple_blist_remove_contact(PurpleC
ops->remove(purplebuddylist, node);
/* Delete the node */
- g_hash_table_destroy(contact->node.settings);
- PURPLE_DBUS_UNREGISTER_POINTER(contact);
- g_free(contact);
+ purple_contact_destroy(contact);
}
}
@@ -1861,8 +1920,6 @@ void purple_blist_remove_buddy(PurpleBud
PurpleContact *contact;
PurpleGroup *group;
struct _purple_hbuddy hb;
- PurplePlugin *prpl;
- PurplePluginProtocolInfo *prpl_info = NULL;
g_return_if_fail(buddy != NULL);
@@ -1918,34 +1975,8 @@ void purple_blist_remove_buddy(PurpleBud
/* Signal that the buddy has been removed before freeing the memory for it */
purple_signal_emit(purple_blist_get_handle(), "buddy-removed", buddy);
- /*
- * Tell the owner PRPL that we're about to free the buddy so it
- * can free proto_data
- */
- prpl = purple_find_prpl(purple_account_get_protocol_id(buddy->account));
- if (prpl)
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
- if (prpl_info && prpl_info->buddy_free)
- prpl_info->buddy_free(buddy);
+ purple_buddy_destroy(buddy);
- /* Delete the node */
- purple_buddy_icon_unref(buddy->icon);
- g_hash_table_destroy(buddy->node.settings);
- purple_presence_destroy(buddy->presence);
- g_free(buddy->name);
- g_free(buddy->alias);
- g_free(buddy->server_alias);
-
- PURPLE_DBUS_UNREGISTER_POINTER(buddy);
- g_free(buddy);
-
- /* FIXME: Once PurpleBuddy is a GObject, timeout callbacks can
- * g_object_ref() it when connecting the callback and
- * g_object_unref() it in the handler. That way, it won't
- * get freed while the timeout is pending and this line can
- * be removed. */
- while (g_source_remove_by_user_data((gpointer *)buddy));
-
/* If the contact is empty then remove it */
if ((contact != NULL) && !cnode->child)
purple_blist_remove_contact(contact);
@@ -1988,11 +2019,7 @@ void purple_blist_remove_chat(PurpleChat
ops->remove(purplebuddylist, node);
/* Delete the node */
- g_hash_table_destroy(chat->components);
- g_hash_table_destroy(chat->node.settings);
- g_free(chat->alias);
- PURPLE_DBUS_UNREGISTER_POINTER(chat);
- g_free(chat);
+ purple_chat_destroy(chat);
}
void purple_blist_remove_group(PurpleGroup *group)
@@ -2033,10 +2060,7 @@ void purple_blist_remove_group(PurpleGro
}
/* Delete the node */
- g_hash_table_destroy(group->node.settings);
- g_free(group->name);
- PURPLE_DBUS_UNREGISTER_POINTER(group);
- g_free(group);
+ purple_group_destroy(group);
}
PurpleBuddy *purple_contact_get_priority_buddy(PurpleContact *contact)
@@ -2587,6 +2611,28 @@ static void
}
static void
+purple_blist_node_destroy(PurpleBlistNode *node)
+{
+ PurpleBlistNode *child, *next_child;
+
+ child = node->child;
+ while (child) {
+ next_child = child->next;
+ purple_blist_node_destroy(child);
+ child = next_child;
+ }
+
+ if (PURPLE_BLIST_NODE_IS_BUDDY(node))
+ purple_buddy_destroy((PurpleBuddy*)node);
+ else if (PURPLE_BLIST_NODE_IS_CHAT(node))
+ purple_chat_destroy((PurpleChat*)node);
+ else if (PURPLE_BLIST_NODE_IS_CONTACT(node))
+ purple_contact_destroy((PurpleContact*)node);
+ else if (PURPLE_BLIST_NODE_IS_GROUP(node))
+ purple_group_destroy((PurpleGroup*)node);
+}
+
+static void
purple_blist_node_setting_free(gpointer data)
{
PurpleValue *value;
@@ -2874,12 +2920,20 @@ purple_blist_uninit(void)
void
purple_blist_uninit(void)
{
- if (save_timer != 0)
- {
+ PurpleBlistNode *node, *next_node;
+
+ if (save_timer != 0) {
purple_timeout_remove(save_timer);
save_timer = 0;
purple_blist_sync();
}
+ node = purple_blist_get_root();
+ while (node) {
+ next_node = node->next;
+ purple_blist_node_destroy(node);
+ node = next_node;
+ }
+
purple_signals_unregister_by_instance(purple_blist_get_handle());
}
============================================================
--- libpurple/blist.h 93ef934fff7f894ba39a2024fdac4a77c86c49c2
+++ libpurple/blist.h b1d8652bb542bc432a48db33454250a44b26b797
@@ -478,6 +478,13 @@ PurpleChat *purple_chat_new(PurpleAccoun
PurpleChat *purple_chat_new(PurpleAccount *account, const char *alias, GHashTable *components);
/**
+ * Destroys a chat
+ *
+ * @param chat The chat to destroy
+ */
+void purple_chat_destroy(PurpleChat *chat);
+
+/**
* Adds a new chat to the buddy list.
*
* The chat will be inserted right after node or appended to the end
@@ -501,6 +508,13 @@ PurpleBuddy *purple_buddy_new(PurpleAcco
PurpleBuddy *purple_buddy_new(PurpleAccount *account, const char *name, const char *alias);
/**
+ * Destroys a buddy
+ *
+ * @param buddy The buddy to destroy
+ */
+void purple_buddy_destroy(PurpleBuddy *buddy);
+
+/**
* Sets a buddy's icon.
*
* This should only be called from within Purple. You probably want to
@@ -611,6 +625,13 @@ PurpleGroup *purple_group_new(const char
PurpleGroup *purple_group_new(const char *name);
/**
+ * Destroys a group
+ *
+ * @param group The group to destroy
+*/
+void purple_group_destroy(PurpleGroup *group);
+
+/**
* Adds a new group to the buddy list.
*
* The new group will be inserted after insert or prepended to the list if
@@ -629,6 +650,13 @@ PurpleContact *purple_contact_new(void);
PurpleContact *purple_contact_new(void);
/**
+ * Destroys a contact
+ *
+ * @param contact The contact to destroy
+ */
+void purple_contact_destroy(PurpleContact *contact);
+
+/**
* Adds a new contact to the buddy list.
*
* The new contact will be inserted after insert or prepended to the list if
More information about the Commits
mailing list