Commit a2eb8964 authored by Carlos Garcia Campos's avatar Carlos Garcia Campos Committed by Patrick Griffis
Browse files

session: add support for re-prioritizing queue items

Monitor SoupMessage:priority changes to sort the queue accortding to the
new message priorities.
parent d691bf0b
......@@ -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);
return item;
}
......
......@@ -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;
......
......@@ -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);
}
......
......@@ -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);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment