wp: fix behavior of transitions before advanced for first time

wp_transition_get_completed incorrectly returns TRUE for transitions
that have not been advanced at least once, and hence are obviously not
completed.  This is because transitions start at STEP_NONE, and
completed transition is also indicated by STEP_NONE.

Fix this by adding a private flag to track whether transition was
started.

Fixes object managers sometimes missing object-changed events. How that
happens is the following:

- object activation transitions are advanced in idle callback
- they are aborted on registry global removal events
- registry global removal event can arrive before the idle callback
- wp_object_abort_activation uses wp_transition_get_completed to
  determine whether transition was completed, but it returned bogus
  values on transitions that hadn't been started.
This commit is contained in:
Pauli Virtanen 2022-03-05 23:08:07 +02:00
parent b95da3393c
commit 0a605f666c

View file

@ -65,6 +65,7 @@ struct _WpTransitionPrivate
GDestroyNotify data_destroy;
/* state machine */
gboolean started;
guint step;
GError *error;
};
@ -347,7 +348,7 @@ wp_transition_get_completed (WpTransition * self)
g_return_val_if_fail (WP_IS_TRANSITION (self), FALSE);
WpTransitionPrivate *priv = wp_transition_get_instance_private (self);
return priv->step == WP_TRANSITION_STEP_NONE ||
return (priv->step == WP_TRANSITION_STEP_NONE && priv->started) ||
priv->step == WP_TRANSITION_STEP_ERROR;
}
@ -426,6 +427,8 @@ wp_transition_advance (WpTransition * self)
guint next_step;
GError *error = NULL;
priv->started = TRUE;
if (g_cancellable_set_error_if_cancelled (priv->cancellable, &error)) {
wp_transition_return_error (self, error);
return;
@ -525,6 +528,10 @@ wp_transition_finish (GAsyncResult * res, GError ** error)
if (priv->error) {
g_propagate_error (error, priv->error);
priv->error = NULL;
} else if (!priv->started) {
priv->step = WP_TRANSITION_STEP_ERROR;
g_propagate_error (error, g_error_new (WP_DOMAIN_LIBRARY,
WP_LIBRARY_ERROR_INVARIANT, "finished before starting"));
}
wp_trace_object (priv->source_object, "transition: finished %s",