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
This commit is contained in:
George Kiagiadakis 2020-04-16 17:38:31 +03:00
parent 441a778b2e
commit 49b63b6045
6 changed files with 212 additions and 178 deletions

View file

@ -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;

View file

@ -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.
*
* 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 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.
*
* 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);
}
}

View file

@ -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);
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);
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 (*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

View file

@ -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

View file

@ -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 *

View file

@ -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);