diff --git a/lib/wp/session-item.c b/lib/wp/session-item.c index d23c806e5dfaced0e04420653688f985c68ffad1..f2e2d6d1519c76a769ea06a7d89f60ecebc1669a 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 24311893b3a9e1d5bca14eb8bbc333c9f0da9d21..03e8d15c8c3f940042cf8bead84bbf54a865ef27 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 221f26014a51ab90256e1dcb9668118da1fb77e3..dc3698d1ac3c46aed548b2d4e58ff297e4d435e3 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 5b173641c2dccb30e33eca1e0ad01327979b0d6d..949cb6369eec4a6871d1e96f5ad6a786a0b10a8d 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); }