From 79a39e98c93f691892faabebfb59ed23e4be79a4 Mon Sep 17 00:00:00 2001 From: George Kiagiadakis <george.kiagiadakis@collabora.com> Date: Sun, 29 Mar 2020 12:36:19 +0300 Subject: [PATCH] transition: call execute_step() with _STEP_ERROR in error conditions This allows the implementation to rollback changes, cancel jobs, etc --- lib/wp/session-item.c | 19 +++++++++++++++++-- lib/wp/transition.c | 9 +++++++++ modules/module-si-adapter.c | 4 +++- tests/wp/transition.c | 12 ++++++++---- 4 files changed, 37 insertions(+), 7 deletions(-) diff --git a/lib/wp/session-item.c b/lib/wp/session-item.c index d23c806e..f2e2d6d1 100644 --- a/lib/wp/session-item.c +++ b/lib/wp/session-item.c @@ -125,6 +125,21 @@ wp_session_item_default_get_next_step (WpSessionItem * self, return WP_TRANSITION_STEP_NONE; } +static void +wp_session_item_default_execute_step (WpSessionItem * self, + WpTransition * transition, guint step) +{ + switch (step) { + case WP_TRANSITION_STEP_NONE: + break; + case WP_TRANSITION_STEP_ERROR: + wp_session_item_reset (self); + break; + default: + g_return_if_reached (); + } +} + static void wp_session_item_default_reset (WpSessionItem * self) { @@ -222,9 +237,9 @@ wp_session_item_class_init (WpSessionItemClass * klass) object_class->dispose = wp_session_item_dispose; object_class->finalize = wp_session_item_finalize; - klass->reset = wp_session_item_default_reset; - klass->get_next_step = wp_session_item_default_get_next_step; + klass->execute_step = wp_session_item_default_execute_step; + klass->reset = wp_session_item_default_reset; klass->export = wp_session_item_default_export; klass->export_finish = wp_session_item_default_export_finish; klass->unexport = wp_session_item_default_unexport; diff --git a/lib/wp/transition.c b/lib/wp/transition.c index 24311893..03e8d15c 100644 --- a/lib/wp/transition.c +++ b/lib/wp/transition.c @@ -367,6 +367,10 @@ wp_transition_return (WpTransition * self, WpTransitionPrivate *priv) * When #WpTransitionClass.get_next_step() returns %WP_TRANSITION_STEP_ERROR, * this function calls wp_transition_return_error(), unless it has already been * called directly by #WpTransitionClass.get_next_step(). + * + * In error conditions, #WpTransitionClass.execute_step() is called once with + * @step being %WP_TRANSITION_STEP_ERROR, allowing the implementation to + * rollback any changes or cancel underlying jobs, if necessary. */ void wp_transition_advance (WpTransition * self) @@ -434,6 +438,11 @@ wp_transition_return_error (WpTransition * self, GError * error) priv->step = WP_TRANSITION_STEP_ERROR; priv->error = error; + + /* allow the implementation to rollback changes */ + if (WP_TRANSITION_GET_CLASS (self)->execute_step) + WP_TRANSITION_GET_CLASS (self)->execute_step (self, priv->step); + wp_transition_return (self, priv); } diff --git a/modules/module-si-adapter.c b/modules/module-si-adapter.c index 221f2601..dc3698d1 100644 --- a/modules/module-si-adapter.c +++ b/modules/module-si-adapter.c @@ -341,7 +341,9 @@ si_adapter_execute_step (WpSessionItem * item, WpTransition * transition, break; } default: - g_return_if_reached (); + WP_SESSION_ITEM_GET_CLASS (si_adapter_parent_class)->execute_step (item, + transition, step); + break; } } diff --git a/tests/wp/transition.c b/tests/wp/transition.c index 5b173641..949cb636 100644 --- a/tests/wp/transition.c +++ b/tests/wp/transition.c @@ -102,8 +102,10 @@ wp_test_transition_execute_step (WpTransition * transition, guint step) WpTestTransition * self = WP_TEST_TRANSITION (transition); struct data *d = wp_transition_get_data (transition); - g_assert_cmpint (step, >=, STEP_FIRST); - g_assert_cmpint (step, <=, STEP_FINISH); + if (step != WP_TRANSITION_STEP_ERROR) { + g_assert_cmpint (step, >=, STEP_FIRST); + g_assert_cmpint (step, <=, STEP_FINISH); + } g_assert_nonnull (d); g_assert_cmpint (d->ste_i, <, 10); @@ -115,7 +117,8 @@ wp_test_transition_execute_step (WpTransition * transition, guint step) return; } - g_idle_add (advance_on_idle, transition); + if (step != WP_TRANSITION_STEP_ERROR) + g_idle_add (advance_on_idle, transition); } static void @@ -260,7 +263,8 @@ test_transition_error (void) g_assert_cmpint (data.ste[0], ==, STEP_FIRST); g_assert_cmpint (data.ste[1], ==, STEP_SECOND); g_assert_cmpint (data.ste[2], ==, STEP_THIRD); - g_assert_cmpint (data.ste_i, ==, 3); + g_assert_cmpint (data.ste[3], ==, WP_TRANSITION_STEP_ERROR); + g_assert_cmpint (data.ste_i, ==, 4); g_assert_true (data.destroyed); } -- GitLab