/soc/2013/ankitkv/gobjectification: e436eabb9a84: Merged default...

Ankit Vani a at nevitus.org
Tue Jul 23 19:26:00 EDT 2013


Changeset: e436eabb9a84349ce3026c2a5a87e5e6a6258d36
Author:	 Ankit Vani <a at nevitus.org>
Date:	 2013-07-24 04:55 +0530
Branch:	 soc.2013.gobjectification
URL: https://hg.pidgin.im/soc/2013/ankitkv/gobjectification/rev/e436eabb9a84

Description:

Merged default branch

diffstat:

 libpurple/http.c                  |  352 ++++++++++++---
 libpurple/http.h                  |   27 +-
 libpurple/protocols/msn/contact.c |   38 +-
 libpurple/protocols/msn/nexus.c   |   22 +-
 libpurple/protocols/msn/oim.c     |   17 +-
 libpurple/protocols/msn/session.c |    8 +-
 libpurple/protocols/msn/session.h |    4 +-
 libpurple/protocols/msn/soap.c    |  822 +++++++++----------------------------
 libpurple/protocols/msn/soap.h    |   37 +-
 9 files changed, 567 insertions(+), 760 deletions(-)

diffs (truncated from 1916 to 300 lines):

diff --git a/libpurple/http.c b/libpurple/http.c
--- a/libpurple/http.c
+++ b/libpurple/http.c
@@ -44,6 +44,10 @@ typedef struct _PurpleHttpSocket PurpleH
 
 typedef struct _PurpleHttpHeaders PurpleHttpHeaders;
 
+typedef struct _PurpleHttpKeepaliveHost PurpleHttpKeepaliveHost;
+
+typedef struct _PurpleHttpKeepaliveRequest PurpleHttpKeepaliveRequest;
+
 typedef void (*PurpleHttpSocketConnectCb)(PurpleHttpSocket *hs,
 	const gchar *error, gpointer user_data);
 
@@ -52,8 +56,7 @@ struct _PurpleHttpSocket
 	gboolean is_ssl;
 	gboolean is_busy;
 	uint use_count;
-	PurpleHttpKeepalivePool *pool;
-	gchar *hash;
+	PurpleHttpKeepaliveHost *host;
 
 	PurpleSslConnection *ssl_connection;
 	PurpleProxyConnectData *raw_connection;
@@ -94,11 +97,13 @@ struct _PurpleHttpConnection
 	gpointer user_data;
 	gboolean is_reading;
 	gboolean is_keepalive;
+	gboolean is_cancelling;
 
 	PurpleHttpURL *url;
 	PurpleHttpRequest *request;
 	PurpleHttpResponse *response;
 
+	PurpleHttpKeepaliveRequest *socket_request;
 	PurpleHttpSocket *socket;
 	GString *request_header;
 	int request_header_written, request_contents_written;
@@ -166,11 +171,39 @@ struct _PurpleHttpCookieJar
 	GHashTable *tab;
 };
 
+struct _PurpleHttpKeepaliveRequest
+{
+	PurpleConnection *gc;
+	PurpleHttpSocketConnectCb cb;
+	gpointer user_data;
+
+	PurpleHttpKeepaliveHost *host;
+	PurpleHttpSocket *hs;
+};
+
+struct _PurpleHttpKeepaliveHost
+{
+	PurpleHttpKeepalivePool *pool;
+
+	gchar *host;
+	int port;
+	gboolean is_ssl;
+
+	GSList *sockets; /* list of PurpleHttpSocket */
+
+	GSList *queue; /* list of PurpleHttpKeepaliveRequest */
+	guint process_queue_timeout;
+};
+
 struct _PurpleHttpKeepalivePool
 {
+	gboolean is_destroying;
+
 	int ref_count;
 
-	/* key: purple_http_socket_hash, value: GSList of PurpleHttpSocket */
+	guint limit_per_host;
+
+	/* key: purple_http_socket_hash, value: PurpleHttpKeepaliveHost */
 	GHashTable *by_hash;
 };
 
@@ -194,11 +227,13 @@ static void purple_http_cookie_jar_parse
 static gchar * purple_http_cookie_jar_gen(PurpleHttpCookieJar *cookie_jar);
 gchar * purple_http_cookie_jar_dump(PurpleHttpCookieJar *cjar);
 
