[libsoup] SoupSession: make pause/unpause work in any state



commit 5cb220971a58d00616711d8ba04b7eaff89445a5
Author: Dan Winship <danw gnome org>
Date:   Sun Aug 7 18:50:14 2011 -0400

    SoupSession: make pause/unpause work in any state
    
    https://bugzilla.gnome.org/show_bug.cgi?id=651146

 libsoup/soup-message-queue.h |    3 ++-
 libsoup/soup-session-async.c |   11 +++++++++++
 libsoup/soup-session-sync.c  |   19 +++++++++++++++++++
 libsoup/soup-session.c       |   26 ++++++++++++++++++++++++--
 libsoup/soup-session.h       |    3 ++-
 5 files changed, 58 insertions(+), 4 deletions(-)
---
diff --git a/libsoup/soup-message-queue.h b/libsoup/soup-message-queue.h
index 08cc6df..43cb0ae 100644
--- a/libsoup/soup-message-queue.h
+++ b/libsoup/soup-message-queue.h
@@ -45,7 +45,8 @@ struct _SoupMessageQueueItem {
 	SoupURI *proxy_uri;
 	SoupConnection *conn;
 
-	guint redirection_count;
+	guint paused            : 1;
+	guint redirection_count : 31;
 
 	SoupMessageQueueItemState state;
 
diff --git a/libsoup/soup-session-async.c b/libsoup/soup-session-async.c
index 661883b..c4684d7 100644
--- a/libsoup/soup-session-async.c
+++ b/libsoup/soup-session-async.c
@@ -39,6 +39,7 @@ static void  queue_message   (SoupSession *session, SoupMessage *req,
 static guint send_message    (SoupSession *session, SoupMessage *req);
 static void  cancel_message  (SoupSession *session, SoupMessage *msg,
 			      guint status_code);
+static void  kick            (SoupSession *session);
 
 static void  auth_required   (SoupSession *session, SoupMessage *msg,
 			      SoupAuth *auth, gboolean retrying);
@@ -80,6 +81,7 @@ soup_session_async_class_init (SoupSessionAsyncClass *soup_session_async_class)
 	session_class->send_message = send_message;
 	session_class->cancel_message = cancel_message;
 	session_class->auth_required = auth_required;
+	session_class->kick = kick;
 
 	object_class->finalize = finalize;
 }
@@ -359,6 +361,9 @@ process_queue_item (SoupMessageQueueItem *item,
 	SoupProxyURIResolver *proxy_resolver;
 
 	do {
+		if (item->paused)
+			return;
+
 		switch (item->state) {
 		case SOUP_MESSAGE_STARTING:
 			proxy_resolver = (SoupProxyURIResolver *)soup_session_get_feature_for_message (session, SOUP_TYPE_PROXY_URI_RESOLVER, item->msg);
@@ -575,3 +580,9 @@ auth_required (SoupSession *session, SoupMessage *msg,
 			auth_required (session, msg, auth, retrying);
 	}
 }
+
+static void
+kick (SoupSession *session)
+{
+	do_idle_run_queue (session);
+}
diff --git a/libsoup/soup-session-sync.c b/libsoup/soup-session-sync.c
index 373b1bd..aecbf6f 100644
--- a/libsoup/soup-session-sync.c
+++ b/libsoup/soup-session-sync.c
@@ -61,6 +61,7 @@ static void  cancel_message (SoupSession *session, SoupMessage *msg,
 static void  auth_required  (SoupSession *session, SoupMessage *msg,
 			     SoupAuth *auth, gboolean retrying);
 static void  flush_queue    (SoupSession *session);
+static void  kick           (SoupSession *session);
 
 G_DEFINE_TYPE (SoupSessionSync, soup_session_sync, SOUP_TYPE_SESSION)
 
@@ -98,6 +99,7 @@ soup_session_sync_class_init (SoupSessionSyncClass *session_sync_class)
 	session_class->cancel_message = cancel_message;
 	session_class->auth_required = auth_required;
 	session_class->flush_queue = flush_queue;
+	session_class->kick = kick;
 
 	object_class->finalize = finalize;
 }
@@ -249,6 +251,13 @@ process_queue_item (SoupMessageQueueItem *item)
 
 	item->state = SOUP_MESSAGE_STARTING;
 	do {
+		if (item->paused) {
+			g_mutex_lock (priv->lock);
+			while (item->paused)
+				g_cond_wait (priv->cond, priv->lock);
+			g_mutex_unlock (priv->lock);
+		}
+
 		switch (item->state) {
 		case SOUP_MESSAGE_STARTING:
 			proxy_resolver = (SoupProxyURIResolver *)soup_session_get_feature_for_message (session, SOUP_TYPE_PROXY_URI_RESOLVER, msg);
@@ -454,3 +463,13 @@ flush_queue (SoupSession *session)
 
 	g_hash_table_destroy (current);
 }
+
+static void
+kick (SoupSession *session)
+{
+	SoupSessionSyncPrivate *priv = SOUP_SESSION_SYNC_GET_PRIVATE (session);
+
+	g_mutex_lock (priv->lock);
+	g_cond_broadcast (priv->cond);
+	g_mutex_unlock (priv->lock);
+}
diff --git a/libsoup/soup-session.c b/libsoup/soup-session.c
index 3fc37fd..aa57d12 100644
--- a/libsoup/soup-session.c
+++ b/libsoup/soup-session.c
@@ -1698,10 +1698,20 @@ void
 soup_session_pause_message (SoupSession *session,
 			    SoupMessage *msg)
 {
+	SoupSessionPrivate *priv;
+	SoupMessageQueueItem *item;
+
 	g_return_if_fail (SOUP_IS_SESSION (session));
 	g_return_if_fail (SOUP_IS_MESSAGE (msg));
 
-	soup_message_io_pause (msg);
+	priv = SOUP_SESSION_GET_PRIVATE (session);
+	item = soup_message_queue_lookup (priv->queue, msg);
+	g_return_if_fail (item != NULL);
+
+	item->paused = TRUE;
+	if (item->state == SOUP_MESSAGE_RUNNING)
+		soup_message_io_pause (msg);
+	soup_message_queue_item_unref (item);
 }
 
 /**
@@ -1720,10 +1730,22 @@ void
 soup_session_unpause_message (SoupSession *session,
 			      SoupMessage *msg)
 {
+	SoupSessionPrivate *priv;
+	SoupMessageQueueItem *item;
+
 	g_return_if_fail (SOUP_IS_SESSION (session));
 	g_return_if_fail (SOUP_IS_MESSAGE (msg));
 
-	soup_message_io_unpause (msg);
+	priv = SOUP_SESSION_GET_PRIVATE (session);
+	item = soup_message_queue_lookup (priv->queue, msg);
+	g_return_if_fail (item != NULL);
+
+	item->paused = FALSE;
+	if (item->state == SOUP_MESSAGE_RUNNING)
+		soup_message_io_unpause (msg);
+	soup_message_queue_item_unref (item);
+
+	SOUP_SESSION_GET_CLASS (session)->kick (session);
 }
 
 
diff --git a/libsoup/soup-session.h b/libsoup/soup-session.h
index 4b6661f..7ad1d16 100644
--- a/libsoup/soup-session.h
+++ b/libsoup/soup-session.h
@@ -51,8 +51,9 @@ typedef struct {
 
 	void  (*flush_queue)     (SoupSession *session);
 
+	void  (*kick)            (SoupSession *session);
+
 	/* Padding for future expansion */
-	void (*_libsoup_reserved3) (void);
 	void (*_libsoup_reserved4) (void);
 } SoupSessionClass;
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]