/soc/2015/igor.gajowiak/chatlog: 65a053b47b78: Optimized memory ...
Igor Gajowiak
igor.gajowiak at gmail.com
Sat Aug 15 13:55:44 EDT 2015
Changeset: 65a053b47b788890565533d2d25522a98d3d163a
Author: Igor Gajowiak <igor.gajowiak at gmail.com>
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]) {
More information about the Commits
mailing list