[evolution] EActivityBar: Unset timeout_id without recursive call to g_source_remove()
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution] EActivityBar: Unset timeout_id without recursive call to g_source_remove()
- Date: Wed, 22 Apr 2020 13:23:32 +0000 (UTC)
commit 436ec5bd00a6e0095dc1fdb2a820fe020808d26b
Author: Milan Crha <mcrha redhat com>
Date: Wed Apr 22 15:24:32 2020 +0200
EActivityBar: Unset timeout_id without recursive call to g_source_remove()
That could happen with e_activity_bar_set_activity() being called when
the timeout_id is set and when the activity in question had the last
reference help by the timeout source, because it caused a repeated call
of e_activity_base_set_activity() in the destroy callback on the activity.
src/e-util/e-activity-bar.c | 34 ++++++++++++++++++++++------------
1 file changed, 22 insertions(+), 12 deletions(-)
---
diff --git a/src/e-util/e-activity-bar.c b/src/e-util/e-activity-bar.c
index e3cf5c9134..2cd53e5dfc 100644
--- a/src/e-util/e-activity-bar.c
+++ b/src/e-util/e-activity-bar.c
@@ -61,6 +61,25 @@ typedef struct _EActivityBarTimeoutData {
EActivity *activity;
} EActivityBarTimeoutData;
+/* This is needed, because the scheduled timeout can hold the last
+ reference to the 'activity', which means removing the source will
+ free it, which in turn calls e_activity_bar_set_activity() with NULL,
+ which would call g_source_remove() again, with the same timeout id.
+*/
+static void
+activity_bar_unset_timeout_id (EActivityBar *bar)
+{
+ guint timeout_id;
+
+ g_return_if_fail (E_IS_ACTIVITY_BAR (bar));
+
+ timeout_id = bar->priv->timeout_id;
+ bar->priv->timeout_id = 0;
+
+ if (timeout_id)
+ g_source_remove (timeout_id);
+}
+
static void
activity_bar_timeout_data_free (gpointer ptr)
{
@@ -101,8 +120,7 @@ activity_bar_feedback (EActivityBar *bar)
if (state != E_ACTIVITY_CANCELLED && state != E_ACTIVITY_COMPLETED)
return;
- if (bar->priv->timeout_id > 0)
- g_source_remove (bar->priv->timeout_id);
+ activity_bar_unset_timeout_id (bar);
data = g_slice_new0 (EActivityBarTimeoutData);
@@ -267,12 +285,7 @@ activity_bar_dispose (GObject *object)
priv = E_ACTIVITY_BAR_GET_PRIVATE (object);
- if (priv->timeout_id > 0) {
- guint timeout_id = priv->timeout_id;
-
- priv->timeout_id = 0;
- g_source_remove (timeout_id);
- }
+ activity_bar_unset_timeout_id (E_ACTIVITY_BAR (object));
if (priv->activity != NULL) {
g_signal_handlers_disconnect_matched (
@@ -388,10 +401,7 @@ e_activity_bar_set_activity (EActivityBar *bar,
if (activity != NULL)
g_return_if_fail (E_IS_ACTIVITY (activity));
- if (bar->priv->timeout_id > 0) {
- g_source_remove (bar->priv->timeout_id);
- bar->priv->timeout_id = 0;
- }
+ activity_bar_unset_timeout_id (bar);
if (bar->priv->activity != NULL) {
g_signal_handlers_disconnect_matched (
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]