-static PurpleHttpSocket *
+static PurpleHttpKeepaliveRequest *
 purple_http_keepalive_pool_request(PurpleHttpKeepalivePool *pool,
 	PurpleConnection *gc, const gchar *host, int port, gboolean is_ssl,
 	PurpleHttpSocketConnectCb cb, gpointer user_data);
 static void
+purple_http_keepalive_pool_request_cancel(PurpleHttpKeepaliveRequest *req);
+static void
 purple_http_keepalive_pool_release(PurpleHttpSocket *hs, gboolean invalidate);
 
 static GRegex *purple_http_re_url, *purple_http_re_url_host,
@@ -229,23 +264,6 @@ static GHashTable *purple_http_hc_by_ptr
 
 /*** Helper functions *********************************************************/
 
-/* destroys the key and steals the value */
-static void
-g_hash_table_steal_value(GHashTable *hash_table, const gpointer key,
-	GDestroyNotify key_destroy_func)
-{
-	gpointer orig_key;
-
-	g_return_if_fail(hash_table != NULL);
-
-	if (!g_hash_table_lookup_extended(hash_table, key, &orig_key, NULL))
-		return;
-
-	g_hash_table_steal(hash_table, key);
-
-	key_destroy_func(orig_key);
-}
-
 static time_t purple_http_rfc1123_to_time(const gchar *str)
 {
 	static const gchar *months[13] = {"jan", "feb", "mar", "apr", "may", "jun",
@@ -358,7 +376,6 @@ purple_http_socket_connect_new(PurpleCon
 	hs->connect_cb = cb;
 	hs->cb_data = user_data;
 	hs->fd = -1;
-	hs->hash = purple_http_socket_hash(host, port, is_ssl);
 
 	if (is_ssl) {
 		if (!purple_ssl_is_supported()) {
@@ -480,7 +497,6 @@ purple_http_socket_close_free(PurpleHttp
 			close(hs->fd);
 	}
 
-	g_free(hs->hash);
 	g_free(hs);
 }
 
@@ -687,6 +703,9 @@ static void _purple_http_error(PurpleHtt
 	hc->response->error = g_strdup_vprintf(format, args);
 	va_end(args);
 
+	if (purple_debug_is_verbose())
+		purple_debug_warning("http", "error: %s\n", hc->response->error);
+
 	purple_http_conn_cancel(hc);
 }
 
@@ -1068,7 +1087,7 @@ static gboolean _purple_http_recv_loopbo
 			hc->length_expected = hc->length_got;
 		else if (hc->length_got == 0 && hc->socket->use_count > 1) {
 			purple_debug_info("http", "Keep-alive connection "
-				"expired, retrying...\n");
+				"expired (when reading), retrying...\n");
 			purple_http_conn_retry(hc);
 			return FALSE;
 		} else {
@@ -1273,6 +1292,15 @@ static void _purple_http_send(gpointer _
 		return;
 
 	if (written < 0) {
+		if (hc->request_header_written == 0 &&
+			hc->socket->use_count > 1)
+		{
+			purple_debug_info("http", "Keep-alive connection "
+				"expired (when writing), retrying...\n");
+			purple_http_conn_retry(hc);
+			return;
+		}
+
 		_purple_http_error(hc, _("Error writing to %s: %s"),
 			hc->url->host, g_strerror(errno));
 		return;
@@ -1313,19 +1341,27 @@ static void _purple_http_disconnect(Purp
 		g_string_free(hc->response_buffer, TRUE);
 	hc->response_buffer = NULL;
 
-	purple_http_keepalive_pool_release(hc->socket, !is_graceful);
-	hc->socket = NULL;
+	if (hc->socket_request)
+		purple_http_keepalive_pool_request_cancel(hc->socket_request);
+	else {
+		purple_http_keepalive_pool_release(hc->socket, !is_graceful);
+		hc->socket = NULL;
+	}
 }
 
 static void  _purple_http_connected(PurpleHttpSocket *hs, const gchar *error, gpointer _hc)
 {
 	PurpleHttpConnection *hc = _hc;
 
+	hc->socket_request = NULL;
+	hc->socket = hs;
+
 	if (error != NULL) {
 		_purple_http_error(hc, _("Unable to connect to %s: %s"),
 			hc->url->host, error);
 		return;
 	}
+
 	purple_http_socket_watch(hs, PURPLE_INPUT_WRITE, _purple_http_send, hc);
 }
 
@@ -1368,11 +1404,16 @@ static gboolean _purple_http_reconnect(P
 		return FALSE;
 	}
 
-	hc->socket = purple_http_keepalive_pool_request(
-		hc->request->keepalive_pool, hc->gc, url->host,
-		url->port, is_ssl, _purple_http_connected, hc);
-
-	if (hc->socket == NULL) {
+	if (hc->request->keepalive_pool != NULL) {
+		hc->socket_request = purple_http_keepalive_pool_request(
+			hc->request->keepalive_pool, hc->gc, url->host,
+			url->port, is_ssl, _purple_http_connected, hc);
+	} else {
+		hc->socket = purple_http_socket_connect_new(hc->gc, url->host,
+			url->port, is_ssl, _purple_http_connected, hc);
+	}
+
+	if (hc->socket_request == NULL && hc->socket == NULL) {
 		_purple_http_error(hc, _("Unable to connect to %s"), url->host);
 		return FALSE;
 	}
@@ -1577,6 +1618,10 @@ void purple_http_conn_cancel(PurpleHttpC
 	if (http_conn == NULL)
 		return;
 
+	if (http_conn->is_cancelling)
+		return;
+	http_conn->is_cancelling = TRUE;
+
 	if (purple_debug_is_verbose()) {
 		purple_debug_misc("http", "Cancelling connection %p...\n",
 			http_conn);
@@ -1602,7 +1647,14 @@ purple_http_conn_retry(PurpleHttpConnect
 
 void purple_http_conn_cancel_all(PurpleConnection *gc)
 {
-	GList *gc_list = g_hash_table_lookup(purple_http_hc_by_gc, gc);
+	GList *gc_list;
+
+	if (purple_debug_is_verbose()) {
+		purple_debug_misc("http", "Cancelling all running HTTP "
+			"connections\n");
+	}
+
+	gc_list = g_hash_table_lookup(purple_http_hc_by_gc, gc);
 
 	g_hash_table_insert(purple_http_cancelling_gc, gc, GINT_TO_POINTER(TRUE));
 
@@ -1927,10 +1979,26 @@ gboolean purple_http_cookie_jar_is_empty
 /*** HTTP Keep-Alive pool API *************************************************/
 
 static void
-purple_http_keepalive_pool_socketlist_free(gpointer socketlist)
+purple_http_keepalive_host_process_queue(PurpleHttpKeepaliveHost *host);
+
+static void
+purple_http_keepalive_host_free(gpointer _host)
 {
-	g_slist_free_full(socketlist,
+	PurpleHttpKeepaliveHost *host = _host;
+
+	if (host->process_queue_timeout > 0) {
+		purple_timeout_remove(host->process_queue_timeout);
+		host->process_queue_timeout = 0;
+	}
+
+	g_free(host->host);
+
+	g_slist_free_full(host->queue,
+		(GDestroyNotify)purple_http_keepalive_pool_request_cancel);
+	g_slist_free_full(host->sockets,
 		(GDestroyNotify)purple_http_socket_close_free);
+
+	g_free(host);
 }
 
 PurpleHttpKeepalivePool *
@@ -1940,7 +2008,7 @@ purple_http_keepalive_pool_new(void)
 
 	pool->ref_count = 1;
 	pool->by_hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
-		purple_http_keepalive_pool_socketlist_free);
+		purple_http_keepalive_host_free);
 
 	return pool;
 }
@@ -1950,6 +2018,9 @@ purple_http_keepalive_pool_free(PurpleHt
 {
 	g_return_if_fail(pool != NULL);
 
+	if (pool->is_destroying)
+		return;
+	pool->is_destroying = TRUE;
 	g_hash_table_destroy(pool->by_hash);
 	g_free(pool);
 }
@@ -1978,32 +2049,87 @@ purple_http_keepalive_pool_unref(PurpleH
 	return NULL;
 }
 



More information about the Commits mailing list