[evolution] Use GWeakRef when watching D-Bus bus names
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution] Use GWeakRef when watching D-Bus bus names
- Date: Thu, 21 Feb 2019 13:59:35 +0000 (UTC)
commit 07a2087169e31d9a6c1694ae59c7f1d354b8ef6b
Author: Milan Crha <mcrha redhat com>
Date: Thu Feb 21 14:56:38 2019 +0100
Use GWeakRef when watching D-Bus bus names
With certain operations interleaving the callback to name-appeared
signal could be called after the object in the user_data had been freed.
Even when the free of the object unwatches the D-Bus name, it's too
late, because the signal callback is already scheduled in the main loop.
Reported downstream at:
https://bugzilla.redhat.com/show_bug.cgi?id=1677846
src/modules/itip-formatter/itip-view.c | 105 +++++++++++++++++-----------
src/modules/webkit-editor/e-webkit-editor.c | 47 ++++++++++---
2 files changed, 104 insertions(+), 48 deletions(-)
---
diff --git a/src/modules/itip-formatter/itip-view.c b/src/modules/itip-formatter/itip-view.c
index fa255a992d..7849b8d9e9 100644
--- a/src/modules/itip-formatter/itip-view.c
+++ b/src/modules/itip-formatter/itip-view.c
@@ -1821,57 +1821,75 @@ itip_view_write_for_printing (ItipView *view,
static void
web_extension_proxy_created_cb (GDBusProxy *proxy,
GAsyncResult *result,
- ItipView *view)
+ GWeakRef *view_wr)
{
+ ItipView *view;
GError *error = NULL;
- view->priv->web_extension = g_dbus_proxy_new_finish (result, &error);
- if (!view->priv->web_extension) {
- g_warning ("Error creating web extension proxy: %s\n", error->message);
- g_error_free (error);
+ view = g_weak_ref_get (view_wr);
+
+ if (!view) {
+ e_weak_ref_free (view_wr);
+ return;
}
- view->priv->web_extension_source_changed_cb_signal_id =
- g_dbus_connection_signal_subscribe (
- g_dbus_proxy_get_connection (view->priv->web_extension),
- g_dbus_proxy_get_name (view->priv->web_extension),
- MODULE_ITIP_FORMATTER_WEB_EXTENSION_INTERFACE,
- "SourceChanged",
- MODULE_ITIP_FORMATTER_WEB_EXTENSION_OBJECT_PATH,
- NULL,
- G_DBUS_SIGNAL_FLAGS_NONE,
- source_changed_cb_signal_cb,
- view,
- NULL);
+ view->priv->web_extension = g_dbus_proxy_new_finish (result, &error);
+ if (!view->priv->web_extension) {
+ g_warning ("Error creating web extension proxy: %s\n", error ? error->message : "Unknown
error");
+ g_clear_error (&error);
+ } else {
+ view->priv->web_extension_source_changed_cb_signal_id =
+ g_dbus_connection_signal_subscribe (
+ g_dbus_proxy_get_connection (view->priv->web_extension),
+ g_dbus_proxy_get_name (view->priv->web_extension),
+ MODULE_ITIP_FORMATTER_WEB_EXTENSION_INTERFACE,
+ "SourceChanged",
+ MODULE_ITIP_FORMATTER_WEB_EXTENSION_OBJECT_PATH,
+ NULL,
+ G_DBUS_SIGNAL_FLAGS_NONE,
+ source_changed_cb_signal_cb,
+ view,
+ NULL);
+
+ view->priv->web_extension_recur_toggled_signal_id =
+ g_dbus_connection_signal_subscribe (
+ g_dbus_proxy_get_connection (view->priv->web_extension),
+ g_dbus_proxy_get_name (view->priv->web_extension),
+ MODULE_ITIP_FORMATTER_WEB_EXTENSION_INTERFACE,
+ "RecurToggled",
+ MODULE_ITIP_FORMATTER_WEB_EXTENSION_OBJECT_PATH,
+ NULL,
+ G_DBUS_SIGNAL_FLAGS_NONE,
+ (GDBusSignalCallback) recur_toggled_signal_cb,
+ view,
+ NULL);
- view->priv->web_extension_recur_toggled_signal_id =
- g_dbus_connection_signal_subscribe (
- g_dbus_proxy_get_connection (view->priv->web_extension),
- g_dbus_proxy_get_name (view->priv->web_extension),
- MODULE_ITIP_FORMATTER_WEB_EXTENSION_INTERFACE,
- "RecurToggled",
- MODULE_ITIP_FORMATTER_WEB_EXTENSION_OBJECT_PATH,
- NULL,
- G_DBUS_SIGNAL_FLAGS_NONE,
- (GDBusSignalCallback) recur_toggled_signal_cb,
- view,
+ e_util_invoke_g_dbus_proxy_call_with_error_check (
+ view->priv->web_extension,
+ "CreateDOMBindings",
+ g_variant_new ("(ts)", view->priv->page_id, view->priv->part_id),
NULL);
-
- e_util_invoke_g_dbus_proxy_call_with_error_check (
- view->priv->web_extension,
- "CreateDOMBindings",
- g_variant_new ("(ts)", view->priv->page_id, view->priv->part_id),
- NULL);
+ }
itip_view_init_view (view);
+
+ e_weak_ref_free (view_wr);
+ g_object_unref (view);
}
static void
web_extension_appeared_cb (GDBusConnection *connection,
const gchar *name,
const gchar *name_owner,
- ItipView *view)
+ GWeakRef *view_wr)
{
+ ItipView *view;
+
+ view = g_weak_ref_get (view_wr);
+
+ if (!view)
+ return;
+
g_dbus_proxy_new (
connection,
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START |
@@ -1883,15 +1901,24 @@ web_extension_appeared_cb (GDBusConnection *connection,
MODULE_ITIP_FORMATTER_WEB_EXTENSION_INTERFACE,
NULL,
(GAsyncReadyCallback)web_extension_proxy_created_cb,
- view);
+ e_weak_ref_new (view));
+
+ g_object_unref (view);
}
static void
web_extension_vanished_cb (GDBusConnection *connection,
const gchar *name,
- ItipView *view)
+ GWeakRef *view_wr)
{
- g_clear_object (&view->priv->web_extension);
+ ItipView *view;
+
+ view = g_weak_ref_get (view_wr);
+
+ if (view) {
+ g_clear_object (&view->priv->web_extension);
+ g_object_unref (view);
+ }
}
static void
@@ -1904,7 +1931,7 @@ itip_view_watch_web_extension (ItipView *view)
G_BUS_NAME_WATCHER_FLAGS_NONE,
(GBusNameAppearedCallback) web_extension_appeared_cb,
(GBusNameVanishedCallback) web_extension_vanished_cb,
- view, NULL);
+ e_weak_ref_new (view), (GDestroyNotify) e_weak_ref_free);
}
GDBusProxy *
diff --git a/src/modules/webkit-editor/e-webkit-editor.c b/src/modules/webkit-editor/e-webkit-editor.c
index 33af2bd663..5510608da3 100644
--- a/src/modules/webkit-editor/e-webkit-editor.c
+++ b/src/modules/webkit-editor/e-webkit-editor.c
@@ -530,14 +530,22 @@ dispatch_pending_operations (EWebKitEditor *wk_editor)
static void
web_extension_proxy_created_cb (GDBusProxy *proxy,
GAsyncResult *result,
- EWebKitEditor *wk_editor)
+ GWeakRef *wk_editor_rf)
{
+ EWebKitEditor *wk_editor;
GError *error = NULL;
+ wk_editor = g_weak_ref_get (wk_editor_rf);
+
+ if (!wk_editor) {
+ e_weak_ref_free (wk_editor_rf);
+ return;
+ }
+
wk_editor->priv->web_extension = g_dbus_proxy_new_finish (result, &error);
if (!wk_editor->priv->web_extension) {
- g_warning ("Error creating web extension proxy: %s\n", error->message);
- g_error_free (error);
+ g_warning ("Error creating web extension proxy: %s\n", error ? error->message : "Unknown
error");
+ g_clear_error (&error);
if (wk_editor->priv->initialized_callback) {
wk_editor->priv->initialized_callback (E_CONTENT_EDITOR (wk_editor),
wk_editor->priv->initialized_user_data);
@@ -546,6 +554,9 @@ web_extension_proxy_created_cb (GDBusProxy *proxy,
wk_editor->priv->initialized_user_data = NULL;
}
+ e_weak_ref_free (wk_editor_rf);
+ g_object_unref (wk_editor);
+
return;
}
@@ -628,14 +639,24 @@ web_extension_proxy_created_cb (GDBusProxy *proxy,
wk_editor->priv->initialized_callback = NULL;
wk_editor->priv->initialized_user_data = NULL;
}
+
+ e_weak_ref_free (wk_editor_rf);
+ g_object_unref (wk_editor);
}
static void
web_extension_appeared_cb (GDBusConnection *connection,
const gchar *name,
const gchar *name_owner,
- EWebKitEditor *wk_editor)
+ GWeakRef *wk_editor_wr)
{
+ EWebKitEditor *wk_editor;
+
+ wk_editor = g_weak_ref_get (wk_editor_wr);
+
+ if (!wk_editor)
+ return;
+
g_dbus_proxy_new (
connection,
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START |
@@ -646,15 +667,22 @@ web_extension_appeared_cb (GDBusConnection *connection,
E_WEBKIT_EDITOR_WEB_EXTENSION_INTERFACE,
NULL,
(GAsyncReadyCallback) web_extension_proxy_created_cb,
- wk_editor);
+ e_weak_ref_new (wk_editor));
+
+ g_object_unref (wk_editor);
}
static void
web_extension_vanished_cb (GDBusConnection *connection,
const gchar *name,
- EWebKitEditor *wk_editor)
+ GWeakRef *wk_editor_wr)
{
- g_return_if_fail (E_IS_WEBKIT_EDITOR (wk_editor));
+ EWebKitEditor *wk_editor;
+
+ wk_editor = g_weak_ref_get (wk_editor_wr);
+
+ if (!wk_editor)
+ return;
/* The vanished callback can be sometimes called before the appeared
callback, in which case it doesn't make sense to unwatch the name. */
@@ -666,6 +694,8 @@ web_extension_vanished_cb (GDBusConnection *connection,
wk_editor->priv->web_extension_watch_name_id = 0;
}
}
+
+ g_object_unref (wk_editor);
}
static void
@@ -682,8 +712,7 @@ webkit_editor_watch_web_extension (EWebKitEditor *wk_editor)
G_BUS_NAME_WATCHER_FLAGS_NONE,
(GBusNameAppearedCallback) web_extension_appeared_cb,
(GBusNameVanishedCallback) web_extension_vanished_cb,
- wk_editor,
- NULL);
+ e_weak_ref_new (wk_editor), (GDestroyNotify) e_weak_ref_free);
g_free (service_name);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]