const OstreeCollectionRef *ref,
GCancellable *cancellable,
GError **error);
+static void scan_object_queue_data_free (ScanObjectQueueData *scan_data);
static gboolean
update_progress (gpointer user_data)
"fetched", "u", fetched,
"requested", "u", requested,
"scanning", "u", g_queue_is_empty (&pull_data->scan_object_queue) ? 0 : 1,
+ "caught-error", "b", pull_data->caught_error,
"scanned-metadata", "u", n_scanned_metadata,
"bytes-transferred", "t", bytes_transferred,
"start-time", "t", start_time,
/* we only enter the main loop when we're fetching objects */
g_assert (pull_data->phase == OSTREE_PULL_PHASE_FETCHING_OBJECTS);
- if (pull_data->caught_error)
- return TRUE;
-
if (pull_data->dry_run)
return pull_data->dry_run_emitted_progress;
return current_idle;
}
+/* Most async operations finish by calling this function; it will consume
+ * @errorp if set, update statistics, and initiate processing of any further
+ * requests as appropriate.
+ */
static void
check_outstanding_requests_handle_error (OtPullData *pull_data,
GError **errorp)
g_clear_error (errorp);
}
}
+
+ /* If we're in error state, we wait for any pending operations to complete,
+ * but ensure that all no further operations are queued.
+ */
+ if (pull_data->caught_error)
+ {
+ g_queue_foreach (&pull_data->scan_object_queue, (GFunc) scan_object_queue_data_free, NULL);
+ g_queue_clear (&pull_data->scan_object_queue);
+ g_hash_table_remove_all (pull_data->pending_fetch_metadata);
+ g_hash_table_remove_all (pull_data->pending_fetch_deltaparts);
+ g_hash_table_remove_all (pull_data->pending_fetch_content);
+ }
else
{
GHashTableIter hiter;
return fetch_full || deltas_full || writes_full;
}
+static void
+scan_object_queue_data_free (ScanObjectQueueData *scan_data)
+{
+ g_free (scan_data->path);
+ if (scan_data->requested_ref != NULL)
+ ostree_collection_ref_free (scan_data->requested_ref);
+ g_free (scan_data);
+}
+
static gboolean
idle_worker (gpointer user_data)
{
pull_data->cancellable,
&error);
check_outstanding_requests_handle_error (pull_data, &error);
+ scan_object_queue_data_free (scan_data);
- g_free (scan_data->path);
- if (scan_data->requested_ref != NULL)
- ostree_collection_ref_free (scan_data->requested_ref);
- g_free (scan_data);
return G_SOURCE_CONTINUE;
}
g_clear_pointer (&pull_data->pending_fetch_content, (GDestroyNotify) g_hash_table_unref);
g_clear_pointer (&pull_data->pending_fetch_metadata, (GDestroyNotify) g_hash_table_unref);
g_clear_pointer (&pull_data->pending_fetch_deltaparts, (GDestroyNotify) g_hash_table_unref);
+ g_queue_foreach (&pull_data->scan_object_queue, (GFunc) scan_object_queue_data_free, NULL);
+ g_queue_clear (&pull_data->scan_object_queue);
g_clear_pointer (&pull_data->idle_src, (GDestroyNotify) g_source_destroy);
g_clear_pointer (&pull_data->dirs, (GDestroyNotify) g_ptr_array_unref);
g_clear_pointer (&remote_config, (GDestroyNotify) g_key_file_unref);
gpointer user_data)
{
g_autofree char *status = NULL;
- gboolean scanning;
+ gboolean caught_error, scanning;
guint outstanding_fetches;
guint outstanding_metadata_fetches;
guint outstanding_writes;
"outstanding-fetches", "u", &outstanding_fetches,
"outstanding-metadata-fetches", "u", &outstanding_metadata_fetches,
"outstanding-writes", "u", &outstanding_writes,
+ "caught-error", "b", &caught_error,
"scanning", "u", &scanning,
"scanned-metadata", "u", &n_scanned_metadata,
"fetched-delta-parts", "u", &fetched_delta_parts,
{
g_string_append (buf, status);
}
+ else if (caught_error)
+ {
+ g_string_append_printf (buf, "Caught error, waiting for outstanding tasks");
+ }
else if (outstanding_fetches)
{
guint64 bytes_transferred, start_time, total_delta_part_size;