/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