xdg-app was hanging for me with v2015.8, but worked with v2015.7.
I narrowed things down to the GMainLoop/context commit, in which
we started pushing a temporary main context for synchronous
requests internally.
That's never really going to work with libsoup - there needs
to be a single main context which works on the socket. Furthermore,
clients couldn't get progress messages that way.
For *other* internal uses where we added APIs that talk to the remote
repo, we cleanly push a temporary main context.
(Note that I kind of snuck in a change here around the GError handling
in pulls that isn't strictly related but came up in testing)
data->done = TRUE;
}
+/* Synchronously request a URI - will iterate the thread-default main
+ * context for historical reasons. If you don't want that, push a
+ * temporary one.
+ */
gboolean
_ostree_fetcher_request_uri_to_membuf (OstreeFetcher *fetcher,
SoupURI *uri,
if (g_cancellable_set_error_if_cancelled (cancellable, error))
return FALSE;
- mainctx = g_main_context_new ();
- g_main_context_push_thread_default (mainctx);
+ mainctx = g_main_context_ref_thread_default ();
data.done = FALSE;
data.error = error;
ret = TRUE;
*out_contents = g_memory_output_stream_steal_as_bytes (buf);
out:
- if (mainctx)
- g_main_context_pop_thread_default (mainctx);
g_clear_object (&(data.result_stream));
return ret;
}
GMainLoop *loop;
} FetchMetalinkSyncData;
+/*
+ * Note that for legacy reasons we iterate the caller's main context.
+ * If you don't want that (and you probably don't) push a temporary
+ * one.
+ */
gboolean
_ostree_metalink_request_sync (OstreeMetalink *self,
SoupURI **out_target_uri,
if (fetching_sync_uri != NULL)
*fetching_sync_uri = _ostree_metalink_get_uri (self);
- mainctx = g_main_context_new ();
- g_main_context_push_thread_default (mainctx);
+ mainctx = g_main_context_ref_thread_default ();
request.metalink = g_object_ref (self);
request.urls = g_ptr_array_new_with_free_func ((GDestroyNotify) soup_uri_free);
ret = TRUE;
out:
- if (mainctx)
- g_main_context_pop_thread_default (mainctx);
g_clear_object (&request.metalink);
g_clear_pointer (&request.urls, g_ptr_array_unref);
g_clear_pointer (&request.parser, g_markup_parse_context_free);
guint64 previous_bytes_sec;
guint64 previous_total_downloaded;
+ GError *cached_async_error;
GError **async_error;
gboolean caught_error;
pull_data->is_mirror = (flags & OSTREE_REPO_PULL_FLAGS_MIRROR) > 0;
pull_data->is_commit_only = (flags & OSTREE_REPO_PULL_FLAGS_COMMIT_ONLY) > 0;
- pull_data->async_error = error;
+ if (error)
+ pull_data->async_error = &pull_data->cached_async_error;
+ else
+ pull_data->async_error = NULL;
pull_data->main_context = g_main_context_ref_thread_default ();
pull_data->flags = flags;
ret = TRUE;
out:
+ /* This is pretty ugly - we have two error locations, because we
+ * have a mix of synchronous and async code. Mixing them gets messy
+ * as we need to avoid overwriting errors.
+ */
+ if (pull_data->cached_async_error && error && !*error)
+ g_propagate_error (error, pull_data->cached_async_error);
+ else
+ g_clear_error (&pull_data->cached_async_error);
+
ostree_repo_abort_transaction (pull_data->repo, cancellable, NULL);
g_main_context_unref (pull_data->main_context);
if (update_timeout)
GError **error)
{
gboolean ret = FALSE;
+
if (is_metalink)
{
glnx_unref_object OstreeMetalink *metalink = NULL;
GError **error)
{
glnx_unref_object OstreeFetcher *fetcher = NULL;
+ g_autoptr(GMainContext) mainctx = NULL;
gboolean ret = FALSE;
SoupURI *base_uri = NULL;
uint i;
const char *filenames[] = {"summary", "summary.sig"};
GBytes **outputs[] = {out_summary, out_signatures};
+ mainctx = g_main_context_new ();
+ g_main_context_push_thread_default (mainctx);
+
fetcher = _ostree_repo_remote_new_fetcher (self, name, error);
if (fetcher == NULL)
goto out;
ret = TRUE;
out:
+ if (mainctx)
+ g_main_context_pop_thread_default (mainctx);
if (base_uri != NULL)
soup_uri_free (base_uri);
-
return ret;
}