diff options
author | Dan Winship <danw@gnome.org> | 2010-06-03 21:23:22 +0200 |
---|---|---|
committer | Dan Winship <danw@gnome.org> | 2010-06-09 11:25:31 -0400 |
commit | b288692d67772c08296ee3aef58965219fcbbfca (patch) | |
tree | 57c162a7c82d457c66f39b6657884ae27c81b639 /libsoup | |
parent | 6d7e7e21e2da6109dd9ce287c2b51e312d66c2c7 (diff) | |
download | libsoup-b288692d67772c08296ee3aef58965219fcbbfca.tar.gz |
SoupSession: continue reorg, remove remaining signal-based flow control
Make the sessions more state-machiney and fix up
soup_session_cancel_message() by having it set the message to the
(new) FINISHING state and letting the session implementation pick it
up from there. Remove the remaining "finished" and "restarted" signal
handlers; move the base session's "finished" handler to
"soup_session_unqueue_item" and call that from the right places in the
subclasses.
Diffstat (limited to 'libsoup')
-rw-r--r-- | libsoup/soup-message-queue.h | 1 | ||||
-rw-r--r-- | libsoup/soup-session-async.c | 203 | ||||
-rw-r--r-- | libsoup/soup-session-private.h | 2 | ||||
-rw-r--r-- | libsoup/soup-session-sync.c | 206 | ||||
-rw-r--r-- | libsoup/soup-session.c | 50 |
5 files changed, 228 insertions, 234 deletions
diff --git a/libsoup/soup-message-queue.h b/libsoup/soup-message-queue.h index 7211d711..4f655b3c 100644 --- a/libsoup/soup-message-queue.h +++ b/libsoup/soup-message-queue.h @@ -31,6 +31,7 @@ typedef enum { SOUP_MESSAGE_READY, SOUP_MESSAGE_RUNNING, SOUP_MESSAGE_RESTARTING, + SOUP_MESSAGE_FINISHING, SOUP_MESSAGE_FINISHED } SoupMessageQueueItemState; diff --git a/libsoup/soup-session-async.c b/libsoup/soup-session-async.c index ee7fdf66..ee9ddd72 100644 --- a/libsoup/soup-session-async.c +++ b/libsoup/soup-session-async.c @@ -37,6 +37,8 @@ static void do_idle_run_queue (SoupSession *session); static void queue_message (SoupSession *session, SoupMessage *req, SoupSessionCallback callback, gpointer user_data); static guint send_message (SoupSession *session, SoupMessage *req); +static void cancel_message (SoupSession *session, SoupMessage *msg, + guint status_code); static void auth_required (SoupSession *session, SoupMessage *msg, SoupAuth *auth, gboolean retrying); @@ -76,6 +78,7 @@ soup_session_async_class_init (SoupSessionAsyncClass *soup_session_async_class) /* virtual method override */ session_class->queue_message = queue_message; session_class->send_message = send_message; + session_class->cancel_message = cancel_message; session_class->auth_required = auth_required; object_class->finalize = finalize; @@ -127,9 +130,9 @@ item_failed (SoupMessageQueueItem *item, guint status) } if (!SOUP_STATUS_IS_SUCCESSFUL (status)) { - item->state = SOUP_MESSAGE_FINISHED; - if (status != SOUP_STATUS_CANCELLED) - soup_session_cancel_message (item->session, item->msg, status); + item->state = SOUP_MESSAGE_FINISHING; + if (!item->msg->status_code) + soup_message_set_status (item->msg, status); soup_message_queue_item_unref (item); return TRUE; } @@ -215,37 +218,28 @@ message_completed (SoupMessage *msg, gpointer user_data) { SoupMessageQueueItem *item = user_data; - if (item->state == SOUP_MESSAGE_RESTARTING) - soup_message_restarted (msg); - else { - item->state = SOUP_MESSAGE_FINISHED; - soup_message_finished (msg); - } + if (item->state != SOUP_MESSAGE_RESTARTING) + item->state = SOUP_MESSAGE_FINISHING; + do_idle_run_queue (item->session); } static void tunnel_message_completed (SoupMessage *msg, gpointer user_data) { SoupMessageQueueItem *item = user_data; + SoupSession *session = item->session; if (item->state == SOUP_MESSAGE_RESTARTING) { soup_message_restarted (msg); if (item->conn) { - soup_session_send_queue_item (item->session, item, tunnel_message_completed); + soup_session_send_queue_item (session, item, tunnel_message_completed); return; } soup_message_set_status (msg, SOUP_STATUS_TRY_AGAIN); - item->state = SOUP_MESSAGE_FINISHED; } - message_completed (msg, item); -} -static void -tunnel_connected (SoupMessage *msg, gpointer user_data) -{ - SoupMessageQueueItem *item = user_data; - SoupSession *session = item->session; + item->state = SOUP_MESSAGE_FINISHED; if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) { if (item->conn) @@ -273,13 +267,13 @@ tunnel_connected (SoupMessage *msg, gpointer user_data) item->related->state = SOUP_MESSAGE_READY; done: - if (item->related->msg->status_code) { - item->related->state = SOUP_MESSAGE_FINISHED; - message_completed (item->related->msg, item->related); - } + soup_message_finished (msg); + if (item->related->msg->status_code) + item->related->state = SOUP_MESSAGE_FINISHING; do_idle_run_queue (item->session); soup_message_queue_item_unref (item->related); + soup_session_unqueue_item (session, item); soup_message_queue_item_unref (item); g_object_unref (session); } @@ -300,15 +294,11 @@ got_connection (SoupConnection *conn, guint status, gpointer user_data) } if (status != SOUP_STATUS_OK) { - soup_connection_disconnect (conn); soup_message_set_status (item->msg, status); - message_completed (item->msg, item); + item->state = SOUP_MESSAGE_FINISHING; - /* There may have been messages waiting for the - * connection count to go down, so queue a run_queue. - */ + soup_connection_disconnect (conn); do_idle_run_queue (session); - soup_message_queue_item_unref (item); g_object_unref (session); return; @@ -322,8 +312,6 @@ got_connection (SoupConnection *conn, guint status, gpointer user_data) tunnel_item = soup_session_make_connect_message (session, conn); tunnel_item->related = item; - g_signal_connect (tunnel_item->msg, "finished", - G_CALLBACK (tunnel_connected), tunnel_item); soup_session_send_queue_item (session, tunnel_item, tunnel_message_completed); return; } @@ -337,15 +325,83 @@ got_connection (SoupConnection *conn, guint status, gpointer user_data) } static void +process_queue_item (SoupMessageQueueItem *item, + gboolean *should_prune) +{ + SoupSession *session = item->session; + SoupProxyURIResolver *proxy_resolver; + + do { + switch (item->state) { + case SOUP_MESSAGE_STARTING: + proxy_resolver = (SoupProxyURIResolver *)soup_session_get_feature_for_message (session, SOUP_TYPE_PROXY_URI_RESOLVER, item->msg); + if (!proxy_resolver) { + item->state = SOUP_MESSAGE_AWAITING_CONNECTION; + break; + } + resolve_proxy_addr (item, proxy_resolver); + return; + + case SOUP_MESSAGE_AWAITING_CONNECTION: + if (!soup_session_get_connection (session, item, should_prune)) + return; + + if (soup_connection_get_state (item->conn) != SOUP_CONNECTION_NEW) { + item->state = SOUP_MESSAGE_READY; + break; + } + + item->state = SOUP_MESSAGE_CONNECTING; + soup_message_queue_item_ref (item); + g_object_ref (session); + soup_connection_connect_async (item->conn, item->cancellable, + got_connection, item); + return; + + case SOUP_MESSAGE_READY: + item->state = SOUP_MESSAGE_RUNNING; + soup_session_send_queue_item (session, item, message_completed); + break; + + case SOUP_MESSAGE_RESTARTING: + item->state = SOUP_MESSAGE_STARTING; + soup_message_restarted (item->msg); + break; + + case SOUP_MESSAGE_FINISHING: + item->state = SOUP_MESSAGE_FINISHED; + soup_message_finished (item->msg); + if (item->state != SOUP_MESSAGE_FINISHED) + break; + + g_object_ref (session); + soup_session_unqueue_item (session, item); + if (item->callback) + item->callback (session, item->msg, item->callback_data); + g_object_unref (item->msg); + do_idle_run_queue (session); + g_object_unref (session); + return; + + default: + /* Nothing to do with this message in any + * other state. + */ + return; + } + } while (item->state != SOUP_MESSAGE_FINISHED); +} + +static void run_queue (SoupSessionAsync *sa) { SoupSession *session = SOUP_SESSION (sa); SoupMessageQueue *queue = soup_session_get_queue (session); SoupMessageQueueItem *item; - SoupProxyURIResolver *proxy_resolver; SoupMessage *msg; gboolean try_pruning = TRUE, should_prune = FALSE; + g_object_ref (session); soup_session_cleanup_connections (session, FALSE); try_again: @@ -355,39 +411,8 @@ run_queue (SoupSessionAsync *sa) msg = item->msg; /* CONNECT messages are handled specially */ - if (msg->method == SOUP_METHOD_CONNECT) - continue; - - if (item->state == SOUP_MESSAGE_STARTING) { - proxy_resolver = (SoupProxyURIResolver *)soup_session_get_feature_for_message (session, SOUP_TYPE_PROXY_URI_RESOLVER, msg); - if (proxy_resolver) { - resolve_proxy_addr (item, proxy_resolver); - continue; - } else - item->state = SOUP_MESSAGE_AWAITING_CONNECTION; - } - - if (item->state == SOUP_MESSAGE_AWAITING_CONNECTION) { - if (!soup_session_get_connection (session, item, - &should_prune)) - continue; - - if (soup_connection_get_state (item->conn) == SOUP_CONNECTION_NEW) { - item->state = SOUP_MESSAGE_CONNECTING; - soup_message_queue_item_ref (item); - g_object_ref (item->session); - soup_connection_connect_async (item->conn, item->cancellable, - got_connection, - item); - continue; - } else - item->state = SOUP_MESSAGE_READY; - } - - if (item->state == SOUP_MESSAGE_READY) { - item->state = SOUP_MESSAGE_RUNNING; - soup_session_send_queue_item (session, item, message_completed); - } + if (msg->method != SOUP_METHOD_CONNECT) + process_queue_item (item, &should_prune); } if (item) soup_message_queue_item_unref (item); @@ -402,35 +427,7 @@ run_queue (SoupSessionAsync *sa) goto try_again; } } -} -static void -request_restarted (SoupMessage *req, gpointer user_data) -{ - SoupMessageQueueItem *item = user_data; - - run_queue ((SoupSessionAsync *)item->session); -} - -static void -final_finished (SoupMessage *req, gpointer user_data) -{ - SoupMessageQueueItem *item = user_data; - SoupSession *session = item->session; - - g_object_ref (session); - - if (item->state == SOUP_MESSAGE_FINISHED) { - g_signal_handlers_disconnect_by_func (req, final_finished, item); - g_signal_handlers_disconnect_by_func (req, request_restarted, item); - if (item->callback) - item->callback (session, req, item->callback_data); - - g_object_unref (req); - soup_message_queue_item_unref (item); - } - - do_idle_run_queue (session); g_object_unref (session); } @@ -460,18 +457,8 @@ static void queue_message (SoupSession *session, SoupMessage *req, SoupSessionCallback callback, gpointer user_data) { - SoupMessageQueueItem *item; - SOUP_SESSION_CLASS (soup_session_async_parent_class)->queue_message (session, req, callback, user_data); - item = soup_message_queue_lookup (soup_session_get_queue (session), req); - g_return_if_fail (item != NULL); - - g_signal_connect (req, "restarted", - G_CALLBACK (request_restarted), item); - g_signal_connect_after (req, "finished", - G_CALLBACK (final_finished), item); - do_idle_run_queue (session); } @@ -482,7 +469,7 @@ send_message (SoupSession *session, SoupMessage *req) GMainContext *async_context = soup_session_get_async_context (session); - /* Balance out the unref that final_finished will do */ + /* Balance out the unref that queuing will eventually do */ g_object_ref (req); queue_message (session, req, NULL, NULL); @@ -490,8 +477,7 @@ send_message (SoupSession *session, SoupMessage *req) item = soup_message_queue_lookup (soup_session_get_queue (session), req); g_return_val_if_fail (item != NULL, SOUP_STATUS_MALFORMED); - while (item->state != SOUP_MESSAGE_FINISHED && - !SOUP_STATUS_IS_TRANSPORT_ERROR (req->status_code)) + while (item->state != SOUP_MESSAGE_FINISHED) g_main_context_iteration (async_context, TRUE); soup_message_queue_item_unref (item); @@ -500,6 +486,13 @@ send_message (SoupSession *session, SoupMessage *req) } static void +cancel_message (SoupSession *session, SoupMessage *msg, guint status_code) +{ + SOUP_SESSION_CLASS (soup_session_async_parent_class)->cancel_message (session, msg, status_code); + do_idle_run_queue (session); +} + +static void got_passwords (SoupPasswordManager *password_manager, SoupMessage *msg, SoupAuth *auth, gboolean retrying, gpointer session) { diff --git a/libsoup/soup-session-private.h b/libsoup/soup-session-private.h index 0f9c3ac4..e4938860 100644 --- a/libsoup/soup-session-private.h +++ b/libsoup/soup-session-private.h @@ -25,6 +25,8 @@ gboolean soup_session_cleanup_connections (SoupSession *s void soup_session_send_queue_item (SoupSession *session, SoupMessageQueueItem *item, SoupMessageCompletionFn completion_cb); +void soup_session_unqueue_item (SoupSession *session, + SoupMessageQueueItem *item); G_END_DECLS diff --git a/libsoup/soup-session-sync.c b/libsoup/soup-session-sync.c index 0de0b81a..077173aa 100644 --- a/libsoup/soup-session-sync.c +++ b/libsoup/soup-session-sync.c @@ -147,23 +147,19 @@ tunnel_connect (SoupSession *session, SoupConnection *conn) item = soup_session_make_connect_message (session, conn); do { soup_session_send_queue_item (session, item, NULL); - if (item->state == SOUP_MESSAGE_RESTARTING) { + status = item->msg->status_code; + if (item->state == SOUP_MESSAGE_RESTARTING && + soup_connection_get_state (conn) != SOUP_CONNECTION_DISCONNECTED) { item->state = SOUP_MESSAGE_STARTING; soup_message_restarted (item->msg); } else { + if (item->state == SOUP_MESSAGE_RESTARTING) + status = SOUP_STATUS_TRY_AGAIN; item->state = SOUP_MESSAGE_FINISHED; soup_message_finished (item->msg); } - } while (item->state == SOUP_MESSAGE_STARTING && - soup_connection_get_state (conn) != SOUP_CONNECTION_DISCONNECTED); - - /* If the message was requeued but its connection was closed, - * return TRY_AGAIN to our caller. - */ - if (item->state == SOUP_MESSAGE_STARTING) - status = SOUP_STATUS_TRY_AGAIN; - else - status = item->msg->status_code; + } while (item->state == SOUP_MESSAGE_STARTING); + soup_session_unqueue_item (session, item); soup_message_queue_item_unref (item); if (SOUP_STATUS_IS_SUCCESSFUL (status)) { @@ -178,129 +174,137 @@ tunnel_connect (SoupSession *session, SoupConnection *conn) return status; } -static gboolean -wait_for_connection (SoupMessageQueueItem *item) +static void +get_connection (SoupMessageQueueItem *item) { SoupSession *session = item->session; SoupMessage *msg = item->msg; - SoupSessionSyncPrivate *priv = SOUP_SESSION_SYNC_GET_PRIVATE (session); gboolean try_pruning = FALSE; - SoupProxyURIResolver *proxy_resolver; guint status; - proxy_resolver = (SoupProxyURIResolver *)soup_session_get_feature_for_message (session, SOUP_TYPE_PROXY_URI_RESOLVER, msg); - if (proxy_resolver && item->state == SOUP_MESSAGE_STARTING) { - item->state = SOUP_MESSAGE_RESOLVING_PROXY_URI; - status = soup_proxy_uri_resolver_get_proxy_uri_sync ( - proxy_resolver, soup_message_get_uri (msg), - item->cancellable, &item->proxy_uri); - if (!SOUP_STATUS_IS_SUCCESSFUL (status)) { - if (status != SOUP_STATUS_CANCELLED) - soup_session_cancel_message (session, msg, status); - return FALSE; - } - item->state = SOUP_MESSAGE_RESOLVED_PROXY_URI; - - if (item->proxy_uri) { - item->state = SOUP_MESSAGE_RESOLVING_PROXY_ADDRESS; - item->proxy_addr = soup_address_new ( - item->proxy_uri->host, item->proxy_uri->port); - status = soup_address_resolve_sync (item->proxy_addr, - item->cancellable); - if (!SOUP_STATUS_IS_SUCCESSFUL (status)) { - if (status != SOUP_STATUS_CANCELLED) - soup_session_cancel_message (session, msg, status); - return FALSE; - } - } - } - - g_mutex_lock (priv->lock); - +try_again: soup_session_cleanup_connections (session, FALSE); - try_again: - item->state = SOUP_MESSAGE_AWAITING_CONNECTION; - if (soup_session_get_connection (session, item, &try_pruning)) { - if (soup_connection_get_state (item->conn) == SOUP_CONNECTION_NEW) { - item->state = SOUP_MESSAGE_CONNECTING; - status = soup_connection_connect_sync (item->conn, item->cancellable); - - if (!SOUP_STATUS_IS_SUCCESSFUL (status)) { - soup_connection_disconnect (item->conn); - g_object_unref (item->conn); - item->conn = NULL; - } else if (item->state == SOUP_MESSAGE_FINISHED) { - /* Message was cancelled while we were - * connecting. - */ - soup_connection_disconnect (item->conn); - g_object_unref (item->conn); - item->conn = NULL; - } else if (soup_connection_get_tunnel_addr (item->conn)) { - item->state = SOUP_MESSAGE_TUNNELING; - status = tunnel_connect (session, item->conn); - if (SOUP_STATUS_IS_SUCCESSFUL (status)) - item->state = SOUP_MESSAGE_READY; - else if (status == SOUP_STATUS_TRY_AGAIN) { - soup_connection_disconnect (item->conn); - g_object_unref (item->conn); - item->conn = NULL; - goto try_again; - } else { - soup_message_set_status (item->msg, status); - item->state = SOUP_MESSAGE_FINISHED; - } - } else - item->state = SOUP_MESSAGE_READY; - } else - item->state = SOUP_MESSAGE_READY; - - g_mutex_unlock (priv->lock); - return item->conn != NULL; + if (!soup_session_get_connection (session, item, &try_pruning)) { + if (!try_pruning) + return; + soup_session_cleanup_connections (session, TRUE); + if (!soup_session_get_connection (session, item, &try_pruning)) + return; + try_pruning = FALSE; } - if (try_pruning) { - try_pruning = FALSE; - if (soup_session_cleanup_connections (session, TRUE)) - goto try_again; + if (soup_connection_get_state (item->conn) != SOUP_CONNECTION_NEW) { + item->state = SOUP_MESSAGE_READY; + return; } - /* Wait... */ - g_cond_wait (priv->cond, priv->lock); + status = soup_connection_connect_sync (item->conn, item->cancellable); + + if (!SOUP_STATUS_IS_SUCCESSFUL (status)) { + if (!msg->status_code) + soup_message_set_status (msg, status); + item->state = SOUP_MESSAGE_FINISHING; + soup_connection_disconnect (item->conn); + g_object_unref (item->conn); + item->conn = NULL; + return; + } - /* See if something bad happened */ - if (item->state == SOUP_MESSAGE_FINISHED) { - g_mutex_unlock (priv->lock); - return FALSE; + if (soup_connection_get_tunnel_addr (item->conn)) { + status = tunnel_connect (session, item->conn); + if (!SOUP_STATUS_IS_SUCCESSFUL (status)) { + soup_connection_disconnect (item->conn); + g_object_unref (item->conn); + item->conn = NULL; + if (status == SOUP_STATUS_TRY_AGAIN) + goto try_again; + soup_message_set_status (item->msg, status); + item->state = SOUP_MESSAGE_FINISHING; + return; + } } - goto try_again; + item->state = SOUP_MESSAGE_READY; } static void process_queue_item (SoupMessageQueueItem *item) { - SoupSessionSyncPrivate *priv = SOUP_SESSION_SYNC_GET_PRIVATE (item->session); + SoupSession *session = item->session; + SoupSessionSyncPrivate *priv = SOUP_SESSION_SYNC_GET_PRIVATE (session); + SoupMessage *msg = item->msg; + SoupProxyURIResolver *proxy_resolver; + guint status; item->state = SOUP_MESSAGE_STARTING; do { - if (!wait_for_connection (item)) + switch (item->state) { + case SOUP_MESSAGE_STARTING: + proxy_resolver = (SoupProxyURIResolver *)soup_session_get_feature_for_message (session, SOUP_TYPE_PROXY_URI_RESOLVER, msg); + if (!proxy_resolver) { + item->state = SOUP_MESSAGE_AWAITING_CONNECTION; + break; + } + + status = soup_proxy_uri_resolver_get_proxy_uri_sync ( + proxy_resolver, soup_message_get_uri (msg), + item->cancellable, &item->proxy_uri); + if (!SOUP_STATUS_IS_SUCCESSFUL (status)) { + soup_message_set_status (msg, status); + item->state = SOUP_MESSAGE_FINISHING; + break; + } + if (!item->proxy_uri) { + item->state = SOUP_MESSAGE_AWAITING_CONNECTION; + break; + } + + item->proxy_addr = soup_address_new ( + item->proxy_uri->host, item->proxy_uri->port); + status = soup_address_resolve_sync (item->proxy_addr, + item->cancellable); + if (SOUP_STATUS_IS_SUCCESSFUL (status)) + item->state = SOUP_MESSAGE_AWAITING_CONNECTION; + else { + soup_message_set_status (msg, status); + item->state = SOUP_MESSAGE_FINISHING; + } break; - if (item->state == SOUP_MESSAGE_READY) { + case SOUP_MESSAGE_AWAITING_CONNECTION: + g_mutex_lock (priv->lock); + do { + get_connection (item); + if (item->state == SOUP_MESSAGE_AWAITING_CONNECTION) + g_cond_wait (priv->cond, priv->lock); + } while (item->state == SOUP_MESSAGE_AWAITING_CONNECTION); + g_mutex_unlock (priv->lock); + break; + + case SOUP_MESSAGE_READY: item->state = SOUP_MESSAGE_RUNNING; soup_session_send_queue_item (item->session, item, NULL); - } + if (item->state != SOUP_MESSAGE_RESTARTING) + item->state = SOUP_MESSAGE_FINISHING; + break; - if (item->state == SOUP_MESSAGE_RESTARTING) { + case SOUP_MESSAGE_RESTARTING: item->state = SOUP_MESSAGE_STARTING; soup_message_restarted (item->msg); - } else { + break; + + case SOUP_MESSAGE_FINISHING: item->state = SOUP_MESSAGE_FINISHED; soup_message_finished (item->msg); + soup_session_unqueue_item (session, item); + break; + + default: + g_warn_if_reached (); + item->state = SOUP_MESSAGE_FINISHING; + break; } - g_cond_broadcast (priv->cond); } while (item->state != SOUP_MESSAGE_FINISHED); } diff --git a/libsoup/soup-session.c b/libsoup/soup-session.c index bd42795b..ff25e33a 100644 --- a/libsoup/soup-session.c +++ b/libsoup/soup-session.c @@ -1390,11 +1390,10 @@ soup_session_get_queue (SoupSession *session) return priv->queue; } -static void -message_finished (SoupMessage *msg, gpointer user_data) +void +soup_session_unqueue_item (SoupSession *session, + SoupMessageQueueItem *item) { - SoupMessageQueueItem *item = user_data; - SoupSession *session = item->session; SoupSessionPrivate *priv = SOUP_SESSION_GET_PRIVATE (session); SoupSessionHost *host; @@ -1403,25 +1402,26 @@ message_finished (SoupMessage *msg, gpointer user_data) item->conn = NULL; } - if (item->state == SOUP_MESSAGE_FINISHED) { - soup_message_queue_remove (priv->queue, item); + if (item->state != SOUP_MESSAGE_FINISHED) { + g_warning ("finished an item with state %d", item->state); + return; + } - g_mutex_lock (priv->host_lock); - host = get_host_for_message (session, item->msg); - host->num_messages--; - g_mutex_unlock (priv->host_lock); + soup_message_queue_remove (priv->queue, item); - g_signal_handlers_disconnect_by_func (msg, message_finished, item); - /* g_signal_handlers_disconnect_by_func doesn't work if you - * have a metamarshal, meaning it doesn't work with - * soup_message_add_header_handler() - */ - g_signal_handlers_disconnect_matched (msg, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, session); - g_signal_emit (session, signals[REQUEST_UNQUEUED], 0, msg); - soup_message_queue_item_unref (item); - } else - g_warning ("finished an item with state %d", item->state); + g_mutex_lock (priv->host_lock); + host = get_host_for_message (session, item->msg); + host->num_messages--; + g_mutex_unlock (priv->host_lock); + + /* g_signal_handlers_disconnect_by_func doesn't work if you + * have a metamarshal, meaning it doesn't work with + * soup_message_add_header_handler() + */ + g_signal_handlers_disconnect_matched (item->msg, G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, session); + g_signal_emit (session, signals[REQUEST_UNQUEUED], 0, item->msg); + soup_message_queue_item_unref (item); } static void @@ -1439,9 +1439,6 @@ queue_message (SoupSession *session, SoupMessage *msg, host->num_messages++; g_mutex_unlock (priv->host_lock); - g_signal_connect_after (msg, "finished", - G_CALLBACK (message_finished), item); - if (!(soup_message_get_flags (msg) & SOUP_MESSAGE_NO_REDIRECT)) { soup_message_add_header_handler ( msg, "got_body", "Location", @@ -1597,11 +1594,8 @@ cancel_message (SoupSession *session, SoupMessage *msg, guint status_code) soup_message_io_stop (msg); soup_message_set_status (msg, status_code); + item->state = SOUP_MESSAGE_FINISHING; - if (item->state != SOUP_MESSAGE_FINISHED) { - item->state = SOUP_MESSAGE_FINISHED; - soup_message_finished (msg); - } soup_message_queue_item_unref (item); } |