From 7959ad9eaf0055dafb36ec90710d5378fe5714c2 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 24 Sep 2013 14:10:40 -0400 Subject: [PATCH] fetcher: Fix previous commit I was getting hangs in the test suite, and looking at the previous commit, we were calling the async completion functions out of the finalizer for the URI, which is weird. I didn't analyze what's going wrong, but what we really should be doing is processing our internal queue after we've downloaded a file, and the request is about to be finalized. I suspect doing queue management from the finalizer created a circular reference type situation. This patch deduplicates the queue processing bits too. https://bugzilla.gnome.org/show_bug.cgi?id=708126 --- src/libostree/ostree-fetcher.c | 43 ++++++++++++---------------------- 1 file changed, 15 insertions(+), 28 deletions(-) diff --git a/src/libostree/ostree-fetcher.c b/src/libostree/ostree-fetcher.c index 3316dd96..d5cad9c0 100644 --- a/src/libostree/ostree-fetcher.c +++ b/src/libostree/ostree-fetcher.c @@ -53,9 +53,6 @@ typedef struct { GSimpleAsyncResult *result; } OstreeFetcherPendingURI; -static void ostree_fetcher_pending_uri_done (OstreeFetcher *self, - OstreeFetcherPendingURI *pending); - static void pending_uri_free (OstreeFetcherPendingURI *pending) { @@ -64,9 +61,6 @@ pending_uri_free (OstreeFetcherPendingURI *pending) if (pending->refcount > 0) return; - if (!pending->is_stream) - ostree_fetcher_pending_uri_done (pending->self, pending); - soup_uri_free (pending->uri); g_clear_object (&pending->self); g_clear_object (&pending->out_tmpfile); @@ -190,20 +184,16 @@ static void on_request_sent (GObject *object, GAsyncResult *result, gpointer user_data); static void -ostree_fetcher_pending_uri_done (OstreeFetcher *self, - OstreeFetcherPendingURI *pending) +ostree_fetcher_process_pending_queue (OstreeFetcher *self) { - OstreeFetcherPendingURI *p; - g_assert (!pending->is_stream); - - self->outstanding--; - p = g_queue_pop_head (&self->pending_queue); - if (p != NULL) + while (g_queue_peek_head (&self->pending_queue) != NULL && + self->outstanding < self->max_outstanding) { + OstreeFetcherPendingURI *next = g_queue_pop_head (&self->pending_queue); self->outstanding++; - soup_request_send_async (p->request, p->cancellable, - on_request_sent, p); + soup_request_send_async (next->request, next->cancellable, + on_request_sent, next); } } @@ -213,20 +203,11 @@ ostree_fetcher_queue_pending_uri (OstreeFetcher *self, { g_assert (!pending->is_stream); - if (self->outstanding >= self->max_outstanding) - { - g_queue_push_tail (&self->pending_queue, pending); - } - else - { - self->outstanding++; - soup_request_send_async (pending->request, pending->cancellable, - on_request_sent, pending); - } + g_queue_push_tail (&self->pending_queue, pending); + + ostree_fetcher_process_pending_queue (self); } - - static void on_splice_complete (GObject *object, GAsyncResult *result, @@ -244,6 +225,12 @@ on_splice_complete (GObject *object, if (!file_info) goto out; + /* Now that we've finished downloading, continue with other queued + * requests. + */ + pending->self->outstanding--; + ostree_fetcher_process_pending_queue (pending->self); + filesize = g_file_info_get_size (file_info); if (filesize < pending->content_length) {