[gnome-builder] pipeline: short-circuit when pipeline is past requested phase
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] pipeline: short-circuit when pipeline is past requested phase
- Date: Mon, 16 Oct 2017 21:58:02 +0000 (UTC)
commit d42b55a8840aa59bec321ab2434f7aac0379a678
Author: Christian Hergert <chergert redhat com>
Date: Mon Oct 16 14:35:07 2017 -0700
pipeline: short-circuit when pipeline is past requested phase
If the build pipeline has already past the requested phase, we
can short circuit. This should help in situations where we end
up queuing the request because a build is in progress (which is
beyond the phase we need to complete).
There is still an issue with this where queued items are stuck
behind an higher-requested phase and they will not be flushed
until that build has completed. To fix this issue, we need to
scan forward and flush items with lower requested phases.
src/libide/buildsystem/ide-build-manager.c | 9 +-
src/libide/buildsystem/ide-build-pipeline.c | 129 ++++++++++++++++++++++-----
src/libide/buildsystem/ide-build-pipeline.h | 8 ++
src/tests/test-ide-build-pipeline.c | 11 +--
4 files changed, 125 insertions(+), 32 deletions(-)
---
diff --git a/src/libide/buildsystem/ide-build-manager.c b/src/libide/buildsystem/ide-build-manager.c
index 344baab..50a4517 100644
--- a/src/libide/buildsystem/ide-build-manager.c
+++ b/src/libide/buildsystem/ide-build-manager.c
@@ -1156,10 +1156,11 @@ ide_build_manager_execute_async (IdeBuildManager *self,
IDE_EXIT;
}
- ide_build_pipeline_execute_async (self->pipeline,
- cancellable,
- ide_build_manager_execute_cb,
- g_steal_pointer (&task));
+ ide_build_pipeline_build_async (self->pipeline,
+ phase,
+ cancellable,
+ ide_build_manager_execute_cb,
+ g_steal_pointer (&task));
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_ERROR_COUNT]);
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_HAS_DIAGNOSTICS]);
diff --git a/src/libide/buildsystem/ide-build-pipeline.c b/src/libide/buildsystem/ide-build-pipeline.c
index b1e0725..d66dc2c 100644
--- a/src/libide/buildsystem/ide-build-pipeline.c
+++ b/src/libide/buildsystem/ide-build-pipeline.c
@@ -1413,59 +1413,144 @@ ide_build_pipeline_task_notify_completed (IdeBuildPipeline *self,
}
/**
- * ide_build_pipeline_execute_async:
+ * ide_build_pipeline_build_async:
* @self: A @IdeBuildPipeline
+ * @phase: the requested build phase
* @cancellable: (nullable): A #GCancellable or %NULL
* @callback: a callback to execute upon completion
* @user_data: data for @callback
*
* Asynchronously starts the build pipeline.
*
- * Any phase that has been invalidated up to the requested phase
- * will be executed until a stage has failed.
+ * The @phase parameter should contain the #IdeBuildPhase that is
+ * necessary to complete. If you simply want to trigger a generic
+ * build, you probably want %IDE_BUILD_PHASE_BUILD. If you only
+ * need to configure the project (and necessarily the dependencies
+ * up to that phase) you might want %IDE_BUILD_PHASE_CONFIGURE.
+ *
+ * You may not specify %IDE_BUILD_PHASE_AFTER or
+ * %IDE_BUILD_PHASE_BEFORE flags as those must always be processed
+ * with the underlying phase they are attached to.
*
* Upon completion, @callback will be executed and should call
* ide_build_pipeline_execute_finish() to get the status of the
* operation.
+ *
+ * Since: 3.28
*/
void
-ide_build_pipeline_execute_async (IdeBuildPipeline *self,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
+ide_build_pipeline_build_async (IdeBuildPipeline *self,
+ IdeBuildPhase phase,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
g_autoptr(GTask) task = NULL;
- g_autoptr(GFile) builddir = NULL;
- g_autoptr(GError) error = NULL;
TaskData *task_data;
IDE_ENTRY;
- g_return_if_fail (IDE_IS_BUILD_PIPELINE (self));
- g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
-
task = g_task_new (self, cancellable, callback, user_data);
- g_task_set_source_tag (task, ide_build_pipeline_execute_async);
+ g_task_set_source_tag (task, ide_build_pipeline_build_async);
g_task_set_priority (task, G_PRIORITY_LOW);
- if (self->requested_mask == IDE_BUILD_PHASE_NONE)
- {
- g_task_return_boolean (task, TRUE);
- IDE_EXIT;
- }
-
/*
- * XXX: Maybe we should allow a phase to be provided with execute
- * now for symmetry with the others. Also, rename to build_async()?
+ * If the requested phase has already been met (by a previous build
+ * or by an active build who has already surpassed this build phase,
+ * we can return a result immediately.
*/
+ if (self->position >= self->pipeline->len)
+ goto short_circuit;
+ else if (self->position >= 0)
+ {
+ const PipelineEntry *entry = &g_array_index (self->pipeline, PipelineEntry, self->position);
+
+ /* This phase is past the requested phase, we can complete the
+ * task immediately.
+ */
+ if (entry->phase > phase)
+ goto short_circuit;
+ }
task_data = task_data_new (task, TASK_BUILD);
- task_data->phase = 1 << g_bit_nth_msf (self->requested_mask, -1);
+ task_data->phase = 1 << g_bit_nth_msf (phase, -1);
g_task_set_task_data (task, task_data, task_data_free);
g_queue_push_tail (&self->task_queue, g_steal_pointer (&task));
ide_build_pipeline_queue_flush (self);
+
+ IDE_EXIT;
+
+short_circuit:
+ g_task_return_boolean (task, TRUE);
+ IDE_EXIT;
+}
+
+/**
+ * ide_build_pipeline_build_finish:
+ * @self: An #IdeBuildPipeline
+ * @result: A #GAsyncResult provided to callback
+ * @error: A location for a #GError, or %NULL
+ *
+ * This function completes the asynchronous request to build
+ * up to a particular phase of the build pipeline.
+ *
+ * Returns: %TRUE if the build stages were executed successfully
+ * up to the requested build phase provided to
+ * ide_build_pipeline_build_async().
+ *
+ * Since: 3.28
+ */
+gboolean
+ide_build_pipeline_build_finish (IdeBuildPipeline *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ gboolean ret;
+
+ IDE_ENTRY;
+
+ g_return_val_if_fail (IDE_IS_BUILD_PIPELINE (self), FALSE);
+ g_return_val_if_fail (G_IS_TASK (result), FALSE);
+
+ ret = g_task_propagate_boolean (G_TASK (result), error);
+
+ IDE_RETURN (ret);
+}
+
+/**
+ * ide_build_pipeline_execute_async:
+ * @self: A @IdeBuildPipeline
+ * @cancellable: (nullable): A #GCancellable or %NULL
+ * @callback: a callback to execute upon completion
+ * @user_data: data for @callback
+ *
+ * Asynchronously starts the build pipeline.
+ *
+ * Any phase that has been invalidated up to the requested phase
+ * will be executed until a stage has failed.
+ *
+ * Upon completion, @callback will be executed and should call
+ * ide_build_pipeline_execute_finish() to get the status of the
+ * operation.
+ *
+ * Since: 3.24
+ */
+void
+ide_build_pipeline_execute_async (IdeBuildPipeline *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ IDE_ENTRY;
+
+ g_return_if_fail (IDE_IS_BUILD_PIPELINE (self));
+ g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+ ide_build_pipeline_build_async (self, self->requested_mask, cancellable, callback, user_data);
+
+ IDE_EXIT;
}
static gboolean
diff --git a/src/libide/buildsystem/ide-build-pipeline.h b/src/libide/buildsystem/ide-build-pipeline.h
index f77e42a..a59092a 100644
--- a/src/libide/buildsystem/ide-build-pipeline.h
+++ b/src/libide/buildsystem/ide-build-pipeline.h
@@ -99,6 +99,14 @@ guint ide_build_pipeline_add_error_format (IdeBuildPipeline
GRegexCompileFlags flags);
gboolean ide_build_pipeline_remove_error_format (IdeBuildPipeline *self,
guint error_format_id);
+void ide_build_pipeline_build_async (IdeBuildPipeline *self,
+ IdeBuildPhase phase,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean ide_build_pipeline_build_finish (IdeBuildPipeline *self,
+ GAsyncResult *result,
+ GError **error);
void ide_build_pipeline_execute_async (IdeBuildPipeline *self,
GCancellable *cancellable,
GAsyncReadyCallback callback,
diff --git a/src/tests/test-ide-build-pipeline.c b/src/tests/test-ide-build-pipeline.c
index 4791d1e..c136fa4 100644
--- a/src/tests/test-ide-build-pipeline.c
+++ b/src/tests/test-ide-build-pipeline.c
@@ -72,14 +72,13 @@ context_loaded (GObject *object,
"configuration", config,
NULL);
- ide_build_pipeline_request_phase (pipeline, IDE_BUILD_PHASE_BUILD);
-
g_debug ("Executing pipeline");
- ide_build_pipeline_execute_async (pipeline,
- NULL,
- execute_cb,
- g_steal_pointer (&task));
+ ide_build_pipeline_build_async (pipeline,
+ IDE_BUILD_PHASE_BUILD,
+ NULL,
+ execute_cb,
+ g_steal_pointer (&task));
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]