SoupSession: make queue items hold a ref on the session
authorDan Winship <danw@gnome.org>
Sun, 12 Aug 2012 14:43:01 +0000 (10:43 -0400)
committerDan Winship <danw@gnome.org>
Mon, 13 Aug 2012 19:02:24 +0000 (15:02 -0400)
Historically, messages sent via soup_session_queue_message() did not
hold a ref on the session, and unreffing the session when messages
were in progress would cancel them. This is ugly internally though,
and at any rate, depends on being able to know for sure that no one
else is secretly holding a ref on the session.

So, fix it so that pending messages hold a ref on the session, and you
need to use soup_session_abort() before unreffing if you want to
cancel everything.

If it turns out that this breaks things it can be reverted before
2.40...

libsoup/soup-message-queue.c
libsoup/soup-session-async.c
libsoup/soup-session-sync.c

index 8ef129a..e464035 100644 (file)
@@ -101,7 +101,7 @@ soup_message_queue_append (SoupMessageQueue *queue, SoupMessage *msg,
        SoupMessageQueueItem *item;
 
        item = g_slice_new0 (SoupMessageQueueItem);
-       item->session = queue->session;
+       item->session = g_object_ref (queue->session);
        item->async_context = soup_session_get_async_context (item->session);
        item->queue = queue;
        item->msg = g_object_ref (msg);
@@ -178,6 +178,7 @@ soup_message_queue_item_unref (SoupMessageQueueItem *item)
        /* And free it */
        g_signal_handlers_disconnect_by_func (item->msg,
                                              queue_message_restarted, item);
+       g_object_unref (item->session);
        g_object_unref (item->msg);
        g_object_unref (item->cancellable);
        if (item->proxy_addr)
index 0f365f3..6c8e182 100644 (file)
@@ -140,7 +140,6 @@ tunnel_complete (SoupMessageQueueItem *item)
        soup_message_queue_item_unref (item->related);
        soup_session_unqueue_item (session, item);
        soup_message_queue_item_unref (item);
-       g_object_unref (session);
 }
 
 static void
@@ -210,7 +209,6 @@ got_connection (SoupConnection *conn, guint status, gpointer user_data)
                soup_connection_disconnect (conn);
                do_idle_run_queue (session);
                soup_message_queue_item_unref (item);
-               g_object_unref (session);
                return;
        }
 
@@ -229,7 +227,6 @@ got_connection (SoupConnection *conn, guint status, gpointer user_data)
 
                do_idle_run_queue (session);
                soup_message_queue_item_unref (item);
-               g_object_unref (session);
                return;
        }
 
@@ -249,7 +246,6 @@ got_connection (SoupConnection *conn, guint status, gpointer user_data)
                          G_CALLBACK (connection_closed), session);
        run_queue ((SoupSessionAsync *)session);
        soup_message_queue_item_unref (item);
-       g_object_unref (session);
 }
 
 static void
@@ -282,7 +278,6 @@ process_queue_item (SoupMessageQueueItem *item,
 
                        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;
@@ -307,14 +302,14 @@ process_queue_item (SoupMessageQueueItem *item,
                        if (item->state != SOUP_MESSAGE_FINISHED)
                                break;
 
-                       g_object_ref (session);
+                       soup_message_queue_item_ref (item);
                        soup_session_unqueue_item (session, item);
                        if (item->callback)
                                item->callback (session, item->msg, item->callback_data);
                        else if (item->new_api)
                                send_request_finished (session, item);
                        do_idle_run_queue (session);
-                       g_object_unref (session);
+                       soup_message_queue_item_unref (item);
                        return;
 
                default:
index 96ab916..81410c5 100644 (file)
@@ -297,7 +297,6 @@ queue_message_callback (gpointer data)
        SoupMessageQueueItem *item = data;
 
        item->callback (item->session, item->msg, item->callback_data);
-       g_object_unref (item->session);
        soup_message_queue_item_unref (item);
        return FALSE;
 }
@@ -311,10 +310,8 @@ queue_message_thread (gpointer data)
        if (item->callback) {
                soup_add_completion (soup_session_get_async_context (item->session),
                                     queue_message_callback, item);
-       } else {
-               g_object_unref (item->session);
+       } else
                soup_message_queue_item_unref (item);
-       }
 
        return NULL;
 }
@@ -326,7 +323,6 @@ soup_session_sync_queue_message (SoupSession *session, SoupMessage *msg,
        SoupMessageQueueItem *item;
        GThread *thread;
 
-       g_object_ref (session);
        item = soup_session_append_queue_item (session, msg, callback, user_data);
        thread = g_thread_new ("SoupSessionSync:queue_message",
                               queue_message_thread, item);