/soc/2015/igor.gajowiak/chatlog: 65a053b47b78: Optimized memory ...
Igor Gajowiak <[email protected]>
| Newsgroups | gmane.comp.gnome.gaim.cvs |
|---|---|
| Message-ID | <[email protected]> |
Changeset: 65a053b47b788890565533d2d25522a98d3d163a Author: Igor Gajowiak <[email protected]> Date: 2015-08-15 19:55 +0200 Branch: default URL: https://hg.pidgin.im/soc/2015/igor.gajowiak/chatlog/rev/65a053b47b78 Description: Optimized memory consumtion. Changed PurpleMessage hashtable so that is keeps weak references. diffstat: finch/gntpounce.c | 3 ++ libpurple/conversation.c | 11 ++++++++- libpurple/message.c | 24 +++++++++++++++++++--- libpurple/message.h | 15 +++++++++---- libpurple/plugins/log/legacylog.c | 1 - libpurple/plugins/log/logsqlite.c | 1 - libpurple/plugins/offlinemsg.c | 7 ++++- libpurple/plugins/tcl/tcl_cmds.c | 7 +++++- libpurple/protocols/gg/chat.c | 2 + libpurple/protocols/gg/message-prpl.c | 2 + libpurple/protocols/irc/cmds.c | 27 +++++++++++++++++++------ libpurple/protocols/jabber/jabber.c | 7 ++++- libpurple/protocols/silc/silc.c | 26 ++++++++++++++++++------ libpurple/protocols/yahoo/ymsg.c | 9 ++++++- libpurple/server.c | 21 ++++++++++++++++--- pidgin/gtkpounce.c | 2 + pidgin/plugins/musicmessaging/musicmessaging.c | 16 +++++++++++--- 17 files changed, 139 insertions(+), 42 deletions(-) diffs (truncated from 539 to 300 lines): diff --git a/finch/gntpounce.c b/finch/gntpounce.c --- a/finch/gntpounce.c +++ b/finch/gntpounce.c @@ -876,8 +876,11 @@ pounce_cb(PurplePounce *pounce, PurplePo im = purple_im_conversation_new(account, pouncee); pmsg = purple_message_new_outgoing(pouncee, message, 0); + purple_serv_send_im(purple_account_get_connection(account), pmsg); purple_conversation_write_message(PURPLE_CONVERSATION(im), pmsg); + + g_object_unref(G_OBJECT(pmsg)); } } diff --git a/libpurple/conversation.c b/libpurple/conversation.c --- a/libpurple/conversation.c +++ b/libpurple/conversation.c @@ -141,6 +141,8 @@ common_send(PurpleConversation *conv, co purple_signal_emit(purple_conversations_get_handle(), "sent-im-msg", account, msg); } + + g_object_unref(G_OBJECT(msg)); } else if (PURPLE_IS_CHAT_CONVERSATION(conv)) { int id = purple_chat_conversation_get_id(PURPLE_CHAT_CONVERSATION(conv)); @@ -156,6 +158,8 @@ common_send(PurpleConversation *conv, co purple_signal_emit(purple_conversations_get_handle(), "sent-chat-msg", account, msg, id); } + + g_object_unref(G_OBJECT(msg)); } if (err < 0) { @@ -804,8 +808,9 @@ purple_conversation_replace_message(Purp void purple_conversation_write_system_message(PurpleConversation *conv, const gchar *message, PurpleMessageFlags flags) { - _purple_conversation_write_common(conv, - purple_message_new_system(message, flags)); + PurpleMessage *msg = purple_message_new_system(message, flags); + _purple_conversation_write_common(conv, msg); + g_object_unref(G_OBJECT(msg)); } void @@ -852,6 +857,8 @@ purple_conversation_send_replace_message // Replace message in conversation if sending succeeded if (purple_serv_send_replace_im(gc, replaced_msg_id, msg)) purple_conversation_replace_message(conv, replaced_msg_id, msg); + + g_object_unref(G_OBJECT(msg)); } else if (PURPLE_IS_CHAT_CONVERSATION(conv)) { // TODO: Do we need to implement this? diff --git a/libpurple/message.c b/libpurple/message.c --- a/libpurple/message.c +++ b/libpurple/message.c @@ -56,6 +56,11 @@ enum static GObjectClass *parent_class; static GParamSpec *properties[PROP_LAST]; +/* + * Contains weak (non-owning) references to #PurpleMessage. Calling + * g_object_unref on a message with refcnt equal to 1 automatically removes + * entry from this map. + */ static GHashTable *messages = NULL; /****************************************************************************** @@ -147,7 +152,7 @@ purple_message_find_by_id(guint id) { g_return_val_if_fail(id > 0, NULL); - return g_hash_table_lookup(messages, GINT_TO_POINTER(id)); + return g_hash_table_lookup(messages, GUINT_TO_POINTER(id)); } const gchar * @@ -259,6 +264,13 @@ generate_next_id() return id++; } +static void remove_message_from_hashtable(gpointer data, + GObject *where_the_object_was) +{ + guint id = GPOINTER_TO_UINT(data); + g_hash_table_remove(messages, GUINT_TO_POINTER(id)); +} + static void purple_message_init(GTypeInstance *instance, gpointer klass) { @@ -270,7 +282,11 @@ purple_message_init(GTypeInstance *insta purple_marshal_VOID__POINTER, G_TYPE_NONE, 1, PURPLE_TYPE_MESSAGE); priv->id = generate_next_id(); - g_hash_table_insert(messages, GINT_TO_POINTER(priv->id), msg); + g_hash_table_insert(messages, GUINT_TO_POINTER(priv->id), msg); + + /* Register a callback for removing weak reference from hash table */ + g_object_weak_ref(G_OBJECT(msg), remove_message_from_hashtable, + GUINT_TO_POINTER(priv->id)); } static void @@ -423,8 +439,8 @@ purple_message_get_type(void) void _purple_message_init(void) { - messages = g_hash_table_new_full(g_direct_hash, g_direct_equal, - NULL, g_object_unref); + /* Hashtable contains non-owning references to PurpleMessage */ + messages = g_hash_table_new(g_direct_hash, g_direct_equal); } void diff --git a/libpurple/message.h b/libpurple/message.h --- a/libpurple/message.h +++ b/libpurple/message.h @@ -96,7 +96,8 @@ purple_message_get_type(void); * * This function should be used when a complete * message deserialization is needed. For sending or receiving a message - * see purple_message_new_outgoing, purple_message_new_incoming. + * see purple_message_new_outgoing, purple_message_new_incoming. Message must be + * freed using g_object_unref. * * Returns: the new #PurpleMessage. */ @@ -113,7 +114,8 @@ purple_message_new(const gchar *author, * * Creates new outgoing message (the user is the author). * - * You don't need to set the #PURPLE_MESSAGE_SEND flag. + * You don't need to set the #PURPLE_MESSAGE_SEND flag. Message must be freed + * using g_object_unref. * * Returns: the new #PurpleMessage. */ @@ -130,7 +132,8 @@ purple_message_new_outgoing(const gchar * * Creates new incoming message (the user is the recipient). * - * You don't need to set the #PURPLE_MESSAGE_RECV flag. + * You don't need to set the #PURPLE_MESSAGE_RECV flag. Message must be freed + * using g_object_unref. * * Returns: the new #PurpleMessage. */ @@ -145,7 +148,8 @@ purple_message_new_incoming(const gchar * * Creates new system message. * - * You don't need to set the #PURPLE_MESSAGE_SYSTEM flag. + * You don't need to set the #PURPLE_MESSAGE_SYSTEM flag. Message must be freed + * using g_object_unref. * * Returns: the new #PurpleMessage. */ @@ -168,7 +172,8 @@ purple_message_get_id(const PurpleMessag * purple_message_find_by_id: * @id: The message identifier. * - * Finds the message with a given @id. + * Finds the message with a given @id. Does not increase the refcount of + * the found message. * * Returns: the #PurpleMessage, or %NULL if not found. */ diff --git a/libpurple/plugins/log/legacylog.c b/libpurple/plugins/log/legacylog.c --- a/libpurple/plugins/log/legacylog.c +++ b/libpurple/plugins/log/legacylog.c @@ -472,7 +472,6 @@ fill_arrays(gchar *text, GArray *account g_object_ref(G_OBJECT(acc)); g_object_ref(G_OBJECT(contact)); - g_object_ref(G_OBJECT(msg)); g_array_append_val(accounts, acc); g_array_append_val(contacts, contact); diff --git a/libpurple/plugins/log/logsqlite.c b/libpurple/plugins/log/logsqlite.c --- a/libpurple/plugins/log/logsqlite.c +++ b/libpurple/plugins/log/logsqlite.c @@ -755,7 +755,6 @@ sqlitelog_execute_get_msgs_query(sqlite3 g_object_set_data(G_OBJECT(msg), SQLITELOG_MESSAGE_ID_ATTR, GUINT_TO_POINTER(id)); - g_object_ref(G_OBJECT(msg)); messages = g_list_prepend(messages, msg); } diff --git a/libpurple/plugins/offlinemsg.c b/libpurple/plugins/offlinemsg.c --- a/libpurple/plugins/offlinemsg.c +++ b/libpurple/plugins/offlinemsg.c @@ -108,9 +108,12 @@ record_pounce(OfflineMsg *offline) GINT_TO_POINTER(OFFLINE_MSG_YES)); /* TODO: use a reference to a PurpleMessage */ - purple_conversation_write_message(conv, - purple_message_new_outgoing(offline->who, offline->message, 0)); + PurpleMessage *msg = purple_message_new_outgoing( + offline->who, offline->message, 0); + purple_conversation_write_message(conv, msg); + + g_object_unref(G_OBJECT(msg)); discard_data(offline); } diff --git a/libpurple/plugins/tcl/tcl_cmds.c b/libpurple/plugins/tcl/tcl_cmds.c --- a/libpurple/plugins/tcl/tcl_cmds.c +++ b/libpurple/plugins/tcl/tcl_cmds.c @@ -877,6 +877,7 @@ int tcl_cmd_conversation(ClientData unus break; } purple_conversation_write_message(convo, pmsg); + g_object_unref(G_OBJECT(pmsg)); break; case CMD_CONV_NAME: if (objc != 3) { @@ -1413,7 +1414,11 @@ int tcl_cmd_send_im(ClientData unused, T who = Tcl_GetString(objv[2]); text = Tcl_GetString(objv[3]); - purple_serv_send_im(gc, purple_message_new_outgoing(who, text, 0)); + PurpleMessage *msg = purple_message_new_outgoing(who, text, 0); + + purple_serv_send_im(gc, msg); + + g_object_unref(G_OBJECT(msg)); return TCL_OK; } diff --git a/libpurple/protocols/gg/chat.c b/libpurple/protocols/gg/chat.c --- a/libpurple/protocols/gg/chat.c +++ b/libpurple/protocols/gg/chat.c @@ -530,6 +530,8 @@ void ggp_chat_got_message(PurpleConnecti purple_conversation_write_message( PURPLE_CONVERSATION(chat->conv), pmsg); + + g_object_unref(G_OBJECT(pmsg)); } else { purple_serv_got_chat_in(gc, chat->local_id, ggp_uin_to_str(who), PURPLE_MESSAGE_RECV, message, time); diff --git a/libpurple/protocols/gg/message-prpl.c b/libpurple/protocols/gg/message-prpl.c --- a/libpurple/protocols/gg/message-prpl.c +++ b/libpurple/protocols/gg/message-prpl.c @@ -241,6 +241,8 @@ static void ggp_message_got_display(Purp purple_message_set_time(pmsg, msg->time); purple_conversation_write_message(PURPLE_CONVERSATION(im), pmsg); + + g_object_unref(G_OBJECT(pmsg)); } else purple_debug_error("gg", "ggp_message_got_display: " "unexpected message type: %d\n", msg->type); diff --git a/libpurple/protocols/irc/cmds.c b/libpurple/protocols/irc/cmds.c --- a/libpurple/protocols/irc/cmds.c +++ b/libpurple/protocols/irc/cmds.c @@ -122,8 +122,11 @@ int irc_cmd_ctcp_action(struct irc_conn } g_free(msg); - if (purple_message_is_empty(pmsg)) + if (purple_message_is_empty(pmsg)) { + g_object_unref(G_OBJECT(pmsg)); return 0; + } + msg = g_strdup(purple_message_get_contents(pmsg)); /* XXX: is it really necessary? */ if (strncmp(msg, "/me ", 4) != 0) { @@ -188,12 +191,18 @@ int irc_cmd_ctcp_action(struct irc_conn purple_serv_got_chat_in(gc, purple_chat_conversation_get_id(PURPLE_CHAT_CONVERSATION(convo)), purple_connection_get_display_name(gc), PURPLE_MESSAGE_SEND, action, time(NULL)); - else - purple_conversation_write_message(convo, purple_message_new_outgoing( - purple_connection_get_display_name(gc), action, 0)); + else { + PurpleMessage *pmsg2 = purple_message_new_outgoing( + purple_connection_get_display_name(gc), action, 0); + + purple_conversation_write_message(convo, pmsg2); + + g_object_unref(G_OBJECT(pmsg2)); + } g_free(action); } + g_object_unref(G_OBJECT(pmsg)); return 1; } @@ -501,9 +510,13 @@ int irc_cmd_query(struct irc_conn *irc, if (args[1]) { _______________________________________________ Commits mailing list [email protected] https://pidgin.im/cgi-bin/mailman/listinfo/commits