lfb-event: Notify state change before completing async task

lfb_event_trigger_feedback_async() internally uses a GTask to handle
invocation of the user provided callback when g_task_return_*() is
called.

Currently GTask is completed first and only afterwards is the state of
the event being updated which can lead to suprising behaviour in code
like this:

static void
on_event_triggered (LfbEvent     *event,
                    GAsyncResult *res,
                    CallsRinger  *self)
{
  g_autoptr (GError) err = NULL;
  gboolean ok;

  g_return_if_fail (LFB_IS_EVENT (event));

  ok = lfb_event_trigger_feedback_finish (event, res, &err);
  if (ok) {
    LfbEventState state = lfb_event_get_state (event);
    /* do something with state */
  }
}

In this case `state` would return a stale value that's about to get
changed. Instead it would be better to *first* change the state and only
afterwards complete the GTask.

This also makes the sync and async variants consistent in terms of when
they change the event state.

Closes: #59
This commit is contained in:
Evangelos Ribeiro Tzaras
2022-10-11 12:32:43 +02:00
parent 21399aec6e
commit 7391062b87
+2 -4
View File
@@ -150,7 +150,6 @@ on_trigger_feedback_finished (LfbGdbusFeedback *proxy,
LfbEvent *self = data->event; LfbEvent *self = data->event;
g_autoptr (GError) err = NULL; g_autoptr (GError) err = NULL;
gboolean success; gboolean success;
LfbEventState state;
g_return_if_fail (G_IS_TASK (task)); g_return_if_fail (G_IS_TASK (task));
g_return_if_fail (LFB_GDBUS_IS_FEEDBACK (proxy)); g_return_if_fail (LFB_GDBUS_IS_FEEDBACK (proxy));
@@ -160,16 +159,15 @@ on_trigger_feedback_finished (LfbGdbusFeedback *proxy,
&self->id, &self->id,
res, res,
&err); &err);
lfb_event_set_state (self, success ? LFB_EVENT_STATE_RUNNING : LFB_EVENT_STATE_ERRORED);
if (!success) { if (!success) {
g_task_return_error (task, g_steal_pointer (&err)); g_task_return_error (task, g_steal_pointer (&err));
state = LFB_EVENT_STATE_ERRORED;
} else { } else {
g_task_return_boolean (task, TRUE); g_task_return_boolean (task, TRUE);
state = LFB_EVENT_STATE_RUNNING;
_lfb_active_add_id (self->id); _lfb_active_add_id (self->id);
} }
lfb_event_set_state (self, state);
g_free (data); g_free (data);
g_object_unref (task); g_object_unref (task);
g_object_unref (self); g_object_unref (self);