From 7391062b87629de02c98f1b64be841a1ebbdeda9 Mon Sep 17 00:00:00 2001 From: Evangelos Ribeiro Tzaras Date: Thu, 15 Sep 2022 16:52:59 +0200 Subject: [PATCH] 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 --- libfeedback/lfb-event.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/libfeedback/lfb-event.c b/libfeedback/lfb-event.c index 875f821..6dcbf21 100644 --- a/libfeedback/lfb-event.c +++ b/libfeedback/lfb-event.c @@ -150,7 +150,6 @@ on_trigger_feedback_finished (LfbGdbusFeedback *proxy, LfbEvent *self = data->event; g_autoptr (GError) err = NULL; gboolean success; - LfbEventState state; g_return_if_fail (G_IS_TASK (task)); g_return_if_fail (LFB_GDBUS_IS_FEEDBACK (proxy)); @@ -160,16 +159,15 @@ on_trigger_feedback_finished (LfbGdbusFeedback *proxy, &self->id, res, &err); + + lfb_event_set_state (self, success ? LFB_EVENT_STATE_RUNNING : LFB_EVENT_STATE_ERRORED); if (!success) { g_task_return_error (task, g_steal_pointer (&err)); - state = LFB_EVENT_STATE_ERRORED; } else { g_task_return_boolean (task, TRUE); - state = LFB_EVENT_STATE_RUNNING; _lfb_active_add_id (self->id); } - lfb_event_set_state (self, state); g_free (data); g_object_unref (task); g_object_unref (self);