/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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.