# HG changeset patch # User Ka-Hing Cheung # Date 1191201757 0 # Node ID 66921a5c9ae9bf5753bf8bc6801dde6f1ca11093 # Parent 10d27a4be2fd194786b30124a603ce83afd22bf5 cleanup soap connection with a timeout diff -r 10d27a4be2fd -r 66921a5c9ae9 libpurple/protocols/msn/session.c --- a/libpurple/protocols/msn/session.c Mon Oct 01 00:40:30 2007 +0000 +++ b/libpurple/protocols/msn/session.c Mon Oct 01 01:22:37 2007 +0000 @@ -102,6 +102,9 @@ if (session->soap_table) g_hash_table_destroy(session->soap_table); + if (session->soap_cleanup_handle) + purple_timeout_remove(session->soap_cleanup_handle); + g_free(session); } diff -r 10d27a4be2fd -r 66921a5c9ae9 libpurple/protocols/msn/session.h --- a/libpurple/protocols/msn/session.h Mon Oct 01 00:40:30 2007 +0000 +++ b/libpurple/protocols/msn/session.h Mon Oct 01 01:22:37 2007 +0000 @@ -128,6 +128,7 @@ } passport_info; GHashTable *soap_table; + int soap_cleanup_handle; }; /** diff -r 10d27a4be2fd -r 66921a5c9ae9 libpurple/protocols/msn/soap2.c --- a/libpurple/protocols/msn/soap2.c Mon Oct 01 00:40:30 2007 +0000 +++ b/libpurple/protocols/msn/soap2.c Mon Oct 01 01:22:37 2007 +0000 @@ -33,6 +33,8 @@ #include #include +#define SOAP_TIMEOUT 10 + static GHashTable *conn_table = NULL; typedef struct _MsnSoapRequest { @@ -46,6 +48,7 @@ MsnSession *session; char *host; + time_t last_used; PurpleSslConnection *ssl; gboolean connected; @@ -78,6 +81,40 @@ static void msn_soap_request_destroy(MsnSoapRequest *req); static void msn_soap_connection_sanitize(MsnSoapConnection *conn, gboolean disconnect); +static gboolean +msn_soap_cleanup_each(gpointer key, gpointer value, gpointer data) +{ + MsnSoapConnection *conn = value; + time_t *t = data; + + if ((*t - conn->last_used) > SOAP_TIMEOUT * 2) { + purple_debug_info("soap", "cleaning up soap conn %p\n", conn); + return TRUE; + } + + return FALSE; +} + +static gboolean +msn_soap_cleanup_for_session(gpointer data) +{ + MsnSession *sess = data; + time_t t = time(NULL); + + purple_debug_info("soap", "session cleanup timeout\n"); + + if (sess->soap_table) { + g_hash_table_foreach_remove(sess->soap_table, msn_soap_cleanup_each, + &t); + + if (g_hash_table_size(sess->soap_table) == 0) { + purple_timeout_remove(sess->soap_cleanup_handle); + sess->soap_cleanup_handle = 0; + } + } + + return TRUE; +} static MsnSoapConnection * msn_soap_get_connection(MsnSession *session, const char *host) @@ -91,11 +128,17 @@ NULL, (GDestroyNotify)msn_soap_connection_destroy); } + if (session->soap_cleanup_handle == 0) + session->soap_cleanup_handle = purple_timeout_add(SOAP_TIMEOUT * 1000, + msn_soap_cleanup_for_session, session); + if (conn == NULL) { conn = msn_soap_connection_new(session, host); g_hash_table_insert(session->soap_table, conn->host, conn); } + conn->last_used = time(NULL); + return conn; }