[libsoup/carlosgc/priority-changes: 1/2] session: add support for re-prioritizing queue items
- From: Carlos Garcia Campos <carlosgc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libsoup/carlosgc/priority-changes: 1/2] session: add support for re-prioritizing queue items
- Date: Tue, 1 Jun 2021 10:18:38 +0000 (UTC)
commit be0586f43a3ade67b15baa8e9cf03a2033ad37b5
Author: Carlos Garcia Campos <cgarcia igalia com>
Date: Tue Jun 1 11:53:08 2021 +0200
session: add support for re-prioritizing queue items
Monitor SoupMessage:priority changes to sort the queue accortding to the
new message priorities.
libsoup/soup-message-queue-item.c | 1 -
libsoup/soup-message-queue-item.h | 1 -
libsoup/soup-session.c | 32 +++++++++++++++++++++++++++-
tests/session-test.c | 45 +++++++++++++++++++++++++++++++++++++++
4 files changed, 76 insertions(+), 3 deletions(-)
---
diff --git a/libsoup/soup-message-queue-item.c b/libsoup/soup-message-queue-item.c
index 71c77054..42bd865d 100644
--- a/libsoup/soup-message-queue-item.c
+++ b/libsoup/soup-message-queue-item.c
@@ -26,7 +26,6 @@ soup_message_queue_item_new (SoupSession *session,
item->msg = g_object_ref (msg);
item->async = async;
item->cancellable = cancellable ? g_object_ref (cancellable) : g_cancellable_new ();
- item->priority = soup_message_get_priority (msg);
g_signal_connect_swapped (msg, "restarted",
G_CALLBACK (g_cancellable_reset),
diff --git a/libsoup/soup-message-queue-item.h b/libsoup/soup-message-queue-item.h
index f7d72ccb..cb483668 100644
--- a/libsoup/soup-message-queue-item.h
+++ b/libsoup/soup-message-queue-item.h
@@ -38,7 +38,6 @@ struct _SoupMessageQueueItem {
guint io_started : 1;
guint async : 1;
guint connect_only : 1;
- guint priority : 3;
guint resend_count : 5;
int io_priority;
diff --git a/libsoup/soup-session.c b/libsoup/soup-session.c
index d74e26dc..b3fbea5f 100644
--- a/libsoup/soup-session.c
+++ b/libsoup/soup-session.c
@@ -107,6 +107,8 @@ typedef struct {
GQueue *queue;
GSource *queue_source;
+ guint16 in_async_run_queue;
+ gboolean needs_queue_sort;
char *user_agent;
char *accept_language;
@@ -1323,8 +1325,27 @@ static int
compare_queue_item (SoupMessageQueueItem *a,
SoupMessageQueueItem *b)
{
+ SoupMessagePriority a_priority = soup_message_get_priority (a->msg);
+ SoupMessagePriority b_priority = soup_message_get_priority (b->msg);
+
/* For the same priority we want to append items in the queue */
- return b->priority > a->priority ? 1 : -1;
+ return b_priority > a_priority ? 1 : -1;
+}
+
+static void
+message_priority_changed (SoupMessage *msg,
+ GParamSpec *pspec,
+ SoupMessageQueueItem *item)
+{
+ SoupSessionPrivate *priv = soup_session_get_instance_private (item->session);
+
+ if (priv->in_async_run_queue) {
+ priv->needs_queue_sort = TRUE;
+ return;
+ }
+
+ g_queue_sort (priv->queue, (GCompareDataFunc)compare_queue_item, NULL);
+ priv->needs_queue_sort = FALSE;
}
static SoupMessageQueueItem *
@@ -1359,6 +1380,8 @@ soup_session_append_queue_item (SoupSession *session,
G_CALLBACK (misdirected_handler), item);
g_signal_connect (msg, "restarted",
G_CALLBACK (message_restarted), item);
+ g_signal_connect (msg, "notify::priority",
+ G_CALLBACK (message_priority_changed), item);
for (f = priv->features; f; f = g_slist_next (f)) {
SoupSessionFeature *feature = SOUP_SESSION_FEATURE (f->data);
@@ -2054,6 +2077,7 @@ async_run_queue (SoupSession *session)
gboolean try_cleanup = TRUE, should_cleanup = FALSE;
g_object_ref (session);
+ priv->in_async_run_queue++;
soup_session_cleanup_connections (session, FALSE);
try_again:
@@ -2070,6 +2094,12 @@ async_run_queue (SoupSession *session)
}
}
+ priv->in_async_run_queue--;
+ if (!priv->in_async_run_queue && priv->needs_queue_sort) {
+ g_queue_sort (priv->queue, (GCompareDataFunc)compare_queue_item, NULL);
+ priv->needs_queue_sort = FALSE;
+ }
+
g_object_unref (session);
}
diff --git a/tests/session-test.c b/tests/session-test.c
index 4a1596b3..1c51600c 100644
--- a/tests/session-test.c
+++ b/tests/session-test.c
@@ -230,6 +230,50 @@ do_priority_tests (void)
soup_test_session_abort_unref (session);
}
+static void
+do_priority_change_test (void)
+{
+ SoupSession *session;
+ SoupMessage *msgs[3];
+ int i, finished_count = 0;
+ SoupMessagePriority priorities[] =
+ { SOUP_MESSAGE_PRIORITY_LOW,
+ SOUP_MESSAGE_PRIORITY_HIGH,
+ SOUP_MESSAGE_PRIORITY_NORMAL };
+
+ session = soup_test_session_new ("max-conns", 1, NULL);
+
+ expected_priorities[0] = SOUP_MESSAGE_PRIORITY_HIGH;
+ expected_priorities[1] = SOUP_MESSAGE_PRIORITY_LOW;
+ expected_priorities[2] = SOUP_MESSAGE_PRIORITY_VERY_LOW;
+
+ for (i = 0; i < 3; i++) {
+ GUri *msg_uri;
+ char buf[5];
+
+ g_snprintf (buf, sizeof (buf), "%d", i);
+ msg_uri = g_uri_parse_relative (base_uri, buf, SOUP_HTTP_URI_FLAGS, NULL);
+ msgs[i] = soup_message_new_from_uri ("GET", msg_uri);
+ g_uri_unref (msg_uri);
+
+ soup_message_set_priority (msgs[i], priorities[i]);
+ g_signal_connect (msgs[i], "finished",
+ G_CALLBACK (priority_test_finished_cb), &finished_count);
+ soup_session_send_async (session, msgs[i], G_PRIORITY_DEFAULT, NULL, NULL, NULL);
+ }
+
+ soup_message_set_priority (msgs[2], SOUP_MESSAGE_PRIORITY_VERY_LOW);
+
+ debug_printf (2, " waiting for finished\n");
+ while (finished_count != 3)
+ g_main_context_iteration (NULL, TRUE);
+
+ for (i = 0; i < 3; i++)
+ g_object_unref (msgs[i]);
+
+ soup_test_session_abort_unref (session);
+}
+
static void
test_session_properties (const char *name,
SoupSession *session,
@@ -437,6 +481,7 @@ main (int argc, char **argv)
g_test_add_func ("/session/SoupSession", do_plain_tests);
g_test_add_func ("/session/priority", do_priority_tests);
+ g_test_add_func ("/session/priority-change", do_priority_change_test);
g_test_add_func ("/session/property", do_property_tests);
g_test_add_func ("/session/features", do_features_test);
g_test_add_func ("/session/queue-order", do_queue_order_test);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]