From 49dab605c29d0ab1f3d6cac3ac5dd6d2d4efed76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Fri, 29 May 2020 11:39:22 +0200 Subject: [PATCH] libfeedback: Cancel all running feedbacks on uninit We keep track of the active ids and end them on uninit. This make sure feedbacks don't continue to run if the application quits and forgets to end a feedback. --- libfeedback/lfb-event.c | 4 ++++ libfeedback/lfb-priv.h | 2 ++ libfeedback/libfeedback.c | 49 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+) diff --git a/libfeedback/lfb-event.c b/libfeedback/lfb-event.c index fd43b1a..9d34265 100644 --- a/libfeedback/lfb-event.c +++ b/libfeedback/lfb-event.c @@ -160,6 +160,7 @@ on_trigger_feedback_finished (LfbGdbusFeedback *proxy, } else { g_task_return_boolean (task, TRUE); state = LFB_EVENT_STATE_RUNNING; + _lfb_active_add_id (self->id); } lfb_event_set_state (self, state); @@ -363,6 +364,7 @@ on_feedback_ended (LfbEvent *self, lfb_event_set_end_reason (self, reason); lfb_event_set_state (self, LFB_EVENT_STATE_ENDED); g_signal_emit (self, signals[SIGNAL_FEEDBACK_ENDED], 0); + _lfb_active_remove_id (self->id); self->id = 0; g_signal_handler_disconnect (proxy, self->handler_id); self->handler_id = 0; @@ -412,6 +414,8 @@ lfb_event_trigger_feedback (LfbEvent *self, GError **error) &self->id, NULL, error); + if (success) + _lfb_active_add_id (self->id); lfb_event_set_state (self, success ? LFB_EVENT_STATE_RUNNING : LFB_EVENT_STATE_ERRORED); return success; } diff --git a/libfeedback/lfb-priv.h b/libfeedback/lfb-priv.h index b03fb0f..4ff2477 100644 --- a/libfeedback/lfb-priv.h +++ b/libfeedback/lfb-priv.h @@ -12,5 +12,7 @@ G_BEGIN_DECLS LfbGdbusFeedback *_lfb_get_proxy (void); +void _lfb_active_add_id (guint id); +void _lfb_active_remove_id (guint id); G_END_DECLS diff --git a/libfeedback/libfeedback.c b/libfeedback/libfeedback.c index 08dc8a8..7e8a946 100644 --- a/libfeedback/libfeedback.c +++ b/libfeedback/libfeedback.c @@ -40,6 +40,51 @@ static LfbGdbusFeedback *_proxy; static char *_app_id; static gboolean _initted; +static GHashTable *_active_ids; + +static void +lfb_cancel_feedbacks (void) +{ + gpointer key, value; + GHashTableIter iter; + + g_hash_table_iter_init (&iter, _active_ids); + + while (g_hash_table_iter_next (&iter, &key, &value)) { + guint id = GPOINTER_TO_UINT(key); + g_hash_table_iter_remove (&iter); + g_debug ("Cancellling feedback on shutdown %d", id); + /* Need to use a sync call here since there might not be a main loop anymore */ + lfb_gdbus_feedback_call_end_feedback_sync (_proxy, id, NULL, NULL); + } +} + +void +_lfb_active_add_id (guint id) +{ + g_return_if_fail (id > 0); + + if (!_initted) + return; + + g_hash_table_add (_active_ids, GUINT_TO_POINTER (id)); +} + +void +_lfb_active_remove_id (guint id) +{ + gboolean success; + + g_return_if_fail (id > 0); + + if (!_initted) + return; + + success = g_hash_table_remove (_active_ids, GUINT_TO_POINTER(id)); + if (!success) + g_warning ("Event id %d not known", id); +} + LfbGdbusFeedback * _lfb_get_proxy (void) @@ -73,6 +118,7 @@ lfb_init (const gchar *app_id, GError **error) if (!_proxy) return FALSE; + _active_ids = g_hash_table_new (g_direct_hash, g_direct_equal); g_object_add_weak_pointer (G_OBJECT (_proxy), (gpointer *) &_proxy); _initted = TRUE; @@ -90,6 +136,9 @@ lfb_uninit (void) { _initted = FALSE; + /* Cancel all feedbacks that the client forgot to clean up */ + lfb_cancel_feedbacks (); + g_clear_pointer (&_active_ids, g_hash_table_destroy); g_clear_pointer (&_app_id, g_free); g_clear_object (&_proxy); }