summaryrefslogtreecommitdiff
path: root/client/gdaemonfilemonitor.c
diff options
context:
space:
mode:
authorWilliam Jon McCann <jmccann@redhat.com>2012-09-13 15:38:17 -0400
committerAlexander Larsson <alexl@redhat.com>2012-09-13 21:52:43 +0200
commitbe11520b5f6ad1d4ac95b2ba0cde18fbbbc26db6 (patch)
tree06d371a8a97571f10422b76a385908a27978784e /client/gdaemonfilemonitor.c
parentde93fcf03b7ca6f7a83e5a83cd1df05a83b7c2c7 (diff)
downloadgvfs-be11520b5f6ad1d4ac95b2ba0cde18fbbbc26db6.tar.gz
Try to unsubscribe from the proxy used for subscription
This makes cancel much cleaner and solves a problem where we were trying to use a previously disposed proxy. https://bugzilla.gnome.org/show_bug.cgi?id=683985
Diffstat (limited to 'client/gdaemonfilemonitor.c')
-rw-r--r--client/gdaemonfilemonitor.c159
1 files changed, 50 insertions, 109 deletions
diff --git a/client/gdaemonfilemonitor.c b/client/gdaemonfilemonitor.c
index ebf082c9..7e247bd5 100644
--- a/client/gdaemonfilemonitor.c
+++ b/client/gdaemonfilemonitor.c
@@ -47,6 +47,7 @@ struct _GDaemonFileMonitor
char *remote_obj_path;
char *remote_id;
GDBusConnection *connection;
+ GVfsDBusMonitor *proxy;
};
G_DEFINE_TYPE (GDaemonFileMonitor, g_daemon_file_monitor, G_TYPE_FILE_MONITOR)
@@ -58,6 +59,8 @@ g_daemon_file_monitor_finalize (GObject* object)
daemon_monitor = G_DAEMON_FILE_MONITOR (object);
+ g_clear_object (&daemon_monitor->proxy);
+
_g_dbus_unregister_vfs_filter (daemon_monitor->object_path);
g_clear_object (&daemon_monitor->connection);
@@ -65,7 +68,7 @@ g_daemon_file_monitor_finalize (GObject* object)
g_free (daemon_monitor->object_path);
g_free (daemon_monitor->remote_id);
g_free (daemon_monitor->remote_obj_path);
-
+
if (G_OBJECT_CLASS (g_daemon_file_monitor_parent_class)->finalize)
(*G_OBJECT_CLASS (g_daemon_file_monitor_parent_class)->finalize) (object);
}
@@ -156,27 +159,10 @@ g_daemon_file_monitor_init (GDaemonFileMonitor* daemon_monitor)
G_OBJECT (daemon_monitor));
}
-
-typedef void (*ProxyCreated) (GVfsDBusMonitor *proxy, gpointer user_data);
-
-typedef struct {
- GDaemonFileMonitor* monitor;
- ProxyCreated cb;
- GDBusConnection *connection;
-} AsyncProxyCreate;
-
-static void
-async_proxy_create_free (AsyncProxyCreate *data)
-{
- g_object_unref (data->monitor);
- g_clear_object (&data->connection);
- g_free (data);
-}
-
static void
subscribe_cb (GVfsDBusMonitor *proxy,
GAsyncResult *res,
- AsyncProxyCreate *data)
+ GDaemonFileMonitor* monitor)
{
GError *error = NULL;
@@ -186,34 +172,22 @@ subscribe_cb (GVfsDBusMonitor *proxy,
error->message, g_quark_to_string (error->domain), error->code);
g_error_free (error);
}
-
- /* monitor subscription successful, let's keep the connection open and listen for the changes */
- data->monitor->connection = g_object_ref (data->connection);
- _g_dbus_connect_vfs_filters (data->monitor->connection);
-
- async_proxy_create_free (data);
-}
-
-static void
-subscribe_proxy_created_cb (GVfsDBusMonitor *proxy,
- gpointer user_data)
-{
- AsyncProxyCreate *data = user_data;
- if (proxy == NULL)
+ /* If its cancelled already, unsubscribe and don't save stuff */
+ if (g_file_monitor_is_cancelled (G_FILE_MONITOR (monitor)))
{
- /* TODO: report an error? */
- async_proxy_create_free (data);
+ gvfs_dbus_monitor_call_unsubscribe (proxy,
+ monitor->object_path,
+ NULL, NULL, NULL);
+ g_clear_object (&monitor->connection);
+ g_object_unref (monitor);
return;
}
-
- gvfs_dbus_monitor_call_subscribe (proxy,
- data->monitor->object_path,
- NULL,
- (GAsyncReadyCallback) subscribe_cb,
- data);
-
- g_object_unref (proxy);
+
+ _g_dbus_connect_vfs_filters (monitor->connection);
+ monitor->proxy = g_object_ref (proxy);
+
+ g_object_unref (monitor);
}
static void
@@ -221,7 +195,7 @@ async_proxy_new_cb (GObject *source_object,
GAsyncResult *res,
gpointer user_data)
{
- AsyncProxyCreate *data = user_data;
+ GDaemonFileMonitor* monitor = user_data;
GVfsDBusMonitor *proxy;
GError *error = NULL;
@@ -231,9 +205,25 @@ async_proxy_new_cb (GObject *source_object,
g_printerr ("Error creating monitor proxy: %s (%s, %d)\n",
error->message, g_quark_to_string (error->domain), error->code);
g_error_free (error);
+ g_clear_object (&monitor->connection);
+ g_object_unref (monitor);
+ return;
}
-
- data->cb (proxy, data);
+
+ if (g_file_monitor_is_cancelled (G_FILE_MONITOR (monitor)))
+ {
+ g_clear_object (&monitor->connection);
+ g_object_unref (proxy);
+ g_object_unref (monitor);
+ return;
+ }
+
+ gvfs_dbus_monitor_call_subscribe (proxy,
+ monitor->object_path,
+ NULL,
+ (GAsyncReadyCallback) subscribe_cb,
+ monitor);
+ g_object_unref (proxy);
}
static void
@@ -241,24 +231,24 @@ async_got_connection_cb (GDBusConnection *connection,
GError *io_error,
gpointer callback_data)
{
- AsyncProxyCreate *data = callback_data;
+ GDaemonFileMonitor* monitor = callback_data;
if (! connection)
{
g_printerr ("Error getting connection for monitoring: %s (%s, %d)\n",
io_error->message, g_quark_to_string (io_error->domain), io_error->code);
- data->cb (NULL, data);
+ g_object_unref (monitor);
return;
}
- data->connection = g_object_ref (connection);
+ monitor->connection = g_object_ref (connection);
gvfs_dbus_monitor_proxy_new (connection,
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
- data->monitor->remote_id,
- data->monitor->remote_obj_path,
+ monitor->remote_id,
+ monitor->remote_obj_path,
NULL,
async_proxy_new_cb,
- data);
+ monitor);
}
GFileMonitor*
@@ -266,78 +256,29 @@ g_daemon_file_monitor_new (const char *remote_id,
const char *remote_obj_path)
{
GDaemonFileMonitor* daemon_monitor;
- AsyncProxyCreate *data;
-
+
daemon_monitor = g_object_new (G_TYPE_DAEMON_FILE_MONITOR, NULL);
daemon_monitor->remote_id = g_strdup (remote_id);
daemon_monitor->remote_obj_path = g_strdup (remote_obj_path);
- data = g_new0 (AsyncProxyCreate, 1);
- data->monitor = g_object_ref (daemon_monitor);
- data->cb = subscribe_proxy_created_cb;
-
_g_dbus_connection_get_for_async (daemon_monitor->remote_id,
async_got_connection_cb,
- data,
+ g_object_ref (daemon_monitor),
NULL);
-
- return G_FILE_MONITOR (daemon_monitor);
-}
-
-static void
-unsubscribe_cb (GVfsDBusMonitor *proxy,
- GAsyncResult *res,
- AsyncProxyCreate *data)
-{
- GError *error = NULL;
-
- if (! gvfs_dbus_monitor_call_unsubscribe_finish (proxy, res, &error))
- {
- g_printerr ("Error calling org.gtk.vfs.Monitor.Unsubscribe(): %s (%s, %d)\n",
- error->message, g_quark_to_string (error->domain), error->code);
- g_error_free (error);
- }
-
- async_proxy_create_free (data);
-}
-static void
-unsubscribe_proxy_created_cb (GVfsDBusMonitor *proxy,
- gpointer user_data)
-{
- AsyncProxyCreate *data = user_data;
-
- if (proxy == NULL)
- {
- /* Let's assume the target backend is gone already and there's nothing to cancel */
- async_proxy_create_free (data);
- return;
- }
-
- gvfs_dbus_monitor_call_unsubscribe (proxy,
- data->monitor->object_path,
- NULL,
- (GAsyncReadyCallback) unsubscribe_cb,
- data);
-
- g_object_unref (proxy);
+ return G_FILE_MONITOR (daemon_monitor);
}
static gboolean
g_daemon_file_monitor_cancel (GFileMonitor* monitor)
{
GDaemonFileMonitor *daemon_monitor = G_DAEMON_FILE_MONITOR (monitor);
- AsyncProxyCreate *data;
-
- data = g_new0 (AsyncProxyCreate, 1);
- data->monitor = g_object_ref (daemon_monitor);
- data->cb = unsubscribe_proxy_created_cb;
-
- _g_dbus_connection_get_for_async (daemon_monitor->remote_id,
- async_got_connection_cb,
- data,
- NULL);
+
+ if (daemon_monitor->proxy != NULL)
+ gvfs_dbus_monitor_call_unsubscribe (daemon_monitor->proxy,
+ daemon_monitor->object_path,
+ NULL, NULL, NULL);
return TRUE;
}