From 49b63b604528ab119c132e91511e8db3d818bd97 Mon Sep 17 00:00:00 2001 From: George Kiagiadakis <george.kiagiadakis@collabora.com> Date: Thu, 16 Apr 2020 17:38:31 +0300 Subject: [PATCH] session-item: refactor export to use a process similar to activate + expose the export transition in the session item class + make the export-related flags immutable + add an export error flag + update and improve documentation --- lib/wp/endpoint-link.c | 3 +- lib/wp/session-item.c | 244 ++++++++++++++++-------------- lib/wp/session-item.h | 71 +++++---- modules/module-si-adapter.c | 30 ++-- modules/module-si-standard-link.c | 14 +- tests/wp/session-item.c | 30 ++-- 6 files changed, 213 insertions(+), 179 deletions(-) diff --git a/lib/wp/endpoint-link.c b/lib/wp/endpoint-link.c index 96d093b2..24046eca 100644 --- a/lib/wp/endpoint-link.c +++ b/lib/wp/endpoint-link.c @@ -383,7 +383,6 @@ impl_request_state (void *object, enum pw_endpoint_link_state state) switch (state) { case PW_ENDPOINT_LINK_STATE_ACTIVE: - wp_session_item_deactivate (WP_SESSION_ITEM (self->item)); wp_session_item_activate (WP_SESSION_ITEM (self->item), (GAsyncReadyCallback) on_item_activated, self); break; @@ -440,7 +439,7 @@ on_si_link_flags_changed (WpSiLink * item, WpSiFlags flags, { enum pw_endpoint_link_state old_state = self->info.state; - if (flags & WP_SI_FLAG_IN_ERROR) + if (flags & WP_SI_FLAG_EXPORT_ERROR) self->info.state = PW_ENDPOINT_LINK_STATE_ERROR; else if (flags & WP_SI_FLAG_ACTIVE) self->info.state = PW_ENDPOINT_LINK_STATE_ACTIVE; diff --git a/lib/wp/session-item.c b/lib/wp/session-item.c index 22a92649..ea8e6990 100644 --- a/lib/wp/session-item.c +++ b/lib/wp/session-item.c @@ -14,6 +14,7 @@ #define G_LOG_DOMAIN "wp-si" #include "session-item.h" +#include "debug.h" #include "private.h" #include "error.h" #include "wpenums.h" @@ -169,7 +170,7 @@ wp_session_item_default_get_associated_proxy (WpSessionItem * self, } static guint -wp_session_item_default_get_next_step (WpSessionItem * self, +wp_session_item_default_activate_get_next_step (WpSessionItem * self, WpTransition * transition, guint step) { /* the default implementation just activates instantly, @@ -181,32 +182,25 @@ enum { EXPORT_STEP_ENDPOINT = WP_TRANSITION_STEP_CUSTOM_START, EXPORT_STEP_STREAMS, EXPORT_STEP_LINK, - EXPORT_STEP_FINISH, }; static guint -default_export_get_next_step (WpSessionItem * self, WpTransition * transition, - guint step) +wp_session_item_default_export_get_next_step (WpSessionItem * self, + WpTransition * transition, guint step) { WpSessionItemPrivate *priv = wp_session_item_get_instance_private (self); switch (step) { case WP_TRANSITION_STEP_NONE: - if (WP_IS_SI_ENDPOINT (self)) { - priv->flags |= WP_SI_FLAG_EXPORTING; - g_signal_emit (self, signals[SIGNAL_FLAGS_CHANGED], 0, priv->flags); + if (WP_IS_SI_ENDPOINT (self)) return EXPORT_STEP_ENDPOINT; - } - else if (WP_IS_SI_LINK (self)) { - priv->flags |= WP_SI_FLAG_EXPORTING; - g_signal_emit (self, signals[SIGNAL_FLAGS_CHANGED], 0, priv->flags); + else if (WP_IS_SI_LINK (self)) return EXPORT_STEP_LINK; - } else { wp_transition_return_error (transition, g_error_new ( WP_DOMAIN_LIBRARY, WP_LIBRARY_ERROR_INVALID_ARGUMENT, - "Cannot export WpSessionItem of unknown type (%s:%p)", - G_OBJECT_TYPE_NAME (self), self)); + "Cannot export WpSessionItem of unknown type " WP_OBJECT_FORMAT, + WP_OBJECT_ARGS (self))); return WP_TRANSITION_STEP_ERROR; } @@ -221,15 +215,12 @@ default_export_get_next_step (WpSessionItem * self, WpTransition * transition, /* go to next step only when all impl proxies are augmented */ if (g_hash_table_size (priv->impl_streams) == wp_si_endpoint_get_n_streams (WP_SI_ENDPOINT (self))) - return EXPORT_STEP_FINISH; + return WP_TRANSITION_STEP_NONE; else return step; case EXPORT_STEP_LINK: g_return_val_if_fail (WP_IS_SI_LINK (self), WP_TRANSITION_STEP_ERROR); - return EXPORT_STEP_FINISH; - - case EXPORT_STEP_FINISH: return WP_TRANSITION_STEP_NONE; default: @@ -263,8 +254,8 @@ on_export_proxy_augmented (WpProxy * proxy, GAsyncResult * res, gpointer data) } static void -default_export_execute_step (WpSessionItem * self, WpTransition * transition, - guint step) +wp_session_item_default_export_execute_step (WpSessionItem * self, + WpTransition * transition, guint step) { WpSessionItemPrivate *priv = wp_session_item_get_instance_private (self); g_autoptr (WpSession) session = g_weak_ref_get (&priv->session); @@ -312,67 +303,18 @@ default_export_execute_step (WpSessionItem * self, WpTransition * transition, transition); break; - case EXPORT_STEP_FINISH: - priv->flags &= ~WP_SI_FLAG_EXPORTING; - priv->flags |= WP_SI_FLAG_EXPORTED; - g_signal_emit (self, signals[SIGNAL_FLAGS_CHANGED], 0, priv->flags); - wp_transition_advance (transition); - break; - default: g_return_if_reached (); } } + static void -default_export_rollback (WpSessionItem * self) +wp_session_item_default_export_rollback (WpSessionItem * self) { WpSessionItemPrivate *priv = wp_session_item_get_instance_private (self); - static const guint flags = (WP_SI_FLAG_EXPORTING | WP_SI_FLAG_EXPORTED); - g_clear_pointer (&priv->impl_streams, g_hash_table_unref); g_clear_object (&priv->impl_proxy); g_weak_ref_set (&priv->session, NULL); - - if (priv->flags & flags) { - priv->flags &= ~flags; - g_signal_emit (self, signals[SIGNAL_FLAGS_CHANGED], 0, priv->flags); - } -} - -static void -wp_session_item_default_export (WpSessionItem * self, - WpSession * session, GCancellable * cancellable, - GAsyncReadyCallback callback, gpointer callback_data) -{ - WpSessionItemPrivate *priv = wp_session_item_get_instance_private (self); - WpTransition *transition; - - g_weak_ref_set (&priv->session, session); - - transition = wp_transition_new (wp_si_transition_get_type (), - self, cancellable, callback, callback_data); - wp_transition_set_source_tag (transition, wp_session_item_default_export); - - WP_SI_TRANSITION (transition)->get_next_step = default_export_get_next_step; - WP_SI_TRANSITION (transition)->execute_step = default_export_execute_step; - WP_SI_TRANSITION (transition)->rollback = default_export_rollback; - wp_transition_advance (transition); -} - -static gboolean -wp_session_item_default_export_finish (WpSessionItem * self, - GAsyncResult * res, GError ** error) -{ - g_return_val_if_fail ( - g_async_result_is_tagged (res, wp_session_item_default_export), FALSE); - - return wp_transition_finish (res, error); -} - -static void -wp_session_item_default_unexport (WpSessionItem * self) -{ - default_export_rollback (self); } static void @@ -385,10 +327,10 @@ wp_session_item_class_init (WpSessionItemClass * klass) klass->reset = wp_session_item_default_reset; klass->get_associated_proxy = wp_session_item_default_get_associated_proxy; - klass->get_next_step = wp_session_item_default_get_next_step; - klass->export = wp_session_item_default_export; - klass->export_finish = wp_session_item_default_export_finish; - klass->unexport = wp_session_item_default_unexport; + klass->activate_get_next_step = wp_session_item_default_activate_get_next_step; + klass->export_get_next_step = wp_session_item_default_export_get_next_step; + klass->export_execute_step = wp_session_item_default_export_execute_step; + klass->export_rollback = wp_session_item_default_export_rollback; /** * WpSessionItem::flags-changed: @@ -574,17 +516,14 @@ wp_session_item_get_configuration (WpSessionItem * self) } static void -on_transition_completed (WpTransition * transition, GParamSpec * pspec, +on_activate_transition_completed (WpTransition * transition, GParamSpec * pspec, WpSessionItem * self) { WpSessionItemPrivate *priv = wp_session_item_get_instance_private (self); - if (wp_transition_had_error (transition)) - priv->flags |= WP_SI_FLAG_IN_ERROR; - else - priv->flags |= WP_SI_FLAG_ACTIVE; - + priv->flags |= wp_transition_had_error (transition) ? + WP_SI_FLAG_ACTIVATE_ERROR : WP_SI_FLAG_ACTIVE; priv->flags &= ~WP_SI_FLAG_ACTIVATING; g_signal_emit (self, signals[SIGNAL_FLAGS_CHANGED], 0, priv->flags); } @@ -595,15 +534,30 @@ on_transition_completed (WpTransition * transition, GParamSpec * pspec, * @callback: (scope async): a callback to call when activation is finished * @callback_data: (closure): data passed to @callback * - * Activates the item asynchronously. This internally starts a #WpTransition - * that calls into #WpSessionItemClass.get_next_step() and - * #WpSessionItemClass.execute_step() to advance. - * - * You can use wp_session_item_activate_finish() in the @callback to figure out + * Activates the item asynchronously. + * You can use wp_session_item_activate_finish() in the @callback to get * the result of this operation. * - * Normally this function is called internally by the session; there is no need - * to activate an item externally, except for unit testing purposes. + * This internally starts a #WpTransition that calls into + * #WpSessionItemClass.activate_get_next_step() and + * #WpSessionItemClass.activate_execute_step() to advance. + * If the transition fails, #WpSessionItemClass.activate_rollback() is called + * to reverse previous actions. + * + * The default implementation of the above virtual functions activates the + * item successfully without doing anything. In order to implement a meaningful + * session item, you should override all 3 of them. + * + * When this method is called, the %WP_SI_FLAG_ACTIVATING flag is set. When + * the operation finishes successfully, that flag is cleared and replaced with + * either %WP_SI_FLAG_ACTIVE or %WP_SI_FLAG_ACTIVATE_ERROR, depending on the + * success outcome of the operation. In order to clear + * %WP_SI_FLAG_ACTIVATE_ERROR, you can either call wp_session_item_deactivate() + * or wp_session_item_activate() to try activating again. + * + * This method cannot be called if another operation (activation or export) is + * in progress (%WP_SI_FLAGS_MASK_OPERATION_IN_PROGRESS) or if the item is + * already activated. */ void wp_session_item_activate (WpSessionItem * self, @@ -615,24 +569,26 @@ wp_session_item_activate (WpSessionItem * self, WpSessionItemPrivate *priv = wp_session_item_get_instance_private (self); - g_return_if_fail (!(priv->flags & (WP_SI_FLAG_ACTIVATING | WP_SI_FLAG_ACTIVE))); + g_return_if_fail (!(priv->flags & + (WP_SI_FLAGS_MASK_OPERATION_IN_PROGRESS | WP_SI_FLAG_ACTIVE))); - /* TODO: add a way to cancel the transition if reset() is called in the meantime */ + /* TODO: add a way to cancel the transition if deactivate() is called in the meantime */ WpTransition *transition = wp_transition_new (wp_si_transition_get_type (), self, NULL, callback, callback_data); wp_transition_set_source_tag (transition, wp_session_item_activate); g_signal_connect (transition, "notify::completed", - (GCallback) on_transition_completed, self); + (GCallback) on_activate_transition_completed, self); + priv->flags &= ~WP_SI_FLAG_ACTIVATE_ERROR; priv->flags |= WP_SI_FLAG_ACTIVATING; g_signal_emit (self, signals[SIGNAL_FLAGS_CHANGED], 0, priv->flags); WP_SI_TRANSITION (transition)->get_next_step = - WP_SESSION_ITEM_GET_CLASS (self)->get_next_step; + WP_SESSION_ITEM_GET_CLASS (self)->activate_get_next_step; WP_SI_TRANSITION (transition)->execute_step = - WP_SESSION_ITEM_GET_CLASS (self)->execute_step; + WP_SESSION_ITEM_GET_CLASS (self)->activate_execute_step; WP_SI_TRANSITION (transition)->rollback = - WP_SESSION_ITEM_GET_CLASS (self)->rollback; + WP_SESSION_ITEM_GET_CLASS (self)->activate_rollback; wp_transition_advance (transition); } @@ -648,6 +604,7 @@ gboolean wp_session_item_activate_finish (WpSessionItem * self, GAsyncResult * res, GError ** error) { + g_return_val_if_fail (WP_IS_SESSION_ITEM (self), FALSE); g_return_val_if_fail ( g_async_result_is_tagged (res, wp_session_item_activate), FALSE); return wp_transition_finish (res, error); @@ -667,14 +624,13 @@ wp_session_item_deactivate (WpSessionItem * self) g_return_if_fail (WP_IS_SESSION_ITEM (self)); WpSessionItemPrivate *priv = wp_session_item_get_instance_private (self); - static const guint flags = - (WP_SI_FLAG_ACTIVATING | WP_SI_FLAG_ACTIVE | WP_SI_FLAG_IN_ERROR); + static const guint flags = 0xf; /* all activation flags */ //TODO cancel job if ACTIVATING if (priv->flags & WP_SI_FLAG_ACTIVE && - WP_SESSION_ITEM_GET_CLASS (self)->rollback) - WP_SESSION_ITEM_GET_CLASS (self)->rollback (self); + WP_SESSION_ITEM_GET_CLASS (self)->activate_rollback) + WP_SESSION_ITEM_GET_CLASS (self)->activate_rollback (self); if (priv->flags & flags) { priv->flags &= ~flags; @@ -682,19 +638,52 @@ wp_session_item_deactivate (WpSessionItem * self) } } +static void +on_export_transition_completed (WpTransition * transition, GParamSpec * pspec, + WpSessionItem * self) +{ + WpSessionItemPrivate *priv = + wp_session_item_get_instance_private (self); + + priv->flags |= wp_transition_had_error (transition) ? + WP_SI_FLAG_EXPORT_ERROR : WP_SI_FLAG_EXPORTED; + priv->flags &= ~WP_SI_FLAG_EXPORTING; + g_signal_emit (self, signals[SIGNAL_FLAGS_CHANGED], 0, priv->flags); +} + /** - * wp_session_item_export: (virtual export) + * wp_session_item_export: * @self: the session item * @session: the session on which to export this item * @callback: (scope async): a callback to call when exporting is finished * @callback_data: (closure): data passed to @callback * * Exports this item asynchronously on PipeWire, making it part of the - * specified @session. + * specified @session. You can use wp_session_item_export_finish() in the + * @callback to get the result of this operation. + * + * This internally starts a #WpTransition that calls into + * #WpSessionItemClass.export_get_next_step() and + * #WpSessionItemClass.export_execute_step() to advance. + * If the transition fails, #WpSessionItemClass.export_rollback() is called + * to reverse previous actions. + * + * Exporting is internally implemented for endpoints (items that implement + * #WpSiEndpoint) and endpoint links (items that implement #WpSiLink). On other + * items the default implementation will immediately call the @callback, + * reporting error. You can extend this to export custom interfaces by + * overriding the virtual functions mentioned above. + * + * When this method is called, the %WP_SI_FLAG_EXPORTING flag is set. When + * the operation finishes successfully, that flag is cleared and replaced with + * either %WP_SI_FLAG_EXPORTED or %WP_SI_FLAG_EXPORT_ERROR, depending on the + * success outcome of the operation. In order to clear + * %WP_SI_FLAG_EXPORT_ERROR, you can either call wp_session_item_unexport() + * or wp_session_item_export() to try exporting again. * - * Exporting only makes sense for endpoints (items that implement #WpSiEndpoint) - * and endpoint links (items that implement #WpSiLink). On other items the - * default implementation will immediately call the @callback, reporting error. + * This method cannot be called if another operation (activation or export) is + * in progress (%WP_SI_FLAGS_MASK_OPERATION_IN_PROGRESS) or if the item is + * already exported. */ void wp_session_item_export (WpSessionItem * self, WpSession * session, @@ -702,19 +691,37 @@ wp_session_item_export (WpSessionItem * self, WpSession * session, { g_return_if_fail (WP_IS_SESSION_ITEM (self)); g_return_if_fail (WP_IS_SESSION (session)); - g_return_if_fail (WP_SESSION_ITEM_GET_CLASS (self)->export); WpSessionItemPrivate *priv = wp_session_item_get_instance_private (self); - g_return_if_fail (!(priv->flags & (WP_SI_FLAG_EXPORTING | WP_SI_FLAG_EXPORTED))); + g_return_if_fail (!(priv->flags & + (WP_SI_FLAGS_MASK_OPERATION_IN_PROGRESS | WP_SI_FLAG_EXPORTED))); - WP_SESSION_ITEM_GET_CLASS (self)->export (self, session, NULL, - callback, callback_data); + g_weak_ref_set (&priv->session, session); + + /* TODO: add a way to cancel the transition if unexport() is called in the meantime */ + WpTransition *transition = wp_transition_new (wp_si_transition_get_type (), + self, NULL, callback, callback_data); + wp_transition_set_source_tag (transition, wp_session_item_export); + g_signal_connect (transition, "notify::completed", + (GCallback) on_export_transition_completed, self); + + priv->flags &= ~WP_SI_FLAG_EXPORT_ERROR; + priv->flags |= WP_SI_FLAG_EXPORTING; + g_signal_emit (self, signals[SIGNAL_FLAGS_CHANGED], 0, priv->flags); + + WP_SI_TRANSITION (transition)->get_next_step = + WP_SESSION_ITEM_GET_CLASS (self)->export_get_next_step; + WP_SI_TRANSITION (transition)->execute_step = + WP_SESSION_ITEM_GET_CLASS (self)->export_execute_step; + WP_SI_TRANSITION (transition)->rollback = + WP_SESSION_ITEM_GET_CLASS (self)->export_rollback; + wp_transition_advance (transition); } /** - * wp_session_item_export_finish: (virtual export_finish) + * wp_session_item_export_finish: * @self: the session item * @res: the async operation result * @error: (out) (optional): the error of the operation, if any @@ -726,13 +733,13 @@ wp_session_item_export_finish (WpSessionItem * self, GAsyncResult * res, GError ** error) { g_return_val_if_fail (WP_IS_SESSION_ITEM (self), FALSE); - g_return_val_if_fail (WP_SESSION_ITEM_GET_CLASS (self)->export_finish, FALSE); - - return WP_SESSION_ITEM_GET_CLASS (self)->export_finish (self, res, error); + g_return_val_if_fail ( + g_async_result_is_tagged (res, wp_session_item_export), FALSE); + return wp_transition_finish (res, error); } /** - * wp_session_item_unexport: (virtual unexport) + * wp_session_item_unexport: * @self: the session item * * Reverses the effects of a previous call to wp_session_item_export(). @@ -747,9 +754,18 @@ void wp_session_item_unexport (WpSessionItem * self) { g_return_if_fail (WP_IS_SESSION_ITEM (self)); - g_return_if_fail (WP_SESSION_ITEM_GET_CLASS (self)->unexport); + + WpSessionItemPrivate *priv = wp_session_item_get_instance_private (self); + static const guint flags = 0xf0; /* all export flags */ //TODO cancel job if EXPORTING - WP_SESSION_ITEM_GET_CLASS (self)->unexport (self); + if (priv->flags & WP_SI_FLAG_EXPORTED && + WP_SESSION_ITEM_GET_CLASS (self)->export_rollback) + WP_SESSION_ITEM_GET_CLASS (self)->export_rollback (self); + + if (priv->flags & flags) { + priv->flags &= ~flags; + g_signal_emit (self, signals[SIGNAL_FLAGS_CHANGED], 0, priv->flags); + } } diff --git a/lib/wp/session-item.h b/lib/wp/session-item.h index e2617cf1..0f8f45dd 100644 --- a/lib/wp/session-item.h +++ b/lib/wp/session-item.h @@ -28,30 +28,42 @@ G_DECLARE_DERIVABLE_TYPE (WpSessionItem, wp_session_item, * WpSiFlags: * @WP_SI_FLAG_ACTIVATING: set when an activation transition is in progress * @WP_SI_FLAG_ACTIVE: set when an activation transition completes successfully - * @WP_SI_FLAG_IN_ERROR: set when there was an error in the activation process; - * to recover, the handler must call wp_session_item_reset() before anything - * else - * @WP_SI_FLAG_CONFIGURED: must be set by subclasses when all the required - * (%WP_SI_CONFIG_OPTION_REQUIRED) configuration options have been set + * @WP_SI_FLAG_ACTIVATE_ERROR: set when there was an error in the activation + * process; to clear, call wp_session_item_deactivate() * @WP_SI_FLAG_EXPORTING: set when an export operation is in progress * @WP_SI_FLAG_EXPORTED: set when the item has exported all necessary objects * to PipeWire + * @WP_SI_FLAG_EXPORT_ERROR: set when there was an error in the export + * process; to clear, call wp_session_item_unexport() + * @WP_SI_FLAG_CONFIGURED: must be set by subclasses when all the required + * (%WP_SI_CONFIG_OPTION_REQUIRED) configuration options have been set */ typedef enum { /* immutable flags, set internally */ WP_SI_FLAG_ACTIVATING = (1<<0), WP_SI_FLAG_ACTIVE = (1<<1), - WP_SI_FLAG_IN_ERROR = (1<<4), + WP_SI_FLAG_ACTIVATE_ERROR = (1<<2), + + WP_SI_FLAG_EXPORTING = (1<<4), + WP_SI_FLAG_EXPORTED = (1<<5), + WP_SI_FLAG_EXPORT_ERROR = (1<<6), /* flags that can be changed by subclasses */ WP_SI_FLAG_CONFIGURED = (1<<8), - WP_SI_FLAG_EXPORTING = (1<<9), - WP_SI_FLAG_EXPORTED = (1<<10), /* implementation-specific flags */ WP_SI_FLAG_CUSTOM_START = (1<<16), } WpSiFlags; +/** + * WP_SI_FLAGS_MASK_OPERATION_IN_PROGRESS: + * + * A #WpSiFlags mask that can be used to test if an async operation + * (activate or export) is currently in progress. + */ +#define WP_SI_FLAGS_MASK_OPERATION_IN_PROGRESS \ + (WP_SI_FLAG_ACTIVATING | WP_SI_FLAG_EXPORTING) + /** * WpSiConfigOptionFlags: * @WP_SI_CONFIG_OPTION_WRITEABLE: the option can be set externally @@ -68,14 +80,18 @@ typedef enum { * @get_associated_proxy: See wp_session_item_get_associated_proxy() * @configure: See wp_session_item_configure() * @get_configuration: See wp_session_item_get_configuration() - * @get_next_step: Implements #WpTransitionClass.get_next_step() for the - * transition of wp_session_item_activate() - * @execute_step: Implements #WpTransitionClass.execute_step() for the - * transition of wp_session_item_activate() - * @rollback: - * @export: See wp_session_item_export() - * @export_finish: See wp_session_item_export_finish() - * @unexport: See wp_session_item_unexport() + * @activate_get_next_step: Implements #WpTransitionClass.get_next_step() + * for the transition of wp_session_item_activate() + * @activate_execute_step: Implements #WpTransitionClass.execute_step() + * for the transition of wp_session_item_activate() + * @activate_rollback: Reverses any effects of the activation process; + * see wp_session_item_activate() + * @export_get_next_step: Implements #WpTransitionClass.get_next_step() + * for the transition of wp_session_item_export() + * @export_execute_step: Implements #WpTransitionClass.execute_step() + * for the transition of wp_session_item_export() + * @export_rollback: Reverses any effects of the export process; + * see wp_session_item_export() */ struct _WpSessionItemClass { @@ -88,18 +104,17 @@ struct _WpSessionItemClass gboolean (*configure) (WpSessionItem * self, GVariant * args); GVariant * (*get_configuration) (WpSessionItem * self); - guint (*get_next_step) (WpSessionItem * self, WpTransition * transition, - guint step); - void (*execute_step) (WpSessionItem * self, WpTransition * transition, - guint step); - void (*rollback) (WpSessionItem * self); - - void (*export) (WpSessionItem * self, - WpSession * session, GCancellable * cancellable, - GAsyncReadyCallback callback, gpointer callback_data); - gboolean (*export_finish) (WpSessionItem * self, GAsyncResult * res, - GError ** error); - void (*unexport) (WpSessionItem * self); + guint (*activate_get_next_step) (WpSessionItem * self, + WpTransition * transition, guint step); + void (*activate_execute_step) (WpSessionItem * self, + WpTransition * transition, guint step); + void (*activate_rollback) (WpSessionItem * self); + + guint (*export_get_next_step) (WpSessionItem * self, + WpTransition * transition, guint step); + void (*export_execute_step) (WpSessionItem * self, + WpTransition * transition, guint step); + void (*export_rollback) (WpSessionItem * self); }; WP_API diff --git a/modules/module-si-adapter.c b/modules/module-si-adapter.c index cd65e1da..0cd8d5b0 100644 --- a/modules/module-si-adapter.c +++ b/modules/module-si-adapter.c @@ -69,15 +69,6 @@ si_adapter_reset (WpSessionItem * item) g_clear_object (&self->node); } -static void -si_adapter_rollback (WpSessionItem * item) -{ - WpSiAdapter *self = WP_SI_ADAPTER (item); - - g_clear_object (&self->ports_om); - wp_session_item_clear_flag (item, WP_SI_FLAG_CONFIGURED); -} - static gpointer si_adapter_get_associated_proxy (WpSessionItem * item, GType proxy_type) { @@ -186,7 +177,7 @@ si_adapter_configure (WpSessionItem * item, GVariant * args) } static guint -si_adapter_get_next_step (WpSessionItem * item, +si_adapter_activate_get_next_step (WpSessionItem * item, WpTransition * transition, guint step) { switch (step) { @@ -270,8 +261,8 @@ on_ports_changed (WpObjectManager *om, WpTransition * transition) } static void -si_adapter_execute_step (WpSessionItem * item, WpTransition * transition, - guint step) +si_adapter_activate_execute_step (WpSessionItem * item, + WpTransition * transition, guint step) { WpSiAdapter *self = WP_SI_ADAPTER (item); @@ -356,6 +347,15 @@ si_adapter_execute_step (WpSessionItem * item, WpTransition * transition, } } +static void +si_adapter_activate_rollback (WpSessionItem * item) +{ + WpSiAdapter *self = WP_SI_ADAPTER (item); + + g_clear_object (&self->ports_om); + wp_session_item_clear_flag (item, WP_SI_FLAG_CONFIGURED); +} + static void si_adapter_class_init (WpSiAdapterClass * klass) { @@ -365,9 +365,9 @@ si_adapter_class_init (WpSiAdapterClass * klass) si_class->get_associated_proxy = si_adapter_get_associated_proxy; si_class->configure = si_adapter_configure; si_class->get_configuration = si_adapter_get_configuration; - si_class->get_next_step = si_adapter_get_next_step; - si_class->execute_step = si_adapter_execute_step; - si_class->rollback = si_adapter_rollback; + si_class->activate_get_next_step = si_adapter_activate_get_next_step; + si_class->activate_execute_step = si_adapter_activate_execute_step; + si_class->activate_rollback = si_adapter_activate_rollback; } static guint diff --git a/modules/module-si-standard-link.c b/modules/module-si-standard-link.c index 0e5249bb..a1531ce2 100644 --- a/modules/module-si-standard-link.c +++ b/modules/module-si-standard-link.c @@ -143,7 +143,7 @@ si_standard_link_configure (WpSessionItem * item, GVariant * args) } static guint -si_standard_link_get_next_step (WpSessionItem * item, +si_standard_link_activate_get_next_step (WpSessionItem * item, WpTransition * transition, guint step) { WpSiStandardLink *self = wp_transition_get_source_object (transition); @@ -320,8 +320,8 @@ create_links (WpSiStandardLink * self, GVariant * out_ports, GVariant * in_ports } static void -si_standard_link_execute_step (WpSessionItem * item, WpTransition * transition, - guint step) +si_standard_link_activate_execute_step (WpSessionItem * item, + WpTransition * transition, guint step) { WpSiStandardLink *self = WP_SI_STANDARD_LINK (item); @@ -379,7 +379,7 @@ si_standard_link_execute_step (WpSessionItem * item, WpTransition * transition, } static void -si_standard_link_rollback (WpSessionItem * item) +si_standard_link_activate_rollback (WpSessionItem * item) { WpSiStandardLink *self = WP_SI_STANDARD_LINK (item); WpSiEndpoint *out_endpoint, *in_endpoint; @@ -410,9 +410,9 @@ si_standard_link_class_init (WpSiStandardLinkClass * klass) si_class->reset = si_standard_link_reset; si_class->configure = si_standard_link_configure; si_class->get_configuration = si_standard_link_get_configuration; - si_class->get_next_step = si_standard_link_get_next_step; - si_class->execute_step = si_standard_link_execute_step; - si_class->rollback = si_standard_link_rollback; + si_class->activate_get_next_step = si_standard_link_activate_get_next_step; + si_class->activate_execute_step = si_standard_link_activate_execute_step; + si_class->activate_rollback = si_standard_link_activate_rollback; } static GVariant * diff --git a/tests/wp/session-item.c b/tests/wp/session-item.c index 7c2208d2..bcc638c1 100644 --- a/tests/wp/session-item.c +++ b/tests/wp/session-item.c @@ -58,7 +58,7 @@ si_dummy_configure (WpSessionItem * item, GVariant * args) } static guint -si_dummy_get_next_step (WpSessionItem * item, +si_dummy_activate_get_next_step (WpSessionItem * item, WpTransition * transition, guint step) { switch (step) { @@ -94,7 +94,7 @@ si_dummy_step_1 (gpointer data) } static void -si_dummy_execute_step (WpSessionItem * item, WpTransition * transition, +si_dummy_activate_execute_step (WpSessionItem * item, WpTransition * transition, guint step) { TestSiDummy *self = TEST_SI_DUMMY (item); @@ -117,7 +117,7 @@ si_dummy_execute_step (WpSessionItem * item, WpTransition * transition, } static void -si_dummy_rollback (WpSessionItem * item) +si_dummy_activate_rollback (WpSessionItem * item) { TestSiDummy *self = TEST_SI_DUMMY (item); @@ -133,9 +133,9 @@ si_dummy_class_init (TestSiDummyClass * klass) si_class->configure = si_dummy_configure; si_class->get_configuration = si_dummy_get_configuration; - si_class->get_next_step = si_dummy_get_next_step; - si_class->execute_step = si_dummy_execute_step; - si_class->rollback = si_dummy_rollback; + si_class->activate_get_next_step = si_dummy_activate_get_next_step; + si_class->activate_execute_step = si_dummy_activate_execute_step; + si_class->activate_rollback = si_dummy_activate_rollback; } static void @@ -159,11 +159,13 @@ test_flags (void) g_assert_cmpint (wp_session_item_get_flags (item), ==, WP_SI_FLAG_CUSTOM_START); g_assert_cmpint (signalled_flags, ==, WP_SI_FLAG_CUSTOM_START); - /* internal flag, cannot be set */ - signalled_flags = 0; - wp_session_item_set_flag (item, WP_SI_FLAG_ACTIVATING); - g_assert_cmpint (wp_session_item_get_flags (item), ==, WP_SI_FLAG_CUSTOM_START); - g_assert_cmpint (signalled_flags, ==, 0); + /* internal flags cannot be set */ + for (gint i = 0; i < 8; i++) { + signalled_flags = 0; + wp_session_item_set_flag (item, 1 << i); + g_assert_cmpint (wp_session_item_get_flags (item), ==, WP_SI_FLAG_CUSTOM_START); + g_assert_cmpint (signalled_flags, ==, 0); + } signalled_flags = WP_SI_FLAG_CUSTOM_START; wp_session_item_clear_flag (item, WP_SI_FLAG_CUSTOM_START); @@ -297,13 +299,15 @@ test_activation_error (void) g_main_loop_run (loop); g_assert_cmpint (wp_session_item_get_flags (item), ==, - WP_SI_FLAG_CONFIGURED | WP_SI_FLAG_IN_ERROR); + WP_SI_FLAG_ACTIVATE_ERROR | WP_SI_FLAG_CONFIGURED); g_assert_cmpint (signalled_flags, ==, - WP_SI_FLAG_CONFIGURED | WP_SI_FLAG_IN_ERROR); + WP_SI_FLAG_ACTIVATE_ERROR | WP_SI_FLAG_CONFIGURED); g_assert_false (dummy->step_1_done); g_assert_false (dummy->step_2_done); g_assert_true (dummy->cleaned_up); + /* deactivate should not call activate_rollback, + it should only clear the error flag */ dummy->cleaned_up = FALSE; wp_session_item_deactivate (item); -- GitLab