summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
authorTomas Bzatek <tbzatek@redhat.com>2012-07-31 11:58:09 +0200
committerTomas Bzatek <tbzatek@redhat.com>2012-07-31 11:58:09 +0200
commit622a5c0d167556188c38fcde40a42a0dfad9c625 (patch)
tree04f27be7f2a54779e17029ede2554e39c3464aa0 /client
parenta494b809eaf82994108bfbbe5d950fed1a0a8c7c (diff)
downloadgvfs-622a5c0d167556188c38fcde40a42a0dfad9c625.tar.gz
gdbus: Core daemon and client port
Port of most of the gvfs core, few bits still missing. Lot of debug prints around, will be removed in further commits. Same amount of TODOs and FIXMEs. Notes: * kill serials? * get rid of mainloops where applicable (copy/move progress callback, enumerator) * fix keyring integration * use gdbus builtin fd passing within gvfsdaemon.c, kill the extra_fd stuff
Diffstat (limited to 'client')
-rw-r--r--client/gdaemonfile.c3171
-rw-r--r--client/gdaemonfileenumerator.c317
-rw-r--r--client/gdaemonfileenumerator.h3
-rw-r--r--client/gdaemonmount.c198
-rw-r--r--client/gdaemonvfs.c399
-rw-r--r--client/gdaemonvfs.h7
-rw-r--r--client/gvfsdaemondbus.c885
-rw-r--r--client/gvfsdaemondbus.h41
8 files changed, 2579 insertions, 2442 deletions
diff --git a/client/gdaemonfile.c b/client/gdaemonfile.c
index 27e86950..bc0afbe3 100644
--- a/client/gdaemonfile.c
+++ b/client/gdaemonfile.c
@@ -38,11 +38,12 @@
#include <gdaemonfilemonitor.h>
#include <gdaemonfileenumerator.h>
#include <glib/gi18n-lib.h>
-#include "gvfsdbusutils.h"
#include "gmountoperationdbus.h"
#include <gio/gio.h>
#include "metatree.h"
#include <metadata-dbus.h>
+#include <gvfsdbus.h>
+#include <gio/gunixfdlist.h>
static void g_daemon_file_file_iface_init (GFileIface *iface);
@@ -179,6 +180,7 @@ g_daemon_file_get_path (GFile *file)
mount_info = _g_daemon_vfs_get_mount_info_sync (daemon_file->mount_spec,
daemon_file->path,
+ NULL, /* TODO: cancellable */
NULL);
if (mount_info == NULL)
@@ -370,210 +372,130 @@ g_daemon_file_resolve_relative_path (GFile *file,
return child;
}
-static DBusMessage *
-create_empty_message (GFile *file,
- const char *op,
- GMountInfo **mount_info_out,
- GError **error)
-{
- GDaemonFile *daemon_file = G_DAEMON_FILE (file);
- DBusMessage *message;
- GMountInfo *mount_info;
- const char *path;
-
- mount_info = _g_daemon_vfs_get_mount_info_sync (daemon_file->mount_spec,
- daemon_file->path,
- error);
- if (mount_info == NULL)
- return NULL;
-
- if (mount_info_out)
- *mount_info_out = g_mount_info_ref (mount_info);
-
- message =
- dbus_message_new_method_call (mount_info->dbus_id,
- mount_info->object_path,
- G_VFS_DBUS_MOUNT_INTERFACE,
- op);
-
- path = g_mount_info_resolve_path (mount_info,
- daemon_file->path);
- _g_dbus_message_append_args (message, G_DBUS_TYPE_CSTRING, &path, 0);
-
- g_mount_info_unref (mount_info);
- return message;
-}
-
-static DBusMessage *
-do_sync_path_call (GFile *file,
- const char *op,
- GMountInfo **mount_info_out,
- DBusConnection **connection_out,
- GCancellable *cancellable,
- GError **error,
- int first_arg_type,
- ...)
-{
- DBusMessage *message, *reply;
- va_list var_args;
- GError *my_error;
-
- retry:
-
- message = create_empty_message (file, op, mount_info_out, error);
- if (!message)
- return NULL;
-
- va_start (var_args, first_arg_type);
- _g_dbus_message_append_args_valist (message,
- first_arg_type,
- var_args);
- va_end (var_args);
-
-
- my_error = NULL;
- reply = _g_vfs_daemon_call_sync (message,
- connection_out,
- NULL, NULL, NULL,
- cancellable, &my_error);
- dbus_message_unref (message);
-
- if (reply == NULL)
- {
- if (g_error_matches (my_error, G_VFS_ERROR, G_VFS_ERROR_RETRY))
- {
- g_error_free (my_error);
- goto retry;
- }
- g_propagate_error (error, my_error);
- }
-
- return reply;
-}
-
-static DBusMessage *
-do_sync_2_path_call (GFile *file1,
- GFile *file2,
- const char *op,
- const char *callback_obj_path,
- DBusObjectPathMessageFunction callback,
- gpointer callback_user_data,
- DBusConnection **connection_out,
- GCancellable *cancellable,
- GError **error,
- int first_arg_type,
- ...)
+static GVfsDBusMount *
+create_proxy_for_file2 (GFile *file1,
+ GFile *file2,
+ GMountInfo **mount_info1_out,
+ GMountInfo **mount_info2_out,
+ gchar **path1_out,
+ gchar **path2_out,
+ GDBusConnection **connection_out,
+ GCancellable *cancellable,
+ GError **error)
{
+ GVfsDBusMount *proxy;
GDaemonFile *daemon_file1 = G_DAEMON_FILE (file1);
GDaemonFile *daemon_file2 = G_DAEMON_FILE (file2);
- DBusMessage *message, *reply;
GMountInfo *mount_info1, *mount_info2;
- const char *path1, *path2;
- va_list var_args;
- GError *my_error;
+ GDBusConnection *connection;
- retry:
+ proxy = NULL;
+ mount_info2 = NULL;
mount_info1 = _g_daemon_vfs_get_mount_info_sync (daemon_file1->mount_spec,
- daemon_file1->path,
- error);
+ daemon_file1->path,
+ cancellable,
+ error);
+
if (mount_info1 == NULL)
- return NULL;
+ goto out;
- mount_info2 = NULL;
if (daemon_file2)
{
mount_info2 = _g_daemon_vfs_get_mount_info_sync (daemon_file2->mount_spec,
- daemon_file2->path,
- error);
+ daemon_file2->path,
+ cancellable,
+ error);
if (mount_info2 == NULL)
- {
- g_mount_info_unref (mount_info1);
- return NULL;
- }
+ goto out;
- if (mount_info1 != mount_info2)
- {
- g_mount_info_unref (mount_info1);
- /* For copy this will cause the fallback code to be involved */
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
- _("Operation not supported, files on different mounts"));
- return NULL;
- }
+ if (! g_mount_info_equal (mount_info1, mount_info2))
+ {
+ /* For copy this will cause the fallback code to be involved */
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+ _("Operation not supported, files on different mounts"));
+ goto out;
+ }
}
-
- message =
- dbus_message_new_method_call (mount_info1->dbus_id,
- mount_info1->object_path,
- G_VFS_DBUS_MOUNT_INTERFACE,
- op);
- path1 = g_mount_info_resolve_path (mount_info1,
- daemon_file1->path);
- _g_dbus_message_append_args (message, G_DBUS_TYPE_CSTRING, &path1, 0);
+ connection = _g_dbus_connection_get_sync (mount_info1->dbus_id, cancellable, error);
+ if (connection == NULL)
+ goto out;
- if (daemon_file2)
- {
- path2 = g_mount_info_resolve_path (mount_info2,
- daemon_file2->path);
- _g_dbus_message_append_args (message, G_DBUS_TYPE_CSTRING, &path2, 0);
- }
+ proxy = gvfs_dbus_mount_proxy_new_sync (connection,
+ G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
+ mount_info1->dbus_id,
+ mount_info1->object_path,
+ cancellable,
+ error);
- va_start (var_args, first_arg_type);
- _g_dbus_message_append_args_valist (message,
- first_arg_type,
- var_args);
- va_end (var_args);
+ if (proxy == NULL)
+ goto out;
+
+ _g_dbus_connect_vfs_filters (connection);
- my_error = NULL;
- reply = _g_vfs_daemon_call_sync (message,
- connection_out,
- callback_obj_path,
- callback,
- callback_user_data,
- cancellable, &my_error);
- dbus_message_unref (message);
+ if (mount_info1_out)
+ *mount_info1_out = g_mount_info_ref (mount_info1);
+ if (mount_info2_out && mount_info2)
+ *mount_info2_out = g_mount_info_ref (mount_info2);
+ if (path1_out)
+ *path1_out = g_strdup (g_mount_info_resolve_path (mount_info1, daemon_file1->path));
+ if (path2_out && mount_info2)
+ *path2_out = g_strdup (g_mount_info_resolve_path (mount_info2, daemon_file2->path));
+ if (connection_out)
+ *connection_out = connection;
+ out:
g_mount_info_unref (mount_info1);
if (mount_info2)
g_mount_info_unref (mount_info2);
+
+ return proxy;
+}
- if (reply == NULL)
- {
- if (g_error_matches (my_error, G_VFS_ERROR, G_VFS_ERROR_RETRY))
- {
- g_error_free (my_error);
- goto retry;
- }
- g_propagate_error (error, my_error);
- }
-
- return reply;
+static GVfsDBusMount *
+create_proxy_for_file (GFile *file,
+ GMountInfo **mount_info_out,
+ gchar **path_out,
+ GDBusConnection **connection_out,
+ GCancellable *cancellable,
+ GError **error)
+{
+ return create_proxy_for_file2 (file, NULL,
+ mount_info_out, NULL,
+ path_out, NULL,
+ connection_out,
+ cancellable,
+ error);
}
-typedef void (*AsyncPathCallCallback) (DBusMessage *reply,
- DBusConnection *connection,
- GMountInfo *mount_info,
- GSimpleAsyncResult *result,
- GCancellable *cancellable,
- gpointer callback_data);
+typedef void (*CreateProxyAsyncCallback) (GVfsDBusMount *proxy,
+ GDBusConnection *connection,
+ GMountInfo *mount_info,
+ const gchar *path,
+ GSimpleAsyncResult *result,
+ GError *error,
+ GCancellable *cancellable,
+ gpointer callback_data);
typedef struct {
GSimpleAsyncResult *result;
GFile *file;
char *op;
GCancellable *cancellable;
- DBusMessage *args;
- AsyncPathCallCallback callback;
+ CreateProxyAsyncCallback callback;
gpointer callback_data;
GDestroyNotify notify;
GMountInfo *mount_info;
-} AsyncPathCall;
+ GDBusConnection *connection;
+ GVfsDBusMount *proxy;
+} AsyncProxyCreate;
static void
-async_path_call_free (AsyncPathCall *data)
+async_proxy_create_free (AsyncProxyCreate *data)
{
+ g_print ("async_proxy_create_free\n");
if (data->notify)
data->notify (data->callback_data);
@@ -583,144 +505,176 @@ async_path_call_free (AsyncPathCall *data)
g_free (data->op);
if (data->cancellable)
g_object_unref (data->cancellable);
- if (data->args)
- dbus_message_unref (data->args);
if (data->mount_info)
g_mount_info_unref (data->mount_info);
+ if (data->connection)
+ g_object_unref (data->connection);
+ if (data->proxy)
+ g_object_unref (data->proxy);
g_free (data);
}
static void
-async_path_call_done (DBusMessage *reply,
- DBusConnection *connection,
- GError *io_error,
- gpointer _data)
+async_proxy_new_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
{
- AsyncPathCall *data = _data;
+ AsyncProxyCreate *data = user_data;
+ GDaemonFile *daemon_file = G_DAEMON_FILE (data->file);
+ const char *path;
+ GVfsDBusMount *proxy;
+ GError *error = NULL;
GSimpleAsyncResult *result;
-
- if (io_error != NULL)
+
+ proxy = gvfs_dbus_mount_proxy_new_finish (res, &error);
+ g_print ("async_proxy_new_cb, proxy = %p\n", proxy);
+ if (proxy == NULL)
{
- g_simple_async_result_set_from_error (data->result, io_error);
+ g_simple_async_result_take_error (data->result, error);
_g_simple_async_result_complete_with_cancellable (data->result, data->cancellable);
- async_path_call_free (data);
- }
- else
- {
- result = data->result;
- g_object_weak_ref (G_OBJECT (result), (GWeakNotify)async_path_call_free, data);
- data->result = NULL;
-
- data->callback (reply,
- connection,
- data->mount_info,
- result,
- data->cancellable,
- data->callback_data);
-
- /* Free data here, or later if callback ref:ed the result */
- g_object_unref (result);
+ async_proxy_create_free (data);
+ return;
}
+
+ data->proxy = proxy;
+ _g_dbus_connect_vfs_filters (data->connection);
+ path = g_mount_info_resolve_path (data->mount_info, daemon_file->path);
+
+ /* Complete the create_proxy_for_file_async() call */
+ result = data->result;
+ g_object_weak_ref (G_OBJECT (result), (GWeakNotify)async_proxy_create_free, data);
+ data->result = NULL;
+
+ data->callback (proxy,
+ data->connection,
+ data->mount_info,
+ path,
+ result,
+ NULL,
+ data->cancellable,
+ data->callback_data);
+
+ /* Free data here, or later if callback ref:ed the result */
+ g_object_unref (result);
}
static void
-do_async_path_call_callback (GMountInfo *mount_info,
- gpointer _data,
- GError *error)
+async_construct_proxy (GDBusConnection *connection,
+ AsyncProxyCreate *data)
{
- AsyncPathCall *data = _data;
- GDaemonFile *daemon_file = G_DAEMON_FILE (data->file);
- const char *path;
- DBusMessage *message;
- DBusMessageIter arg_source, arg_dest;
+ data->connection = g_object_ref (connection);
+ gvfs_dbus_mount_proxy_new (connection,
+ G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
+ data->mount_info->dbus_id,
+ data->mount_info->object_path,
+ data->cancellable,
+ async_proxy_new_cb,
+ data);
+}
+
+static void
+bus_get_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ AsyncProxyCreate *data = user_data;
+ GDBusConnection *connection;
+ GError *error = NULL;
- if (error != NULL)
+ connection = g_bus_get_finish (res, &error);
+
+ if (connection == NULL)
{
- g_simple_async_result_set_from_error (data->result, error);
+ g_simple_async_result_set_from_error (data->result, error);
_g_simple_async_result_complete_with_cancellable (data->result, data->cancellable);
- async_path_call_free (data);
+ async_proxy_create_free (data);
return;
}
- data->mount_info = g_mount_info_ref (mount_info);
+ async_construct_proxy (connection, data);
+}
- message =
- dbus_message_new_method_call (mount_info->dbus_id,
- mount_info->object_path,
- G_VFS_DBUS_MOUNT_INTERFACE,
- data->op);
+static void
+async_got_connection_cb (GDBusConnection *connection,
+ GError *io_error,
+ gpointer callback_data)
+{
+ AsyncProxyCreate *data = callback_data;
+
+ g_print ("async_got_connection_cb, connection = %p\n", connection);
- path = g_mount_info_resolve_path (mount_info, daemon_file->path);
- _g_dbus_message_append_args (message, G_DBUS_TYPE_CSTRING, &path, 0);
+ if (connection == NULL)
+ {
+ /* TODO: we should probably test if we really want a session bus;
+ * for now, this code is on par with the old dbus code */
+ g_bus_get (G_BUS_TYPE_SESSION,
+ data->cancellable,
+ bus_get_cb,
+ data);
+ return;
+ }
+
+ async_construct_proxy (connection, data);
+}
- /* Append more args from data->args */
+static void
+async_got_mount_info (GMountInfo *mount_info,
+ gpointer _data,
+ GError *error)
+{
+ AsyncProxyCreate *data = _data;
+
+ g_print ("async_got_mount_info, mount_info = %p\n", mount_info);
- if (data->args)
+ if (error != NULL)
{
- dbus_message_iter_init (data->args, &arg_source);
- dbus_message_iter_init_append (message, &arg_dest);
-
- _g_dbus_message_iter_copy (&arg_dest, &arg_source);
+ g_simple_async_result_set_from_error (data->result, error);
+ _g_simple_async_result_complete_with_cancellable (data->result, data->cancellable);
+ async_proxy_create_free (data);
+ return;
}
- _g_vfs_daemon_call_async (message,
- async_path_call_done, data,
- data->cancellable);
-
- dbus_message_unref (message);
+ data->mount_info = g_mount_info_ref (mount_info);
+
+ _g_dbus_connection_get_for_async (mount_info->dbus_id,
+ async_got_connection_cb,
+ data,
+ data->cancellable);
}
static void
-do_async_path_call (GFile *file,
- const char *op,
- GCancellable *cancellable,
- GAsyncReadyCallback op_callback,
- gpointer op_callback_data,
- AsyncPathCallCallback callback,
- gpointer callback_data,
- GDestroyNotify notify,
- int first_arg_type,
- ...)
+create_proxy_for_file_async (GFile *file,
+ GCancellable *cancellable,
+ GAsyncReadyCallback op_callback,
+ gpointer op_callback_data,
+ CreateProxyAsyncCallback callback,
+ gpointer callback_data,
+ GDestroyNotify notify)
{
GDaemonFile *daemon_file = G_DAEMON_FILE (file);
- va_list var_args;
- AsyncPathCall *data;
+ AsyncProxyCreate *data;
- data = g_new0 (AsyncPathCall, 1);
+ g_print ("create_proxy_for_file_async\n");
+
+ data = g_new0 (AsyncProxyCreate, 1);
data->result = g_simple_async_result_new (G_OBJECT (file),
- op_callback, op_callback_data,
- NULL);
+ op_callback, op_callback_data,
+ NULL);
data->file = g_object_ref (file);
- data->op = g_strdup (op);
if (cancellable)
data->cancellable = g_object_ref (cancellable);
data->callback = callback;
data->callback_data = callback_data;
data->notify = notify;
- if (first_arg_type != 0)
- {
- data->args = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_CALL);
- if (data->args == NULL)
- _g_dbus_oom ();
-
- va_start (var_args, first_arg_type);
- _g_dbus_message_append_args_valist (data->args,
- first_arg_type,
- var_args);
- va_end (var_args);
- }
-
-
_g_daemon_vfs_get_mount_info_async (daemon_file->mount_spec,
- daemon_file->path,
- do_async_path_call_callback,
- data);
+ daemon_file->path,
+ async_got_mount_info,
+ data);
}
-
static GFileEnumerator *
g_daemon_file_enumerate_children (GFile *file,
const char *attributes,
@@ -728,47 +682,51 @@ g_daemon_file_enumerate_children (GFile *file,
GCancellable *cancellable,
GError **error)
{
- DBusMessage *reply;
- dbus_uint32_t flags_dbus;
char *obj_path;
+ char *path;
GDaemonFileEnumerator *enumerator;
- DBusConnection *connection;
+ GDBusConnection *connection;
char *uri;
-
+ GVfsDBusMount *proxy;
+ gboolean res;
+
+ g_print ("g_daemon_file_enumerate_children\n");
+
enumerator = g_daemon_file_enumerator_new (file, attributes);
- obj_path = g_daemon_file_enumerator_get_object_path (enumerator);
-
+ proxy = create_proxy_for_file (file, NULL, &path, &connection, cancellable, error);
+ if (proxy == NULL)
+ goto out;
+
+ obj_path = g_daemon_file_enumerator_get_object_path (enumerator);
uri = g_file_get_uri (file);
+
+ res = gvfs_dbus_mount_call_enumerate_sync (proxy,
+ path,
+ obj_path,
+ attributes ? attributes : "",
+ flags,
+ uri,
+ cancellable,
+ error);
+
+ g_print ("g_daemon_file_enumerate_children: done, res = %d\n", res);
- if (attributes == NULL)
- attributes = "";
- flags_dbus = flags;
- reply = do_sync_path_call (file,
- G_VFS_DBUS_MOUNT_OP_ENUMERATE,
- NULL, &connection,
- cancellable, error,
- DBUS_TYPE_STRING, &obj_path,
- DBUS_TYPE_STRING, &attributes,
- DBUS_TYPE_UINT32, &flags_dbus,
- DBUS_TYPE_STRING, &uri,
- 0);
+ g_free (path);
g_free (uri);
g_free (obj_path);
+ g_object_unref (proxy);
- if (reply == NULL)
- goto error;
-
- dbus_message_unref (reply);
-
+ if (! res)
+ goto out;
+
g_daemon_file_enumerator_set_sync_connection (enumerator, connection);
return G_FILE_ENUMERATOR (enumerator);
-
- error:
- if (reply)
- dbus_message_unref (reply);
- g_object_unref (enumerator);
+
+out:
+ if (enumerator != NULL)
+ g_object_unref (enumerator);
return NULL;
}
@@ -843,94 +801,143 @@ g_daemon_file_query_info (GFile *file,
GCancellable *cancellable,
GError **error)
{
- DBusMessage *reply;
- dbus_uint32_t flags_dbus;
- DBusMessageIter iter;
+ char *path;
GFileInfo *info;
char *uri;
+ GVfsDBusMount *proxy;
+ GVariant *iter_info;
+ gboolean res;
+
+ g_print ("g_daemon_file_query_info\n");
+
+ proxy = create_proxy_for_file (file, NULL, &path, NULL, cancellable, error);
+ if (proxy == NULL)
+ return NULL;
uri = g_file_get_uri (file);
- if (attributes == NULL)
- attributes = "";
- flags_dbus = flags;
- reply = do_sync_path_call (file,
- G_VFS_DBUS_MOUNT_OP_QUERY_INFO,
- NULL, NULL,
- cancellable, error,
- DBUS_TYPE_STRING, &attributes,
- DBUS_TYPE_UINT32, &flags_dbus,
- DBUS_TYPE_STRING, &uri,
- 0);
+ iter_info = NULL;
+ res = gvfs_dbus_mount_call_query_info_sync (proxy,
+ path,
+ attributes ? attributes : "",
+ flags,
+ uri,
+ &iter_info,
+ cancellable,
+ error);
+
+ g_print ("g_daemon_file_query_info: done, res = %d\n", res);
+ g_free (path);
g_free (uri);
-
- if (reply == NULL)
- return NULL;
+ g_object_unref (proxy);
- info = NULL;
-
- if (!dbus_message_iter_init (reply, &iter) ||
- (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRUCT))
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- /* Translators: %s is the name of a programming function */
- _("Invalid return value from %s"), "get_info");
- goto out;
- }
+ if (! res)
+ return NULL;
- info = _g_dbus_get_file_info (&iter, error);
+ info = _g_dbus_get_file_info (iter_info, error);
+ g_variant_unref (iter_info);
if (info)
add_metadata (file, attributes, info);
-
- out:
- dbus_message_unref (reply);
+
return info;
}
+
+typedef struct {
+ GFile *file;
+ char *attributes;
+ GFileQueryInfoFlags flags;
+ int io_priority;
+ GSimpleAsyncResult *result;
+ GCancellable *cancellable;
+} AsyncCallQueryInfo;
+
static void
-query_info_async_cb (DBusMessage *reply,
- DBusConnection *connection,
- GMountInfo *mount_info,
- GSimpleAsyncResult *result,
- GCancellable *cancellable,
- gpointer callback_data)
+async_call_query_info_free (AsyncCallQueryInfo *data)
{
- const char *attributes = callback_data;
- DBusMessageIter iter;
+ if (data->file)
+ g_object_unref (data->file);
+ if (data->result)
+ g_object_unref (data->result);
+ if (data->cancellable)
+ g_object_unref (data->cancellable);
+ g_free (data->attributes);
+ g_free (data);
+}
+
+static void
+query_info_async_cb (GVfsDBusMount *proxy,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ AsyncCallQueryInfo *data = user_data;
+ GError *error = NULL;
+ GSimpleAsyncResult *orig_result;
+ GVariant *iter_info;
GFileInfo *info;
- GError *error;
GFile *file;
-
- info = NULL;
- if (!dbus_message_iter_init (reply, &iter) ||
- (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRUCT))
+ g_print ("query_info_async_cb\n");
+ orig_result = data->result;
+
+ if (! gvfs_dbus_mount_call_query_info_finish (proxy, &iter_info, res, &error))
{
- g_simple_async_result_set_error (result,
- G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Invalid return value from %s"), "query_info");
- _g_simple_async_result_complete_with_cancellable (result, cancellable);
- return;
+ g_simple_async_result_take_error (orig_result, error);
+ goto out;
}
+
+ info = _g_dbus_get_file_info (iter_info, &error);
+ g_variant_unref (iter_info);
- error = NULL;
- info = _g_dbus_get_file_info (&iter, &error);
if (info == NULL)
{
- g_simple_async_result_set_from_error (result, error);
- g_error_free (error);
- _g_simple_async_result_complete_with_cancellable (result, cancellable);
- return;
+ g_simple_async_result_take_error (orig_result, error);
+ goto out;
}
- file = G_FILE (g_async_result_get_source_object (G_ASYNC_RESULT (result)));
- add_metadata (file, attributes, info);
+ file = G_FILE (g_async_result_get_source_object (G_ASYNC_RESULT (orig_result)));
+ add_metadata (file, data->attributes, info);
g_object_unref (file);
- g_simple_async_result_set_op_res_gpointer (result, info, g_object_unref);
- _g_simple_async_result_complete_with_cancellable (result, cancellable);
+ g_simple_async_result_set_op_res_gpointer (orig_result, info, g_object_unref);
+
+out:
+ _g_simple_async_result_complete_with_cancellable (orig_result, data->cancellable);
+ data->result = NULL;
+ g_object_unref (orig_result); /* trigger async_proxy_create_free() */
+}
+
+static void
+query_info_async_get_proxy_cb (GVfsDBusMount *proxy,
+ GDBusConnection *connection,
+ GMountInfo *mount_info,
+ const gchar *path,
+ GSimpleAsyncResult *result,
+ GError *error,
+ GCancellable *cancellable,
+ gpointer callback_data)
+{
+ AsyncCallQueryInfo *data = callback_data;
+ char *uri;
+
+ g_print ("query_info_async_get_proxy_cb, proxy = %p\n", proxy);
+
+ uri = g_file_get_uri (data->file);
+
+ data->result = g_object_ref (result);
+
+ gvfs_dbus_mount_call_query_info (proxy,
+ path,
+ data->attributes ? data->attributes : "",
+ data->flags,
+ uri,
+ cancellable,
+ (GAsyncReadyCallback) query_info_async_cb,
+ data);
+
+ g_free (uri);
}
static void
@@ -942,23 +949,23 @@ g_daemon_file_query_info_async (GFile *file,
GAsyncReadyCallback callback,
gpointer user_data)
{
- guint32 dbus_flags;
- char *uri;
+ AsyncCallQueryInfo *data;
- uri = g_file_get_uri (file);
-
- dbus_flags = flags;
- do_async_path_call (file,
- G_VFS_DBUS_MOUNT_OP_QUERY_INFO,
- cancellable,
- callback, user_data,
- query_info_async_cb, g_strdup (attributes), g_free,
- DBUS_TYPE_STRING, &attributes,
- DBUS_TYPE_UINT32, &dbus_flags,
- DBUS_TYPE_STRING, &uri,
- 0);
+ g_print ("g_daemon_file_query_info_async\n");
+
+ data = g_new0 (AsyncCallQueryInfo, 1);
+ data->file = g_object_ref (file);
+ data->attributes = g_strdup (attributes);
+ data->flags = flags;
+ data->io_priority = io_priority;
+ if (cancellable)
+ data->cancellable = g_object_ref (cancellable);
- g_free (uri);
+ create_proxy_for_file_async (file,
+ cancellable,
+ callback, user_data,
+ query_info_async_get_proxy_cb,
+ data, (GDestroyNotify) async_call_query_info_free);
}
static GFileInfo *
@@ -976,67 +983,100 @@ g_daemon_file_query_info_finish (GFile *file,
return NULL;
}
+
typedef struct {
+ GFile *file;
+ guint16 mode;
+ int io_priority;
+ gchar *etag;
+ gboolean make_backup;
+ GFileCreateFlags flags;
GSimpleAsyncResult *result;
GCancellable *cancellable;
- gboolean can_seek;
-} GetFDData;
+} AsyncCallFileReadWrite;
+
+static void
+async_call_file_read_write_free (AsyncCallFileReadWrite *data)
+{
+ if (data->file)
+ g_object_unref (data->file);
+ if (data->result)
+ g_object_unref (data->result);
+ if (data->cancellable)
+ g_object_unref (data->cancellable);
+ g_free (data->etag);
+ g_free (data);
+}
static void
-read_async_get_fd_cb (int fd,
- gpointer callback_data)
+read_async_cb (GVfsDBusMount *proxy,
+ GAsyncResult *res,
+ gpointer user_data)
{
- GetFDData *data = callback_data;
+ AsyncCallFileReadWrite *data = user_data;
+ GError *error = NULL;
+ GSimpleAsyncResult *orig_result;
+ gboolean can_seek;
+ GUnixFDList *fd_list;
+ int fd;
+ guint fd_id;
GFileInputStream *stream;
+
+ g_print ("read_async_cb\n");
+ orig_result = data->result;
- if (fd == -1)
+ if (! gvfs_dbus_mount_call_open_for_read_finish (proxy, &fd_id, &can_seek, &fd_list, res, &error))
+ {
+ g_simple_async_result_take_error (orig_result, error);
+ goto out;
+ }
+
+ if (fd_list == NULL || g_unix_fd_list_get_length (fd_list) != 1 ||
+ (fd = g_unix_fd_list_get (fd_list, fd_id, NULL)) == -1)
{
- g_simple_async_result_set_error (data->result,
- G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Couldn't get stream file descriptor"));
+ g_simple_async_result_set_error (orig_result,
+ G_IO_ERROR, G_IO_ERROR_FAILED,
+ _("Couldn't get stream file descriptor"));
}
else
{
- stream = g_daemon_file_input_stream_new (fd, data->can_seek);
- g_simple_async_result_set_op_res_gpointer (data->result, stream, g_object_unref);
+ stream = g_daemon_file_input_stream_new (fd, can_seek);
+ g_simple_async_result_set_op_res_gpointer (orig_result, stream, g_object_unref);
+ g_object_unref (fd_list);
}
- _g_simple_async_result_complete_with_cancellable (data->result, data->cancellable);
-
- g_object_unref (data->result);
- g_free (data);
+out:
+ _g_simple_async_result_complete_with_cancellable (orig_result, data->cancellable);
+ data->result = NULL;
+ g_object_unref (orig_result); /* trigger async_proxy_create_free() */
}
static void
-read_async_cb (DBusMessage *reply,
- DBusConnection *connection,
- GMountInfo *mount_info,
- GSimpleAsyncResult *result,
- GCancellable *cancellable,
- gpointer callback_data)
-{
- guint32 fd_id;
- dbus_bool_t can_seek;
- GetFDData *get_fd_data;
-
- if (!dbus_message_get_args (reply, NULL,
- DBUS_TYPE_UINT32, &fd_id,
- DBUS_TYPE_BOOLEAN, &can_seek,
- DBUS_TYPE_INVALID))
- {
- g_simple_async_result_set_error (result,
- G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Invalid return value from %s"), "open");
- _g_simple_async_result_complete_with_cancellable (result, cancellable);
- return;
- }
+file_read_async_get_proxy_cb (GVfsDBusMount *proxy,
+ GDBusConnection *connection,
+ GMountInfo *mount_info,
+ const gchar *path,
+ GSimpleAsyncResult *result,
+ GError *error,
+ GCancellable *cancellable,
+ gpointer callback_data)
+{
+ AsyncCallFileReadWrite *data = callback_data;
+ guint32 pid;
+
+ g_print ("file_read_async_get_proxy_cb, proxy = %p\n", proxy);
+
+ pid = get_pid_for_file (data->file);
- get_fd_data = g_new0 (GetFDData, 1);
- get_fd_data->result = g_object_ref (result);
- get_fd_data->can_seek = can_seek;
+ data->result = g_object_ref (result);
- _g_dbus_connection_get_fd_async (connection, fd_id,
- read_async_get_fd_cb, get_fd_data);
+ gvfs_dbus_mount_call_open_for_read (proxy,
+ path,
+ pid,
+ NULL,
+ cancellable,
+ (GAsyncReadyCallback) read_async_cb,
+ data);
}
static void
@@ -1046,17 +1086,21 @@ g_daemon_file_read_async (GFile *file,
GAsyncReadyCallback callback,
gpointer callback_data)
{
- guint32 pid;
+ AsyncCallFileReadWrite *data;
- pid = get_pid_for_file (file);
+ g_print ("g_daemon_file_read_async\n");
+
+ data = g_new0 (AsyncCallFileReadWrite, 1);
+ data->file = g_object_ref (file);
+ data->io_priority = io_priority;
+ if (cancellable)
+ data->cancellable = g_object_ref (cancellable);
- do_async_path_call (file,
- G_VFS_DBUS_MOUNT_OP_OPEN_FOR_READ,
- cancellable,
- callback, callback_data,
- read_async_cb, NULL, NULL,
- DBUS_TYPE_UINT32, &pid,
- 0);
+ create_proxy_for_file_async (file,
+ cancellable,
+ callback, callback_data,
+ file_read_async_get_proxy_cb,
+ data, (GDestroyNotify) async_call_file_read_write_free);
}
static GFileInputStream *
@@ -1074,178 +1118,143 @@ g_daemon_file_read_finish (GFile *file,
return NULL;
}
-
static GFileInputStream *
g_daemon_file_read (GFile *file,
GCancellable *cancellable,
GError **error)
{
- DBusConnection *connection;
+ GVfsDBusMount *proxy;
+ char *path;
+ gboolean res;
+ gboolean can_seek;
+ GUnixFDList *fd_list;
int fd;
- DBusMessage *reply;
- guint32 fd_id;
- dbus_bool_t can_seek;
+ guint fd_id;
guint32 pid;
+ g_print ("g_daemon_file_read\n");
+
pid = get_pid_for_file (file);
- reply = do_sync_path_call (file,
- G_VFS_DBUS_MOUNT_OP_OPEN_FOR_READ,
- NULL, &connection,
- cancellable, error,
- DBUS_TYPE_UINT32, &pid,
- 0);
- if (reply == NULL)
+ proxy = create_proxy_for_file (file, NULL, &path, NULL, cancellable, error);
+ if (proxy == NULL)
return NULL;
- if (!dbus_message_get_args (reply, NULL,
- DBUS_TYPE_UINT32, &fd_id,
- DBUS_TYPE_BOOLEAN, &can_seek,
- DBUS_TYPE_INVALID))
- {
- dbus_message_unref (reply);
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Invalid return value from %s"), "open");
- return NULL;
- }
+ res = gvfs_dbus_mount_call_open_for_read_sync (proxy,
+ path,
+ pid,
+ NULL,
+ &fd_id,
+ &can_seek,
+ &fd_list,
+ cancellable,
+ error);
- dbus_message_unref (reply);
+ g_print ("g_daemon_file_read: done, res = %d\n", res);
+
+ g_free (path);
+ g_object_unref (proxy);
- fd = _g_dbus_connection_get_fd_sync (connection, fd_id);
- if (fd == -1)
+ if (! res)
+ return NULL;
+
+ if (fd_list == NULL || g_unix_fd_list_get_length (fd_list) != 1 ||
+ (fd = g_unix_fd_list_get (fd_list, fd_id, NULL)) == -1)
{
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
_("Didn't get stream file descriptor"));
return NULL;
}
+
+ g_object_unref (fd_list);
return g_daemon_file_input_stream_new (fd, can_seek);
}
static GFileOutputStream *
-g_daemon_file_append_to (GFile *file,
- GFileCreateFlags flags,
- GCancellable *cancellable,
- GError **error)
-{
- DBusConnection *connection;
+file_open_write (GFile *file,
+ guint16 mode,
+ const char *etag,
+ gboolean make_backup,
+ GFileCreateFlags flags,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GVfsDBusMount *proxy;
+ char *path;
+ gboolean res;
+ gboolean can_seek;
+ GUnixFDList *fd_list;
int fd;
- DBusMessage *reply;
guint32 fd_id;
- dbus_bool_t can_seek;
- guint16 mode;
- guint64 initial_offset;
- dbus_bool_t make_backup;
- guint32 dbus_flags;
- char *etag;
guint32 pid;
+ guint64 initial_offset;
pid = get_pid_for_file (file);
- mode = 1;
- etag = "";
- make_backup = FALSE;
- dbus_flags = flags;
-
- reply = do_sync_path_call (file,
- G_VFS_DBUS_MOUNT_OP_OPEN_FOR_WRITE,
- NULL, &connection,
- cancellable, error,
- DBUS_TYPE_UINT16, &mode,
- DBUS_TYPE_STRING, &etag,
- DBUS_TYPE_BOOLEAN, &make_backup,
- DBUS_TYPE_UINT32, &dbus_flags,
- DBUS_TYPE_UINT32, &pid,
- 0);
- if (reply == NULL)
+ if (etag == NULL)
+ etag = "";
+
+ proxy = create_proxy_for_file (file, NULL, &path, NULL, cancellable, error);
+ if (proxy == NULL)
return NULL;
- if (!dbus_message_get_args (reply, NULL,
- DBUS_TYPE_UINT32, &fd_id,
- DBUS_TYPE_BOOLEAN, &can_seek,
- DBUS_TYPE_UINT64, &initial_offset,
- DBUS_TYPE_INVALID))
- {
- dbus_message_unref (reply);
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Invalid return value from %s"), "open");
- return NULL;
- }
+ res = gvfs_dbus_mount_call_open_for_write_sync (proxy,
+ path,
+ mode,
+ etag,
+ make_backup,
+ flags,
+ pid,
+ NULL,
+ &fd_id,
+ &can_seek,
+ &initial_offset,
+ &fd_list,
+ cancellable,
+ error);
+
+ g_print ("file_open_write: done, res = %d\n", res);
- dbus_message_unref (reply);
+ g_free (path);
+ g_object_unref (proxy);
- fd = _g_dbus_connection_get_fd_sync (connection, fd_id);
- if (fd == -1)
+ if (! res)
+ return NULL;
+
+ if (fd_list == NULL || g_unix_fd_list_get_length (fd_list) != 1 ||
+ (fd = g_unix_fd_list_get (fd_list, 0, NULL)) == -1)
{
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Didn't get stream file descriptor"));
+ _("Didn't get stream file descriptor"));
return NULL;
}
+
+ g_object_unref (fd_list);
return g_daemon_file_output_stream_new (fd, can_seek, initial_offset);
}
static GFileOutputStream *
+g_daemon_file_append_to (GFile *file,
+ GFileCreateFlags flags,
+ GCancellable *cancellable,
+ GError **error)
+{
+ g_print ("g_daemon_file_append_to\n");
+
+ return file_open_write (file, 1, "", FALSE, flags, cancellable, error);
+}
+
+static GFileOutputStream *
g_daemon_file_create (GFile *file,
GFileCreateFlags flags,
GCancellable *cancellable,
GError **error)
{
- DBusConnection *connection;
- int fd;
- DBusMessage *reply;
- guint32 fd_id;
- dbus_bool_t can_seek;
- guint16 mode;
- guint64 initial_offset;
- dbus_bool_t make_backup;
- char *etag;
- guint32 dbus_flags;
- guint32 pid;
-
- pid = get_pid_for_file (file);
+ g_print ("g_daemon_file_create\n");
- mode = 0;
- etag = "";
- make_backup = FALSE;
- dbus_flags = flags;
-
- reply = do_sync_path_call (file,
- G_VFS_DBUS_MOUNT_OP_OPEN_FOR_WRITE,
- NULL, &connection,
- cancellable, error,
- DBUS_TYPE_UINT16, &mode,
- DBUS_TYPE_STRING, &etag,
- DBUS_TYPE_BOOLEAN, &make_backup,
- DBUS_TYPE_UINT32, &dbus_flags,
- DBUS_TYPE_UINT32, &pid,
- 0);
- if (reply == NULL)
- return NULL;
-
- if (!dbus_message_get_args (reply, NULL,
- DBUS_TYPE_UINT32, &fd_id,
- DBUS_TYPE_BOOLEAN, &can_seek,
- DBUS_TYPE_UINT64, &initial_offset,
- DBUS_TYPE_INVALID))
- {
- dbus_message_unref (reply);
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Invalid return value from %s"), "open");
- return NULL;
- }
-
- dbus_message_unref (reply);
-
- fd = _g_dbus_connection_get_fd_sync (connection, fd_id);
- if (fd == -1)
- {
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Didn't get stream file descriptor"));
- return NULL;
- }
-
- return g_daemon_file_output_stream_new (fd, can_seek, initial_offset);
+ return file_open_write (file, 0, "", FALSE, flags, cancellable, error);
}
static GFileOutputStream *
@@ -1256,62 +1265,29 @@ g_daemon_file_replace (GFile *file,
GCancellable *cancellable,
GError **error)
{
- DBusConnection *connection;
- int fd;
- DBusMessage *reply;
- guint32 fd_id;
- dbus_bool_t can_seek;
- guint16 mode;
- guint64 initial_offset;
- dbus_bool_t dbus_make_backup;
- guint32 dbus_flags;
- guint32 pid;
+ g_print ("g_daemon_file_replace\n");
- pid = get_pid_for_file (file);
-
- mode = 2;
- dbus_make_backup = make_backup;
- dbus_flags = flags;
+ return file_open_write (file, 2, etag, make_backup, flags, cancellable, error);
+}
- if (etag == NULL)
- etag = "";
-
- reply = do_sync_path_call (file,
- G_VFS_DBUS_MOUNT_OP_OPEN_FOR_WRITE,
- NULL, &connection,
- cancellable, error,
- DBUS_TYPE_UINT16, &mode,
- DBUS_TYPE_STRING, &etag,
- DBUS_TYPE_BOOLEAN, &dbus_make_backup,
- DBUS_TYPE_UINT32, &dbus_flags,
- DBUS_TYPE_UINT32, &pid,
- 0);
- if (reply == NULL)
- return NULL;
- if (!dbus_message_get_args (reply, NULL,
- DBUS_TYPE_UINT32, &fd_id,
- DBUS_TYPE_BOOLEAN, &can_seek,
- DBUS_TYPE_UINT64, &initial_offset,
- DBUS_TYPE_INVALID))
- {
- dbus_message_unref (reply);
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Invalid return value from %s"), "open");
- return NULL;
- }
-
- dbus_message_unref (reply);
+typedef struct {
+ GSimpleAsyncResult *result;
+ GCancellable *cancellable;
+ guint32 flags;
+ GMountOperation *mount_operation;
+} AsyncMountOp;
- fd = _g_dbus_connection_get_fd_sync (connection, fd_id);
- if (fd == -1)
- {
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Didn't get stream file descriptor"));
- return NULL;
- }
-
- return g_daemon_file_output_stream_new (fd, can_seek, initial_offset);
+static void
+free_async_mount_op (AsyncMountOp *data)
+{
+ if (data->result)
+ g_object_unref (data->result);
+ if (data->cancellable)
+ g_object_unref (data->cancellable);
+ if (data->mount_operation)
+ g_object_unref (data->mount_operation);
+ g_free (data);
}
static void
@@ -1321,7 +1297,9 @@ mount_mountable_location_mounted_cb (GObject *source_object,
{
GSimpleAsyncResult *result = user_data;
GError *error = NULL;
-
+
+ g_print ("mount_mountable_location_mounted_cb\n");
+
if (!g_file_mount_enclosing_volume_finish (G_FILE (source_object), res, &error))
{
g_simple_async_result_set_from_error (result, error);
@@ -1330,77 +1308,115 @@ mount_mountable_location_mounted_cb (GObject *source_object,
g_simple_async_result_complete (result);
g_object_unref (result);
-
}
static void
-mount_mountable_async_cb (DBusMessage *reply,
- DBusConnection *connection,
- GMountInfo *mount_info,
- GSimpleAsyncResult *result,
- GCancellable *cancellable,
- gpointer callback_data)
+mount_mountable_async_cb (GVfsDBusMount *proxy,
+ GAsyncResult *res,
+ gpointer user_data)
{
- GMountOperation *mount_operation = callback_data;
- GMountSpec *mount_spec;
- char *path;
- DBusMessageIter iter;
+ AsyncMountOp *data = user_data;
+ GSimpleAsyncResult *orig_result;
+ GError *error = NULL;
+ gboolean is_uri;
+ gchar *out_path;
+ gboolean must_mount_location;
+ GVariant *iter_mountspec;
GFile *file;
- dbus_bool_t must_mount_location, is_uri;
-
- path = NULL;
-
- dbus_message_iter_init (reply, &iter);
+ GMountSpec *mount_spec;
- if (!_g_dbus_message_iter_get_args (&iter, NULL,
- DBUS_TYPE_BOOLEAN, &is_uri,
- G_DBUS_TYPE_CSTRING, &path,
- DBUS_TYPE_BOOLEAN, &must_mount_location,
- 0))
- {
- g_simple_async_result_set_error (result,
- G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Invalid return value from %s"), "call");
- _g_simple_async_result_complete_with_cancellable (result, cancellable);
-
- return;
+ g_print ("mount_mountable_async_cb\n");
+ orig_result = data->result;
+ data->result = NULL;
+
+ is_uri = FALSE;
+ out_path = NULL;
+ must_mount_location = FALSE;
+ iter_mountspec = NULL;
+ if (! gvfs_dbus_mount_call_mount_mountable_finish (proxy,
+ &is_uri,
+ &out_path,
+ &must_mount_location,
+ &iter_mountspec,
+ res,
+ &error))
+ {
+ g_simple_async_result_take_error (orig_result, error);
+ goto out;
}
-
+
if (is_uri)
{
- file = g_file_new_for_uri (path);
+ file = g_file_new_for_uri (out_path);
}
else
{
- mount_spec = g_mount_spec_from_dbus (&iter);
+ mount_spec = g_mount_spec_from_dbus (iter_mountspec);
+ g_variant_unref (iter_mountspec);
+
if (mount_spec == NULL)
- {
- g_simple_async_result_set_error (result,
- G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Invalid return value from %s"), "call");
- _g_simple_async_result_complete_with_cancellable (result, cancellable);
- return;
- }
+ {
+ g_simple_async_result_set_error (orig_result,
+ G_IO_ERROR, G_IO_ERROR_FAILED,
+ _("Invalid return value from %s"), "call");
+ goto out;
+ }
- file = g_daemon_file_new (mount_spec, path);
+ file = g_daemon_file_new (mount_spec, out_path);
g_mount_spec_unref (mount_spec);
}
- g_free (path);
- g_simple_async_result_set_op_res_gpointer (result, file, g_object_unref);
+ g_free (out_path);
+ g_simple_async_result_set_op_res_gpointer (orig_result, file, g_object_unref);
if (must_mount_location)
{
g_file_mount_enclosing_volume (file,
- 0,
- mount_operation,
- cancellable,
- mount_mountable_location_mounted_cb,
- g_object_ref (result));
-
+ 0,
+ data->mount_operation,
+ data->cancellable,
+ mount_mountable_location_mounted_cb,
+ orig_result);
+ return;
}
- else
- _g_simple_async_result_complete_with_cancellable (result, cancellable);
+
+out:
+ _g_simple_async_result_complete_with_cancellable (orig_result, data->cancellable);
+ g_object_unref (orig_result); /* trigger async_proxy_create_free() */
+}
+
+static void
+mount_mountable_got_proxy_cb (GVfsDBusMount *proxy,
+ GDBusConnection *connection,
+ GMountInfo *mount_info,
+ const gchar *path,
+ GSimpleAsyncResult *result,
+ GError *error,
+ GCancellable *cancellable,
+ gpointer callback_data)
+{
+ AsyncMountOp *data = callback_data;
+ GMountSource *mount_source;
+ const char *dbus_id, *obj_path;
+
+ g_print ("mount_mountable_got_proxy_cb, proxy = %p\n", proxy);
+
+ data->result = g_object_ref (result);
+
+ mount_source = g_mount_operation_dbus_wrap (data->mount_operation, _g_daemon_vfs_get_async_bus ());
+
+ dbus_id = g_mount_source_get_dbus_id (mount_source);
+ obj_path = g_mount_source_get_obj_path (mount_source);
+
+ gvfs_dbus_mount_call_mount_mountable (proxy,
+ path,
+ dbus_id,
+ obj_path,
+ cancellable,
+ (GAsyncReadyCallback) mount_mountable_async_cb,
+ data);
+
+ g_object_unref (mount_source);
}
static void
@@ -1411,28 +1427,21 @@ g_daemon_file_mount_mountable (GFile *file,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GMountSource *mount_source;
- const char *dbus_id, *obj_path;
-
- mount_source = g_mount_operation_dbus_wrap (mount_operation, _g_daemon_vfs_get_async_bus ());
+ AsyncMountOp *data;
- dbus_id = g_mount_source_get_dbus_id (mount_source);
- obj_path = g_mount_source_get_obj_path (mount_source);
-
- if (mount_operation)
- g_object_ref (mount_operation);
-
- do_async_path_call (file,
- G_VFS_DBUS_MOUNT_OP_MOUNT_MOUNTABLE,
- cancellable,
- callback, user_data,
- mount_mountable_async_cb,
- mount_operation, mount_operation ? g_object_unref : NULL,
- DBUS_TYPE_STRING, &dbus_id,
- DBUS_TYPE_OBJECT_PATH, &obj_path,
- 0);
+ g_print ("g_daemon_file_mount_mountable\n");
+
+ data = g_new0 (AsyncMountOp, 1);
+ data->flags = flags;
+ data->mount_operation = g_object_ref (mount_operation);
+ if (cancellable)
+ data->cancellable = g_object_ref (cancellable);
- g_object_unref (mount_source);
+ create_proxy_for_file_async (file,
+ cancellable,
+ callback, user_data,
+ mount_mountable_got_proxy_cb,
+ data, (GDestroyNotify) free_async_mount_op);
}
static GFile *
@@ -1451,46 +1460,82 @@ g_daemon_file_mount_mountable_finish (GFile *file,
}
static void
-start_mountable_async_cb (DBusMessage *reply,
- DBusConnection *connection,
- GMountInfo *mount_info,
- GSimpleAsyncResult *result,
- GCancellable *cancellable,
- gpointer callback_data)
+start_mountable_async_cb (GVfsDBusMount *proxy,
+ GAsyncResult *res,
+ gpointer user_data)
{
- _g_simple_async_result_complete_with_cancellable (result, cancellable);
+ AsyncMountOp *data = user_data;
+ GSimpleAsyncResult *orig_result;
+ GError *error = NULL;
+
+ g_print ("start_mountable_async_cb\n");
+ orig_result = data->result;
+
+ if (! gvfs_dbus_mount_call_start_mountable_finish (proxy, res, &error))
+ g_simple_async_result_take_error (orig_result, error);
+
+ _g_simple_async_result_complete_with_cancellable (orig_result, data->cancellable);
+ data->result = NULL;
+ g_object_unref (orig_result); /* trigger async_proxy_create_free() */
}
static void
-g_daemon_file_start_mountable (GFile *file,
- GDriveStartFlags flags,
- GMountOperation *mount_operation,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
+start_mountable_got_proxy_cb (GVfsDBusMount *proxy,
+ GDBusConnection *connection,
+ GMountInfo *mount_info,
+ const gchar *path,
+ GSimpleAsyncResult *result,
+ GError *error,
+ GCancellable *cancellable,
+ gpointer callback_data)
+{
+ AsyncMountOp *data = callback_data;
GMountSource *mount_source;
const char *dbus_id, *obj_path;
- mount_source = g_mount_operation_dbus_wrap (mount_operation, _g_daemon_vfs_get_async_bus ());
+ g_print ("start_mountable_got_proxy_cb, proxy = %p\n", proxy);
+
+ data->result = g_object_ref (result);
+
+ mount_source = g_mount_operation_dbus_wrap (data->mount_operation, _g_daemon_vfs_get_async_bus ());
dbus_id = g_mount_source_get_dbus_id (mount_source);
obj_path = g_mount_source_get_obj_path (mount_source);
+
+ gvfs_dbus_mount_call_start_mountable (proxy,
+ path,
+ dbus_id,
+ obj_path,
+ cancellable,
+ (GAsyncReadyCallback) start_mountable_async_cb,
+ data);
+
+ g_object_unref (mount_source);
+}
- if (mount_operation)
- g_object_ref (mount_operation);
-
- do_async_path_call (file,
- G_VFS_DBUS_MOUNT_OP_START_MOUNTABLE,
- cancellable,
- callback, user_data,
- start_mountable_async_cb,
- mount_operation, mount_operation ? g_object_unref : NULL,
- DBUS_TYPE_STRING, &dbus_id,
- DBUS_TYPE_OBJECT_PATH, &obj_path,
- 0);
+static void
+g_daemon_file_start_mountable (GFile *file,
+ GDriveStartFlags flags,
+ GMountOperation *mount_operation,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ AsyncMountOp *data;
+
+ g_print ("g_daemon_file_start_mountable\n");
+
+ data = g_new0 (AsyncMountOp, 1);
+ data->flags = flags;
+ data->mount_operation = g_object_ref (mount_operation);
+ if (cancellable)
+ data->cancellable = g_object_ref (cancellable);
- g_object_unref (mount_source);
+ create_proxy_for_file_async (file,
+ cancellable,
+ callback, user_data,
+ start_mountable_got_proxy_cb,
+ data, (GDestroyNotify) free_async_mount_op);
}
static gboolean
@@ -1502,50 +1547,85 @@ g_daemon_file_start_mountable_finish (GFile *file,
}
static void
-stop_mountable_async_cb (DBusMessage *reply,
- DBusConnection *connection,
- GMountInfo *mount_info,
- GSimpleAsyncResult *result,
- GCancellable *cancellable,
- gpointer callback_data)
+stop_mountable_async_cb (GVfsDBusMount *proxy,
+ GAsyncResult *res,
+ gpointer user_data)
{
- _g_simple_async_result_complete_with_cancellable (result, cancellable);
+ AsyncMountOp *data = user_data;
+ GSimpleAsyncResult *orig_result;
+ GError *error = NULL;
+
+ g_print ("stop_mountable_async_cb\n");
+ orig_result = data->result;
+
+ if (! gvfs_dbus_mount_call_stop_mountable_finish (proxy, res, &error))
+ g_simple_async_result_take_error (orig_result, error);
+
+ _g_simple_async_result_complete_with_cancellable (orig_result, data->cancellable);
+ data->result = NULL;
+ g_object_unref (orig_result); /* trigger async_proxy_create_free() */
}
static void
-g_daemon_file_stop_mountable (GFile *file,
- GMountUnmountFlags flags,
- GMountOperation *mount_operation,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
+stop_mountable_got_proxy_cb (GVfsDBusMount *proxy,
+ GDBusConnection *connection,
+ GMountInfo *mount_info,
+ const gchar *path,
+ GSimpleAsyncResult *result,
+ GError *error,
+ GCancellable *cancellable,
+ gpointer callback_data)
{
- guint32 dbus_flags;
+ AsyncMountOp *data = callback_data;
GMountSource *mount_source;
const char *dbus_id, *obj_path;
- mount_source = g_mount_operation_dbus_wrap (mount_operation, _g_daemon_vfs_get_async_bus ());
+ g_print ("stop_mountable_got_proxy_cb, proxy = %p\n", proxy);
+
+ data->result = g_object_ref (result);
+
+ mount_source = g_mount_operation_dbus_wrap (data->mount_operation, _g_daemon_vfs_get_async_bus ());
dbus_id = g_mount_source_get_dbus_id (mount_source);
obj_path = g_mount_source_get_obj_path (mount_source);
-
- if (mount_operation)
- g_object_ref (mount_operation);
-
- dbus_flags = flags;
- do_async_path_call (file,
- G_VFS_DBUS_MOUNT_OP_STOP_MOUNTABLE,
- cancellable,
- callback, user_data,
- stop_mountable_async_cb,
- mount_operation, mount_operation ? g_object_unref : NULL,
- DBUS_TYPE_UINT32, &dbus_flags,
- DBUS_TYPE_STRING, &dbus_id, DBUS_TYPE_OBJECT_PATH, &obj_path,
- 0);
+
+ gvfs_dbus_mount_call_stop_mountable (proxy,
+ path,
+ data->flags,
+ dbus_id,
+ obj_path,
+ cancellable,
+ (GAsyncReadyCallback) stop_mountable_async_cb,
+ data);
g_object_unref (mount_source);
}
+static void
+g_daemon_file_stop_mountable (GFile *file,
+ GMountUnmountFlags flags,
+ GMountOperation *mount_operation,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ AsyncMountOp *data;
+
+ g_print ("g_daemon_file_stop_mountable\n");
+
+ data = g_new0 (AsyncMountOp, 1);
+ data->flags = flags;
+ data->mount_operation = g_object_ref (mount_operation);
+ if (cancellable)
+ data->cancellable = g_object_ref (cancellable);
+
+ create_proxy_for_file_async (file,
+ cancellable,
+ callback, user_data,
+ stop_mountable_got_proxy_cb,
+ data, (GDestroyNotify) free_async_mount_op);
+}
+
static gboolean
g_daemon_file_stop_mountable_finish (GFile *file,
GAsyncResult *result,
@@ -1554,52 +1634,86 @@ g_daemon_file_stop_mountable_finish (GFile *file,
return TRUE;
}
-
static void
-eject_mountable_async_cb (DBusMessage *reply,
- DBusConnection *connection,
- GMountInfo *mount_info,
- GSimpleAsyncResult *result,
- GCancellable *cancellable,
- gpointer callback_data)
+eject_mountable_async_cb (GVfsDBusMount *proxy,
+ GAsyncResult *res,
+ gpointer user_data)
{
- _g_simple_async_result_complete_with_cancellable (result, cancellable);
+ AsyncMountOp *data = user_data;
+ GSimpleAsyncResult *orig_result;
+ GError *error = NULL;
+
+ g_print ("eject_mountable_async_cb\n");
+ orig_result = data->result;
+
+ if (! gvfs_dbus_mount_call_eject_mountable_finish (proxy, res, &error))
+ g_simple_async_result_take_error (orig_result, error);
+
+ _g_simple_async_result_complete_with_cancellable (orig_result, data->cancellable);
+ data->result = NULL;
+ g_object_unref (orig_result); /* trigger async_proxy_create_free() */
}
static void
-g_daemon_file_eject_mountable_with_operation (GFile *file,
- GMountUnmountFlags flags,
- GMountOperation *mount_operation,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- guint32 dbus_flags;
+eject_mountable_got_proxy_cb (GVfsDBusMount *proxy,
+ GDBusConnection *connection,
+ GMountInfo *mount_info,
+ const gchar *path,
+ GSimpleAsyncResult *result,
+ GError *error,
+ GCancellable *cancellable,
+ gpointer callback_data)
+{
+ AsyncMountOp *data = callback_data;
GMountSource *mount_source;
const char *dbus_id, *obj_path;
- mount_source = g_mount_operation_dbus_wrap (mount_operation, _g_daemon_vfs_get_async_bus ());
+ g_print ("eject_mountable_got_proxy_cb, proxy = %p\n", proxy);
+
+ data->result = g_object_ref (result);
+
+ mount_source = g_mount_operation_dbus_wrap (data->mount_operation, _g_daemon_vfs_get_async_bus ());
dbus_id = g_mount_source_get_dbus_id (mount_source);
obj_path = g_mount_source_get_obj_path (mount_source);
-
- if (mount_operation)
- g_object_ref (mount_operation);
-
- dbus_flags = flags;
- do_async_path_call (file,
- G_VFS_DBUS_MOUNT_OP_EJECT_MOUNTABLE,
- cancellable,
- callback, user_data,
- eject_mountable_async_cb,
- mount_operation, mount_operation ? g_object_unref : NULL,
- DBUS_TYPE_UINT32, &dbus_flags,
- DBUS_TYPE_STRING, &dbus_id, DBUS_TYPE_OBJECT_PATH, &obj_path,
- 0);
+
+ gvfs_dbus_mount_call_eject_mountable (proxy,
+ path,
+ data->flags,
+ dbus_id,
+ obj_path,
+ cancellable,
+ (GAsyncReadyCallback) eject_mountable_async_cb,
+ data);
g_object_unref (mount_source);
}
+static void
+g_daemon_file_eject_mountable_with_operation (GFile *file,
+ GMountUnmountFlags flags,
+ GMountOperation *mount_operation,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ AsyncMountOp *data;
+
+ g_print ("g_daemon_file_eject_mountable_with_operation\n");
+
+ data = g_new0 (AsyncMountOp, 1);
+ data->flags = flags;
+ data->mount_operation = g_object_ref (mount_operation);
+ if (cancellable)
+ data->cancellable = g_object_ref (cancellable);
+
+ create_proxy_for_file_async (file,
+ cancellable,
+ callback, user_data,
+ eject_mountable_got_proxy_cb,
+ data, (GDestroyNotify) free_async_mount_op);
+}
+
static gboolean
g_daemon_file_eject_mountable_with_operation_finish (GFile *file,
GAsyncResult *result,
@@ -1627,50 +1741,85 @@ g_daemon_file_eject_mountable_finish (GFile *file,
}
static void
-unmount_mountable_async_cb (DBusMessage *reply,
- DBusConnection *connection,
- GMountInfo *mount_info,
- GSimpleAsyncResult *result,
- GCancellable *cancellable,
- gpointer callback_data)
+unmount_mountable_async_cb (GVfsDBusMount *proxy,
+ GAsyncResult *res,
+ gpointer user_data)
{
- _g_simple_async_result_complete_with_cancellable (result, cancellable);
+ AsyncMountOp *data = user_data;
+ GSimpleAsyncResult *orig_result;
+ GError *error = NULL;
+
+ g_print ("unmount_mountable_async_cb\n");
+ orig_result = data->result;
+
+ if (! gvfs_dbus_mount_call_unmount_mountable_finish (proxy, res, &error))
+ g_simple_async_result_take_error (orig_result, error);
+
+ _g_simple_async_result_complete_with_cancellable (orig_result, data->cancellable);
+ data->result = NULL;
+ g_object_unref (orig_result); /* trigger async_proxy_create_free() */
}
static void
-g_daemon_file_unmount_mountable_with_operation (GFile *file,
- GMountUnmountFlags flags,
- GMountOperation *mount_operation,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- guint32 dbus_flags;
+unmount_mountable_got_proxy_cb (GVfsDBusMount *proxy,
+ GDBusConnection *connection,
+ GMountInfo *mount_info,
+ const gchar *path,
+ GSimpleAsyncResult *result,
+ GError *error,
+ GCancellable *cancellable,
+ gpointer callback_data)
+{
+ AsyncMountOp *data = callback_data;
GMountSource *mount_source;
const char *dbus_id, *obj_path;
- mount_source = g_mount_operation_dbus_wrap (mount_operation, _g_daemon_vfs_get_async_bus ());
+ g_print ("unmount_mountable_got_proxy_cb, proxy = %p\n", proxy);
+
+ data->result = g_object_ref (result);
+
+ mount_source = g_mount_operation_dbus_wrap (data->mount_operation, _g_daemon_vfs_get_async_bus ());
dbus_id = g_mount_source_get_dbus_id (mount_source);
obj_path = g_mount_source_get_obj_path (mount_source);
-
- if (mount_operation)
- g_object_ref (mount_operation);
-
- dbus_flags = flags;
- do_async_path_call (file,
- G_VFS_DBUS_MOUNT_OP_UNMOUNT_MOUNTABLE,
- cancellable,
- callback, user_data,
- unmount_mountable_async_cb,
- mount_operation, mount_operation ? g_object_unref : NULL,
- DBUS_TYPE_UINT32, &dbus_flags,
- DBUS_TYPE_STRING, &dbus_id, DBUS_TYPE_OBJECT_PATH, &obj_path,
- 0);
+
+ gvfs_dbus_mount_call_unmount_mountable (proxy,
+ path,
+ data->flags,
+ dbus_id,
+ obj_path,
+ cancellable,
+ (GAsyncReadyCallback) unmount_mountable_async_cb,
+ data);
g_object_unref (mount_source);
}
+static void
+g_daemon_file_unmount_mountable_with_operation (GFile *file,
+ GMountUnmountFlags flags,
+ GMountOperation *mount_operation,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ AsyncMountOp *data;
+
+ g_print ("g_daemon_file_unmount_mountable_with_operation\n");
+
+ data = g_new0 (AsyncMountOp, 1);
+ data->flags = flags;
+ data->mount_operation = g_object_ref (mount_operation);
+ if (cancellable)
+ data->cancellable = g_object_ref (cancellable);
+
+ create_proxy_for_file_async (file,
+ cancellable,
+ callback, user_data,
+ unmount_mountable_got_proxy_cb,
+ data, (GDestroyNotify) free_async_mount_op);
+}
+
static gboolean
g_daemon_file_unmount_mountable_with_operation_finish (GFile *file,
GAsyncResult *result,
@@ -1680,14 +1829,46 @@ g_daemon_file_unmount_mountable_with_operation_finish (GFile *file
}
static void
-poll_mountable_async_cb (DBusMessage *reply,
- DBusConnection *connection,
- GMountInfo *mount_info,
- GSimpleAsyncResult *result,
- GCancellable *cancellable,
- gpointer callback_data)
+poll_mountable_async_cb (GVfsDBusMount *proxy,
+ GAsyncResult *res,
+ gpointer user_data)
{
- _g_simple_async_result_complete_with_cancellable (result, cancellable);
+ AsyncMountOp *data = user_data;
+ GSimpleAsyncResult *orig_result;
+ GError *error = NULL;
+
+ g_print ("poll_mountable_async_cb\n");
+ orig_result = data->result;
+
+ if (! gvfs_dbus_mount_call_poll_mountable_finish (proxy, res, &error))
+ g_simple_async_result_take_error (orig_result, error);
+
+ _g_simple_async_result_complete_with_cancellable (orig_result, data->cancellable);
+ data->result = NULL;
+ g_object_unref (orig_result); /* trigger async_proxy_create_free() */
+}
+
+static void
+poll_mountable_got_proxy_cb (GVfsDBusMount *proxy,
+ GDBusConnection *connection,
+ GMountInfo *mount_info,
+ const gchar *path,
+ GSimpleAsyncResult *result,
+ GError *error,
+ GCancellable *cancellable,
+ gpointer callback_data)
+{
+ AsyncMountOp *data = callback_data;
+
+ g_print ("poll_mountable_got_proxy_cb, proxy = %p\n", proxy);
+
+ data->result = g_object_ref (result);
+
+ gvfs_dbus_mount_call_poll_mountable (proxy,
+ path,
+ cancellable,
+ (GAsyncReadyCallback) poll_mountable_async_cb,
+ data);
}
static void
@@ -1696,14 +1877,19 @@ g_daemon_file_poll_mountable (GFile *file,
GAsyncReadyCallback callback,
gpointer user_data)
{
- do_async_path_call (file,
- G_VFS_DBUS_MOUNT_OP_POLL_MOUNTABLE,
- cancellable,
- callback, user_data,
- poll_mountable_async_cb,
- NULL,
- NULL,
- 0);
+ AsyncMountOp *data;
+
+ g_print ("g_daemon_file_poll_mountable\n");
+
+ data = g_new0 (AsyncMountOp, 1);
+ if (cancellable)
+ data->cancellable = g_object_ref (cancellable);
+
+ create_proxy_for_file_async (file,
+ cancellable,
+ callback, user_data,
+ poll_mountable_got_proxy_cb,
+ data, (GDestroyNotify) free_async_mount_op);
}
static gboolean
@@ -1748,36 +1934,93 @@ static void g_daemon_file_mount_enclosing_volume (GFile *location,
gpointer user_data);
static void
-mount_reply (DBusMessage *reply,
- GError *error,
- gpointer user_data)
+free_mount_data (MountData *data)
+{
+ g_object_unref (data->file);
+ if (data->cancellable)
+ g_object_unref (data->cancellable);
+ if (data->mount_operation)
+ g_object_unref (data->mount_operation);
+ g_free (data);
+}
+
+static void
+mount_reply (GVfsDBusMountTracker *proxy,
+ GAsyncResult *res,
+ gpointer user_data)
{
MountData *data = user_data;
- GSimpleAsyncResult *res;
+ GSimpleAsyncResult *ares;
+ GError *error = NULL;
+
+ g_print ("mount_reply\n");
- if (reply == NULL)
+ if (!gvfs_dbus_mount_tracker_call_mount_location_finish (proxy, res, &error))
{
- res = g_simple_async_result_new_from_error (G_OBJECT (data->file),
- data->callback,
- data->user_data,
- error);
+ ares = g_simple_async_result_new_from_error (G_OBJECT (data->file),
+ data->callback,
+ data->user_data,
+ error);
+ g_error_free (error);
}
else
{
- res = g_simple_async_result_new (G_OBJECT (data->file),
+ ares = g_simple_async_result_new (G_OBJECT (data->file),
data->callback,
data->user_data,
g_daemon_file_mount_enclosing_volume);
}
- _g_simple_async_result_complete_with_cancellable (res, data->cancellable);
+ _g_simple_async_result_complete_with_cancellable (ares, data->cancellable);
+
+ free_mount_data (data);
+}
+
+static void
+mount_enclosing_volume_proxy_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ MountData *data = user_data;
+ GVfsDBusMountTracker *proxy;
+ GError *error = NULL;
+ GSimpleAsyncResult *ares;
+ GDaemonFile *daemon_file;
+ GMountSpec *spec;
+ GMountSource *mount_source;
+
+ g_print ("mount_enclosing_volume_proxy_cb\n");
+ daemon_file = G_DAEMON_FILE (data->file);
+
+ proxy = gvfs_dbus_mount_tracker_proxy_new_for_bus_finish (res, &error);
+ if (proxy == NULL)
+ {
+ ares = g_simple_async_result_new_from_error (G_OBJECT (data->file),
+ data->callback,
+ data->user_data,
+ error);
+ g_error_free (error);
+ _g_simple_async_result_complete_with_cancellable (ares, data->cancellable);
+ free_mount_data (data);
+ return;
+ }
- g_object_unref (data->file);
- if (data->cancellable)
- g_object_unref (data->cancellable);
- if (data->mount_operation)
- g_object_unref (data->mount_operation);
- g_free (data);
+ spec = g_mount_spec_copy (daemon_file->mount_spec);
+ g_mount_spec_set_mount_prefix (spec, daemon_file->path);
+ mount_source = g_mount_operation_dbus_wrap (data->mount_operation, _g_daemon_vfs_get_async_bus ());
+
+ g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (proxy), G_VFS_DBUS_MOUNT_TIMEOUT_MSECS);
+
+ gvfs_dbus_mount_tracker_call_mount_location (proxy,
+ g_mount_spec_to_dbus (spec),
+ g_mount_source_to_dbus (mount_source),
+ data->cancellable,
+ (GAsyncReadyCallback) mount_reply,
+ data);
+
+ g_mount_spec_unref (spec);
+ g_object_unref (mount_source);
+ g_object_unref (proxy);
}
static void
@@ -1788,30 +2031,10 @@ g_daemon_file_mount_enclosing_volume (GFile *location,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GDaemonFile *daemon_file;
- DBusMessage *message;
- GMountSpec *spec;
- GMountSource *mount_source;
- DBusMessageIter iter;
MountData *data;
- daemon_file = G_DAEMON_FILE (location);
+ g_print ("g_daemon_file_mount_enclosing_volume\n");
- message = dbus_message_new_method_call (G_VFS_DBUS_DAEMON_NAME,
- G_VFS_DBUS_MOUNTTRACKER_PATH,
- G_VFS_DBUS_MOUNTTRACKER_INTERFACE,
- G_VFS_DBUS_MOUNTTRACKER_OP_MOUNT_LOCATION);
-
- spec = g_mount_spec_copy (daemon_file->mount_spec);
- g_mount_spec_set_mount_prefix (spec, daemon_file->path);
- dbus_message_iter_init_append (message, &iter);
- g_mount_spec_to_dbus (&iter, spec);
- g_mount_spec_unref (spec);
-
- mount_source = g_mount_operation_dbus_wrap (mount_operation, _g_daemon_vfs_get_async_bus ());
- g_mount_source_to_dbus (mount_source, message);
- g_object_unref (mount_source);
-
data = g_new0 (MountData, 1);
data->callback = callback;
if (data->cancellable)
@@ -1821,13 +2044,13 @@ g_daemon_file_mount_enclosing_volume (GFile *location,
if (mount_operation)
data->mount_operation = g_object_ref (mount_operation);
- /* TODO: Ignoring cancellable here */
- _g_dbus_connection_call_async (_g_daemon_vfs_get_async_bus (),
- message,
- G_VFS_DBUS_MOUNT_TIMEOUT_MSECS,
- mount_reply, data);
-
- dbus_message_unref (message);
+ gvfs_dbus_mount_tracker_proxy_new_for_bus (G_BUS_TYPE_SESSION,
+ G_DBUS_PROXY_FLAGS_NONE,
+ G_VFS_DBUS_DAEMON_NAME,
+ G_VFS_DBUS_MOUNTTRACKER_PATH,
+ NULL,
+ mount_enclosing_volume_proxy_cb,
+ data);
}
static gboolean
@@ -1845,74 +2068,127 @@ g_daemon_file_query_filesystem_info (GFile *file,
GCancellable *cancellable,
GError **error)
{
- DBusMessage *reply;
- DBusMessageIter iter;
GFileInfo *info;
+ GVfsDBusMount *proxy;
+ char *path;
+ gboolean res;
+ GVariant *iter_info;
- if (attributes == NULL)
- attributes = "";
- reply = do_sync_path_call (file,
- G_VFS_DBUS_MOUNT_OP_QUERY_FILESYSTEM_INFO,
- NULL, NULL,
- cancellable, error,
- DBUS_TYPE_STRING, &attributes,
- 0);
- if (reply == NULL)
+ g_print ("g_daemon_file_query_filesystem_info\n");
+
+ proxy = create_proxy_for_file (file, NULL, &path, NULL, cancellable, error);
+ if (proxy == NULL)
return NULL;
- info = NULL;
+ iter_info = NULL;
+ res = gvfs_dbus_mount_call_query_filesystem_info_sync (proxy,
+ path,
+ attributes ? attributes : "",
+ &iter_info,
+ cancellable,
+ error);
- if (!dbus_message_iter_init (reply, &iter) ||
- (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRUCT))
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Invalid return value from %s"), "get_filesystem_info");
- goto out;
- }
+ g_print ("g_daemon_file_query_filesystem_info: done, res = %d\n", res);
- info = _g_dbus_get_file_info (&iter, error);
+ g_free (path);
+ g_object_unref (proxy);
+
+ if (! res)
+ return NULL;
+
+ info = _g_dbus_get_file_info (iter_info, error);
+ g_variant_unref (iter_info);
- out:
- dbus_message_unref (reply);
return info;
}
+
+typedef struct {
+ GFile *file;
+ char *attributes;
+ GFileQueryInfoFlags flags;
+ int io_priority;
+ GSimpleAsyncResult *result;
+ GCancellable *cancellable;
+} AsyncCallQueryFsInfo;
+
+static void
+async_call_query_fs_info_free (AsyncCallQueryFsInfo *data)
+{
+ if (data->file)
+ g_object_unref (data->file);
+ if (data->result)
+ g_object_unref (data->result);
+ if (data->cancellable)
+ g_object_unref (data->cancellable);
+ g_free (data->attributes);
+ g_free (data);
+}
+
static void
-query_fs_info_async_cb (DBusMessage *reply,
- DBusConnection *connection,
- GMountInfo *mount_info,
- GSimpleAsyncResult *result,
- GCancellable *cancellable,
- gpointer callback_data)
+query_fs_info_async_cb (GVfsDBusMount *proxy,
+ GAsyncResult *res,
+ gpointer user_data)
{
- DBusMessageIter iter;
+ AsyncCallQueryFsInfo *data = user_data;
GFileInfo *info;
- GError *error;
+ GError *error = NULL;
+ GSimpleAsyncResult *orig_result;
+ GVariant *iter_info;
- info = NULL;
+ g_print ("query_info_async_cb\n");
+ orig_result = data->result;
- if (!dbus_message_iter_init (reply, &iter) ||
- (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRUCT))
+ if (! gvfs_dbus_mount_call_query_filesystem_info_finish (proxy, &iter_info, res, &error))
{
- g_simple_async_result_set_error (result,
- G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Invalid return value from %s"), "query_info");
- _g_simple_async_result_complete_with_cancellable (result, cancellable);
- return;
+ g_simple_async_result_take_error (orig_result, error);
+ goto out;
}
- error = NULL;
- info = _g_dbus_get_file_info (&iter, &error);
+ info = _g_dbus_get_file_info (iter_info, &error);
+ g_variant_unref (iter_info);
+
if (info == NULL)
{
- g_simple_async_result_set_from_error (result, error);
- g_error_free (error);
- _g_simple_async_result_complete_with_cancellable (result, cancellable);
- return;
+ g_simple_async_result_take_error (orig_result, error);
+ goto out;
}
- g_simple_async_result_set_op_res_gpointer (result, info, g_object_unref);
- _g_simple_async_result_complete_with_cancellable (result, cancellable);
+ g_simple_async_result_set_op_res_gpointer (orig_result, info, g_object_unref);
+
+out:
+ _g_simple_async_result_complete_with_cancellable (orig_result, data->cancellable);
+ data->result = NULL;
+ g_object_unref (orig_result); /* trigger async_proxy_create_free() */
+}
+
+static void
+query_info_fs_async_get_proxy_cb (GVfsDBusMount *proxy,
+ GDBusConnection *connection,
+ GMountInfo *mount_info,
+ const gchar *path,
+ GSimpleAsyncResult *result,
+ GError *error,
+ GCancellable *cancellable,
+ gpointer callback_data)
+{
+ AsyncCallQueryFsInfo *data = callback_data;
+ char *uri;
+
+ g_print ("query_info_fs_async_get_proxy_cb, proxy = %p\n", proxy);
+
+ uri = g_file_get_uri (data->file);
+
+ data->result = g_object_ref (result);
+
+ gvfs_dbus_mount_call_query_filesystem_info (proxy,
+ path,
+ data->attributes ? data->attributes : "",
+ cancellable,
+ (GAsyncReadyCallback) query_fs_info_async_cb,
+ data);
+
+ g_free (uri);
}
static void
@@ -1923,13 +2199,22 @@ g_daemon_file_query_filesystem_info_async (GFile *file,
GAsyncReadyCallback callback,
gpointer user_data)
{
- do_async_path_call (file,
- G_VFS_DBUS_MOUNT_OP_QUERY_FILESYSTEM_INFO,
- cancellable,
- callback, user_data,
- query_fs_info_async_cb, NULL, NULL,
- DBUS_TYPE_STRING, &attributes,
- 0);
+ AsyncCallQueryFsInfo *data;
+
+ g_print ("g_daemon_file_query_filesystem_info_async\n");
+
+ data = g_new0 (AsyncCallQueryFsInfo, 1);
+ data->file = g_object_ref (file);
+ data->attributes = g_strdup (attributes);
+ data->io_priority = io_priority;
+ if (cancellable)
+ data->cancellable = g_object_ref (cancellable);
+
+ create_proxy_for_file_async (file,
+ cancellable,
+ callback, user_data,
+ query_info_fs_async_get_proxy_cb,
+ data, (GDestroyNotify) async_call_query_fs_info_free);
}
static GFileInfo *
@@ -1958,6 +2243,7 @@ g_daemon_file_find_enclosing_mount (GFile *file,
mount_info = _g_daemon_vfs_get_mount_info_sync (daemon_file->mount_spec,
daemon_file->path,
+ cancellable,
error);
if (mount_info == NULL)
return NULL;
@@ -1995,8 +2281,9 @@ g_daemon_file_get_child_for_display_name (GFile *file,
GFile *child;
mount_info = _g_daemon_vfs_get_mount_info_sync (daemon_file->mount_spec,
- daemon_file->path,
- NULL);
+ daemon_file->path,
+ NULL, /* TODO: cancellable */
+ NULL);
if (mount_info && mount_info->prefered_filename_encoding)
@@ -2031,43 +2318,39 @@ g_daemon_file_set_display_name (GFile *file,
{
GDaemonFile *daemon_file;
GMountInfo *mount_info;
- DBusMessage *reply;
- DBusMessageIter iter;
char *new_path;
+ GVfsDBusMount *proxy;
+ char *path;
+ gboolean res;
daemon_file = G_DAEMON_FILE (file);
-
mount_info = NULL;
- reply = do_sync_path_call (file,
- G_VFS_DBUS_MOUNT_OP_SET_DISPLAY_NAME,
- &mount_info, NULL,
- cancellable, error,
- DBUS_TYPE_STRING, &display_name,
- 0);
- if (reply == NULL)
- {
- if (mount_info)
- g_mount_info_unref (mount_info);
- return NULL;
- }
+ g_print ("g_daemon_file_set_display_name\n");
- if (!dbus_message_iter_init (reply, &iter) ||
- !_g_dbus_message_iter_get_args (&iter, NULL,
- G_DBUS_TYPE_CSTRING, &new_path,
- 0))
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Invalid return value from %s"), "query_filesystem_info");
- goto out;
- }
+ proxy = create_proxy_for_file (file, &mount_info, &path, NULL, cancellable, error);
+ if (proxy == NULL)
+ return NULL;
+
+ res = gvfs_dbus_mount_call_set_display_name_sync (proxy,
+ path,
+ display_name,
+ &new_path,
+ cancellable,
+ error);
+ g_print ("g_daemon_file_set_display_name: done, res = %d\n", res);
+
+ g_free (path);
+ g_object_unref (proxy);
+ if (! res)
+ goto out;
+
g_mount_info_apply_prefix (mount_info, &new_path);
file = new_file_for_new_path (daemon_file, new_path);
g_free (new_path);
out:
g_mount_info_unref (mount_info);
- dbus_message_unref (reply);
return file;
}
@@ -2076,18 +2359,26 @@ g_daemon_file_delete (GFile *file,
GCancellable *cancellable,
GError **error)
{
- DBusMessage *reply;
+ GVfsDBusMount *proxy;
+ char *path;
+ gboolean res;
+
+ g_print ("g_daemon_file_delete\n");
- reply = do_sync_path_call (file,
- G_VFS_DBUS_MOUNT_OP_DELETE,
- NULL, NULL,
- cancellable, error,
- 0);
- if (reply == NULL)
+ proxy = create_proxy_for_file (file, NULL, &path, NULL, cancellable, error);
+ if (proxy == NULL)
return FALSE;
- dbus_message_unref (reply);
- return TRUE;
+ res = gvfs_dbus_mount_call_delete_sync (proxy,
+ path,
+ cancellable,
+ error);
+ g_print ("g_daemon_file_delete: done, res = %d\n", res);
+
+ g_free (path);
+ g_object_unref (proxy);
+
+ return res;
}
static gboolean
@@ -2095,18 +2386,26 @@ g_daemon_file_trash (GFile *file,
GCancellable *cancellable,
GError **error)
{
- DBusMessage *reply;
+ GVfsDBusMount *proxy;
+ char *path;
+ gboolean res;
+
+ g_print ("g_daemon_file_trash\n");
- reply = do_sync_path_call (file,
- G_VFS_DBUS_MOUNT_OP_TRASH,
- NULL, NULL,
- cancellable, error,
- 0);
- if (reply == NULL)
+ proxy = create_proxy_for_file (file, NULL, &path, NULL, cancellable, error);
+ if (proxy == NULL)
return FALSE;
- dbus_message_unref (reply);
- return TRUE;
+ res = gvfs_dbus_mount_call_trash_sync (proxy,
+ path,
+ cancellable,
+ error);
+ g_print ("g_daemon_file_trash: done, res = %d\n", res);
+
+ g_free (path);
+ g_object_unref (proxy);
+
+ return res;
}
static gboolean
@@ -2114,18 +2413,26 @@ g_daemon_file_make_directory (GFile *file,
GCancellable *cancellable,
GError **error)
{
- DBusMessage *reply;
+ GVfsDBusMount *proxy;
+ char *path;
+ gboolean res;
+
+ g_print ("g_daemon_file_make_directory\n");
- reply = do_sync_path_call (file,
- G_VFS_DBUS_MOUNT_OP_MAKE_DIRECTORY,
- NULL, NULL,
- cancellable, error,
- 0);
- if (reply == NULL)
+ proxy = create_proxy_for_file (file, NULL, &path, NULL, cancellable, error);
+ if (proxy == NULL)
return FALSE;
- dbus_message_unref (reply);
- return TRUE;
+ res = gvfs_dbus_mount_call_make_directory_sync (proxy,
+ path,
+ cancellable,
+ error);
+ g_print ("g_daemon_file_make_directory: done, res = %d\n", res);
+
+ g_free (path);
+ g_object_unref (proxy);
+
+ return res;
}
static gboolean
@@ -2134,19 +2441,27 @@ g_daemon_file_make_symbolic_link (GFile *file,
GCancellable *cancellable,
GError **error)
{
- DBusMessage *reply;
+ GVfsDBusMount *proxy;
+ char *path;
+ gboolean res;
- reply = do_sync_path_call (file,
- G_VFS_DBUS_MOUNT_OP_MAKE_SYMBOLIC_LINK,
- NULL, NULL,
- cancellable, error,
- G_DBUS_TYPE_CSTRING, &symlink_value,
- 0);
- if (reply == NULL)
+ g_print ("g_daemon_file_make_symbolic_link\n");
+
+ proxy = create_proxy_for_file (file, NULL, &path, NULL, cancellable, error);
+ if (proxy == NULL)
return FALSE;
- dbus_message_unref (reply);
- return TRUE;
+ res = gvfs_dbus_mount_call_make_symbolic_link_sync (proxy,
+ path,
+ symlink_value,
+ cancellable,
+ error);
+ g_print ("g_daemon_file_make_symbolic_link: done, res = %d\n", res);
+
+ g_free (path);
+ g_object_unref (proxy);
+
+ return res;
}
static GFileAttributeInfoList *
@@ -2154,22 +2469,34 @@ g_daemon_file_query_settable_attributes (GFile *file,
GCancellable *cancellable,
GError **error)
{
- DBusMessage *reply;
+ GVfsDBusMount *proxy;
+ char *path;
+ gboolean res;
+ GVariant *iter_list;
GFileAttributeInfoList *list;
- DBusMessageIter iter;
-
- reply = do_sync_path_call (file,
- G_VFS_DBUS_MOUNT_OP_QUERY_SETTABLE_ATTRIBUTES,
- NULL, NULL,
- cancellable, error,
- 0);
- if (reply == NULL)
+
+ g_print ("g_daemon_file_query_settable_attributes\n");
+
+ proxy = create_proxy_for_file (file, NULL, &path, NULL, cancellable, error);
+ if (proxy == NULL)
+ return FALSE;
+
+ iter_list = NULL;
+ res = gvfs_dbus_mount_call_query_settable_attributes_sync (proxy,
+ path,
+ &iter_list,
+ cancellable,
+ error);
+ g_print ("g_daemon_file_query_settable_attributes: done, res = %d\n", res);
+
+ g_free (path);
+ g_object_unref (proxy);
+
+ if (!res)
return NULL;
- dbus_message_iter_init (reply, &iter);
- list = _g_dbus_get_attribute_info_list (&iter, error);
-
- dbus_message_unref (reply);
+ list = _g_dbus_get_attribute_info_list (iter_list, error);
+ g_variant_unref (iter_list);
return list;
}
@@ -2179,20 +2506,33 @@ g_daemon_file_query_writable_namespaces (GFile *file,
GCancellable *cancellable,
GError **error)
{
- DBusMessage *reply;
+ GVfsDBusMount *proxy;
+ char *path;
+ gboolean res;
+ GVariant *iter_list;
GFileAttributeInfoList *list;
- DBusMessageIter iter;
-
- reply = do_sync_path_call (file,
- G_VFS_DBUS_MOUNT_OP_QUERY_WRITABLE_NAMESPACES,
- NULL, NULL,
- cancellable, error,
- 0);
- if (reply)
+
+ g_print ("g_daemon_file_query_writable_namespaces\n");
+
+ proxy = create_proxy_for_file (file, NULL, &path, NULL, cancellable, error);
+ if (proxy == NULL)
+ return FALSE;
+
+ iter_list = NULL;
+ res = gvfs_dbus_mount_call_query_writable_namespaces_sync (proxy,
+ path,
+ &iter_list,
+ cancellable,
+ error);
+ g_print ("g_daemon_file_query_writable_namespaces: done, res = %d\n", res);
+
+ g_free (path);
+ g_object_unref (proxy);
+
+ if (res)
{
- dbus_message_iter_init (reply, &iter);
- list = _g_dbus_get_attribute_info_list (&iter, error);
- dbus_message_unref (reply);
+ list = _g_dbus_get_attribute_info_list (iter_list, error);
+ g_variant_unref (iter_list);
}
else
{
@@ -2200,11 +2540,11 @@ g_daemon_file_query_writable_namespaces (GFile *file,
}
g_file_attribute_info_list_add (list,
- "metadata",
- G_FILE_ATTRIBUTE_TYPE_STRING, /* Also STRINGV, but no way express this ... */
- G_FILE_ATTRIBUTE_INFO_COPY_WITH_FILE |
- G_FILE_ATTRIBUTE_INFO_COPY_WHEN_MOVED);
-
+ "metadata",
+ G_FILE_ATTRIBUTE_TYPE_STRING, /* Also STRINGV, but no way express this ... */
+ G_FILE_ATTRIBUTE_INFO_COPY_WITH_FILE |
+ G_FILE_ATTRIBUTE_INFO_COPY_WHEN_MOVED);
+
return list;
}
@@ -2282,38 +2622,34 @@ g_daemon_file_set_attribute (GFile *file,
GCancellable *cancellable,
GError **error)
{
- DBusMessage *message, *reply;
- DBusMessageIter iter;
- dbus_uint32_t flags_dbus;
+ GVfsDBusMount *proxy;
+ char *path;
+ gboolean res;
GError *my_error;
if (g_str_has_prefix (attribute, "metadata::"))
return set_metadata_attribute (file, attribute, type, value_p, cancellable, error);
retry:
-
- message = create_empty_message (file, G_VFS_DBUS_MOUNT_OP_SET_ATTRIBUTE, NULL, error);
- if (!message)
- return FALSE;
-
- dbus_message_iter_init_append (message, &iter);
-
- flags_dbus = flags;
- dbus_message_iter_append_basic (&iter,
- DBUS_TYPE_UINT32,
- &flags_dbus);
+ g_print ("g_daemon_file_set_attribute\n");
- _g_dbus_append_file_attribute (&iter, attribute, 0, type, value_p);
+ proxy = create_proxy_for_file (file, NULL, &path, NULL, cancellable, error);
+ if (proxy == NULL)
+ return FALSE;
my_error = NULL;
- reply = _g_vfs_daemon_call_sync (message,
- NULL,
- NULL, NULL, NULL,
- cancellable, &my_error);
+ res = gvfs_dbus_mount_call_set_attribute_sync (proxy,
+ path,
+ flags,
+ _g_dbus_append_file_attribute (attribute, 0, type, value_p),
+ cancellable,
+ &my_error);
+ g_print ("g_daemon_file_set_attribute: done, res = %d\n", res);
- dbus_message_unref (message);
+ g_free (path);
+ g_object_unref (proxy);
- if (reply == NULL)
+ if (! res)
{
if (g_error_matches (my_error, G_VFS_ERROR, G_VFS_ERROR_RETRY))
{
@@ -2324,38 +2660,28 @@ g_daemon_file_set_attribute (GFile *file,
return FALSE;
}
- dbus_message_unref (reply);
return TRUE;
}
-struct ProgressCallbackData {
+typedef struct {
GFileProgressCallback progress_callback;
gpointer progress_callback_data;
-};
+} ProgressCallbackData;
-static DBusHandlerResult
-progress_callback_message (DBusConnection *connection,
- DBusMessage *message,
- void *user_data)
+static gboolean
+handle_progress (GVfsDBusProgress *object,
+ GDBusMethodInvocation *invocation,
+ guint64 arg_current,
+ guint64 arg_total,
+ ProgressCallbackData *data)
{
- struct ProgressCallbackData *data = user_data;
- dbus_uint64_t current_dbus, total_dbus;
+ g_print ("handle_progress\n");
- if (dbus_message_is_method_call (message,
- G_VFS_DBUS_PROGRESS_INTERFACE,
- G_VFS_DBUS_PROGRESS_OP_PROGRESS))
- {
- if (dbus_message_get_args (message, NULL,
- DBUS_TYPE_UINT64, &current_dbus,
- DBUS_TYPE_UINT64, &total_dbus,
- 0))
- data->progress_callback (current_dbus, total_dbus, data->progress_callback_data);
- }
- else
- g_warning ("Unknown progress callback message type\n");
+ data->progress_callback (arg_current, arg_total, data->progress_callback_data);
+
+ gvfs_dbus_progress_complete_progress (object, invocation);
- /* TODO: demarshal args and call reall callback */
- return DBUS_HANDLER_RESULT_HANDLED;
+ return TRUE;
}
static gboolean
@@ -2368,17 +2694,23 @@ file_transfer (GFile *source,
gpointer progress_callback_data,
GError **error)
{
- DBusMessage *reply;
- char *obj_path, *dbus_obj_path;
- dbus_uint32_t flags_dbus;
- dbus_bool_t dbus_remove_source;
- struct ProgressCallbackData data;
+ char *obj_path;
+ ProgressCallbackData data;
char *local_path = NULL;
gboolean source_is_daemon;
gboolean dest_is_daemon;
gboolean native_transfer;
gboolean send_progress;
+ GVfsDBusMount *proxy;
+ gchar *path1, *path2;
+ GDBusConnection *connection;
+ gboolean res;
+ GVfsDBusProgress *progress_skeleton;
+ GFile *file1, *file2;
+ GError *my_error;
+ res = FALSE;
+ progress_skeleton = NULL;
native_transfer = FALSE;
source_is_daemon = G_IS_DAEMON_FILE (source);
dest_is_daemon = G_IS_DAEMON_FILE (destination);
@@ -2408,76 +2740,126 @@ file_transfer (GFile *source,
}
if (progress_callback)
+ obj_path = g_strdup_printf ("/org/gtk/vfs/callback/%p", &obj_path);
+ else
+ obj_path = g_strdup ("/org/gtk/vfs/void");
+
+ data.progress_callback = progress_callback;
+ data.progress_callback_data = progress_callback_data;
+
+ /* need to create proxy with daemon files only */
+ if (native_transfer)
{
- obj_path = g_strdup_printf ("/org/gtk/vfs/callback/%p", &obj_path);
- dbus_obj_path = obj_path;
+ file1 = source;
+ file2 = destination;
}
else
{
- obj_path = NULL;
- /* Can't pass NULL obj path as arg */
- dbus_obj_path = "/org/gtk/vfs/void";
+ if (dest_is_daemon)
+ {
+ file1 = destination;
+ file2 = NULL;
+ }
+ else
+ {
+ file1 = source;
+ file2 = NULL;
+ }
}
+
+retry:
+ my_error = NULL;
- data.progress_callback = progress_callback;
- data.progress_callback_data = progress_callback_data;
+ proxy = create_proxy_for_file2 (file1, file2,
+ NULL, NULL,
+ &path1, &path2,
+ &connection,
+ cancellable,
+ &my_error);
+
+ if (proxy == NULL)
+ goto out;
+
+ /* Register progress interface skeleton */
+ progress_skeleton = gvfs_dbus_progress_skeleton_new ();
+ g_dbus_interface_skeleton_set_flags (G_DBUS_INTERFACE_SKELETON (progress_skeleton), G_DBUS_INTERFACE_SKELETON_FLAGS_HANDLE_METHOD_INVOCATIONS_IN_THREAD);
+ g_signal_connect (progress_skeleton, "handle-progress", G_CALLBACK (handle_progress), &data);
- flags_dbus = flags;
- dbus_remove_source = remove_source;
+ if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (progress_skeleton),
+ connection,
+ obj_path,
+ &my_error))
+ goto out;
if (native_transfer == TRUE)
{
- const char *method_string;
-
if (remove_source == FALSE)
- method_string = G_VFS_DBUS_MOUNT_OP_COPY;
+ {
+ res = gvfs_dbus_mount_call_copy_sync (proxy,
+ path1, path2,
+ flags,
+ obj_path,
+ cancellable,
+ &my_error);
+ }
else
- method_string = G_VFS_DBUS_MOUNT_OP_MOVE;
-
- reply = do_sync_2_path_call (source, destination,
- method_string,
- obj_path, progress_callback_message, &data,
- NULL, cancellable, error,
- DBUS_TYPE_UINT32, &flags_dbus,
- DBUS_TYPE_OBJECT_PATH, &dbus_obj_path,
- 0);
+ {
+ res = gvfs_dbus_mount_call_move_sync (proxy,
+ path1, path2,
+ flags,
+ obj_path,
+ cancellable,
+ &my_error);
+ }
}
else if (dest_is_daemon == TRUE)
{
- reply = do_sync_2_path_call (destination, NULL,
- G_VFS_DBUS_MOUNT_OP_PUSH,
- obj_path, progress_callback_message, &data,
- NULL, cancellable, error,
- G_DBUS_TYPE_CSTRING, &local_path,
- DBUS_TYPE_BOOLEAN, &send_progress,
- DBUS_TYPE_UINT32, &flags_dbus,
- DBUS_TYPE_OBJECT_PATH, &dbus_obj_path,
- DBUS_TYPE_BOOLEAN, &dbus_remove_source,
- 0);
+ res = gvfs_dbus_mount_call_push_sync (proxy,
+ path1,
+ local_path,
+ send_progress,
+ flags,
+ obj_path,
+ remove_source,
+ cancellable,
+ &my_error);
}
else
{
- reply = do_sync_2_path_call (source, NULL,
- G_VFS_DBUS_MOUNT_OP_PULL,
- obj_path, progress_callback_message, &data,
- NULL, cancellable, error,
- G_DBUS_TYPE_CSTRING, &local_path,
- DBUS_TYPE_BOOLEAN, &send_progress,
- DBUS_TYPE_UINT32, &flags_dbus,
- DBUS_TYPE_OBJECT_PATH, &dbus_obj_path,
- DBUS_TYPE_BOOLEAN, &dbus_remove_source,
- 0);
+ res = gvfs_dbus_mount_call_pull_sync (proxy,
+ path1,
+ local_path,
+ send_progress,
+ flags,
+ obj_path,
+ remove_source,
+ cancellable,
+ &my_error);
+ }
+ out:
+ if (progress_skeleton)
+ {
+ g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (progress_skeleton));
+ g_object_unref (progress_skeleton);
+ }
+ if (proxy)
+ g_object_unref (proxy);
+
+ if (! res)
+ {
+ if (g_error_matches (my_error, G_VFS_ERROR, G_VFS_ERROR_RETRY))
+ {
+ g_error_free (my_error);
+ goto retry;
+ }
+ g_propagate_error (error, my_error);
}
g_free (local_path);
g_free (obj_path);
- if (reply == NULL)
- return FALSE;
-
- dbus_message_unref (reply);
- return TRUE;
+ return res;
}
static gboolean
@@ -2533,45 +2915,44 @@ g_daemon_file_monitor_dir (GFile* file,
GError **error)
{
GFileMonitor *monitor;
- char *obj_path;
- dbus_uint32_t flags_dbus;
GMountInfo *mount_info;
- DBusMessage *reply;
+ GVfsDBusMount *proxy;
+ char *path;
+ char *obj_path;
+ gboolean res;
- flags_dbus = flags;
+ g_print ("g_daemon_file_monitor_dir\n");
+ monitor = NULL;
mount_info = NULL;
- reply = do_sync_path_call (file,
- G_VFS_DBUS_MOUNT_OP_CREATE_DIR_MONITOR,
- &mount_info, NULL,
- cancellable, error,
- DBUS_TYPE_UINT32, &flags_dbus,
- 0);
-
- if (reply == NULL)
- {
- if (mount_info)
- g_mount_info_unref (mount_info);
- return NULL;
- }
+ obj_path = NULL;
+
+ proxy = create_proxy_for_file (file, &mount_info, &path, NULL, cancellable, error);
+ if (proxy == NULL)
+ return FALSE;
+
- if (!dbus_message_get_args (reply, NULL,
- DBUS_TYPE_OBJECT_PATH, &obj_path,
- DBUS_TYPE_INVALID))
- {
- g_mount_info_unref (mount_info);
- dbus_message_unref (reply);
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Invalid return value from %s"), "monitor_dir");
- return NULL;
- }
+ res = gvfs_dbus_mount_call_create_directory_monitor_sync (proxy,
+ path,
+ flags,
+ &obj_path,
+ cancellable,
+ error);
+ g_print ("g_daemon_file_monitor_dir: done, res = %d\n", res);
+
+ g_free (path);
+ g_object_unref (proxy);
+
+ if (! res)
+ goto out;
monitor = g_daemon_file_monitor_new (mount_info->dbus_id,
obj_path);
+ out:
g_mount_info_unref (mount_info);
- dbus_message_unref (reply);
-
+ g_free (obj_path);
+
return monitor;
}
@@ -2582,114 +2963,151 @@ g_daemon_file_monitor_file (GFile* file,
GError **error)
{
GFileMonitor *monitor;
- char *obj_path;
- dbus_uint32_t flags_dbus;
GMountInfo *mount_info;
- DBusMessage *reply;
+ GVfsDBusMount *proxy;
+ char *path;
+ char *obj_path;
+ gboolean res;
- flags_dbus = flags;
+ g_print ("g_daemon_file_monitor_file\n");
+ monitor = NULL;
mount_info = NULL;
- reply = do_sync_path_call (file,
- G_VFS_DBUS_MOUNT_OP_CREATE_FILE_MONITOR,
- &mount_info, NULL,
- cancellable, error,
- DBUS_TYPE_UINT32, &flags_dbus,
- 0);
-
- if (reply == NULL)
- {
- if (mount_info)
- g_mount_info_unref (mount_info);
- return NULL;
- }
+ obj_path = NULL;
+
+ proxy = create_proxy_for_file (file, &mount_info, &path, NULL, cancellable, error);
+ if (proxy == NULL)
+ return FALSE;
+
- if (!dbus_message_get_args (reply, NULL,
- DBUS_TYPE_OBJECT_PATH, &obj_path,
- DBUS_TYPE_INVALID))
- {
- g_mount_info_unref (mount_info);
- dbus_message_unref (reply);
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Invalid return value from %s"), "monitor_file");
- return NULL;
- }
+ res = gvfs_dbus_mount_call_create_file_monitor_sync (proxy,
+ path,
+ flags,
+ &obj_path,
+ cancellable,
+ error);
+ g_print ("g_daemon_file_monitor_file: done, res = %d\n", res);
+
+ g_free (path);
+ g_object_unref (proxy);
+
+ if (! res)
+ goto out;
monitor = g_daemon_file_monitor_new (mount_info->dbus_id,
- obj_path);
+ obj_path);
+ out:
g_mount_info_unref (mount_info);
- dbus_message_unref (reply);
-
+ g_free (obj_path);
+
return monitor;
}
-typedef struct
-{
- GSimpleAsyncResult *result;
- GCancellable *cancellable;
- dbus_bool_t can_seek;
- guint64 initial_offset;
-}
-StreamOpenParams;
static void
-stream_open_cb (gint fd, StreamOpenParams *params)
+file_open_write_async_cb (GVfsDBusMount *proxy,
+ GAsyncResult *res,
+ gpointer user_data)
{
+ AsyncCallFileReadWrite *data = user_data;
+ GError *error = NULL;
+ GSimpleAsyncResult *orig_result;
+ gboolean can_seek;
+ GUnixFDList *fd_list;
+ int fd;
+ guint fd_id;
+ guint64 initial_offset;
GFileOutputStream *output_stream;
- if (fd == -1)
+ g_print ("file_open_write_async_cb\n");
+ orig_result = data->result;
+
+ if (! gvfs_dbus_mount_call_open_for_write_finish (proxy, &fd_id, &can_seek, &initial_offset, &fd_list, res, &error))
{
- g_simple_async_result_set_error (params->result, G_IO_ERROR, G_IO_ERROR_FAILED,
- "%s", _("Didn't get stream file descriptor"));
+ g_simple_async_result_take_error (orig_result, error);
goto out;
}
- output_stream = g_daemon_file_output_stream_new (fd, params->can_seek, params->initial_offset);
- g_simple_async_result_set_op_res_gpointer (params->result, output_stream, g_object_unref);
+ if (fd_list == NULL || g_unix_fd_list_get_length (fd_list) != 1 ||
+ (fd = g_unix_fd_list_get (fd_list, fd_id, NULL)) == -1)
+ {
+ g_simple_async_result_set_error (orig_result,
+ G_IO_ERROR, G_IO_ERROR_FAILED,
+ _("Couldn't get stream file descriptor"));
+ }
+ else
+ {
+ output_stream = g_daemon_file_output_stream_new (fd, can_seek, initial_offset);
+ g_simple_async_result_set_op_res_gpointer (orig_result, output_stream, g_object_unref);
+ g_object_unref (fd_list);
+ }
out:
- _g_simple_async_result_complete_with_cancellable (params->result, params->cancellable);
- if (params->cancellable)
- g_object_unref (params->cancellable);
- g_object_unref (params->result);
- g_slice_free (StreamOpenParams, params);
+ _g_simple_async_result_complete_with_cancellable (orig_result, data->cancellable);
+ data->result = NULL;
+ g_object_unref (orig_result); /* trigger async_proxy_create_free() */
}
static void
-append_to_async_cb (DBusMessage *reply,
- DBusConnection *connection,
- GMountInfo *mount_info,
- GSimpleAsyncResult *result,
- GCancellable *cancellable,
- gpointer callback_data)
+file_open_write_async_get_proxy_cb (GVfsDBusMount *proxy,
+ GDBusConnection *connection,
+ GMountInfo *mount_info,
+ const gchar *path,
+ GSimpleAsyncResult *result,
+ GError *error,
+ GCancellable *cancellable,
+ gpointer callback_data)
{
- guint32 fd_id;
- StreamOpenParams *open_params;
+ AsyncCallFileReadWrite *data = callback_data;
+ guint32 pid;
- open_params = g_slice_new0 (StreamOpenParams);
+ g_print ("file_open_write_async_get_proxy_cb, proxy = %p\n", proxy);
- if (!dbus_message_get_args (reply, NULL,
- DBUS_TYPE_UINT32, &fd_id,
- DBUS_TYPE_BOOLEAN, &open_params->can_seek,
- DBUS_TYPE_UINT64, &open_params->initial_offset,
- DBUS_TYPE_INVALID))
- {
- g_simple_async_result_set_error (result, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Invalid return value from %s"), "open");
- goto failure;
- }
+ pid = get_pid_for_file (data->file);
+
+ data->result = g_object_ref (result);
+
+ gvfs_dbus_mount_call_open_for_write (proxy,
+ path,
+ data->mode,
+ data->etag,
+ data->make_backup,
+ data->flags,
+ pid,
+ NULL,
+ cancellable,
+ (GAsyncReadyCallback) file_open_write_async_cb,
+ data);
+}
- open_params->result = g_object_ref (result);
+static void
+file_open_write_async (GFile *file,
+ guint16 mode,
+ const char *etag,
+ gboolean make_backup,
+ GFileCreateFlags flags,
+ int io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ AsyncCallFileReadWrite *data;
+
+ data = g_new0 (AsyncCallFileReadWrite, 1);
+ data->file = g_object_ref (file);
+ data->mode = mode;
+ data->etag = g_strdup (etag ? etag : "");
+ data->make_backup = make_backup;
+ data->io_priority = io_priority;
if (cancellable)
- open_params->cancellable = g_object_ref (cancellable);
- _g_dbus_connection_get_fd_async (connection, fd_id,
- (GetFdAsyncCallback) stream_open_cb, open_params);
- return;
+ data->cancellable = g_object_ref (cancellable);
-failure:
- g_slice_free (StreamOpenParams, open_params);
- _g_simple_async_result_complete_with_cancellable (result, cancellable);
+ create_proxy_for_file_async (file,
+ cancellable,
+ callback, user_data,
+ file_open_write_async_get_proxy_cb,
+ data, (GDestroyNotify) async_call_file_read_write_free);
}
static void
@@ -2700,30 +3118,12 @@ g_daemon_file_append_to_async (GFile *file,
GAsyncReadyCallback callback,
gpointer user_data)
{
- guint16 mode;
- dbus_bool_t make_backup;
- guint32 dbus_flags;
- char *etag;
- guint32 pid;
-
- pid = get_pid_for_file (file);
-
- mode = 1;
- etag = "";
- make_backup = FALSE;
- dbus_flags = flags;
+ g_print ("g_daemon_file_append_to_async\n");
- do_async_path_call (file,
- G_VFS_DBUS_MOUNT_OP_OPEN_FOR_WRITE,
- cancellable,
- callback, user_data,
- append_to_async_cb, NULL, NULL,
- DBUS_TYPE_UINT16, &mode,
- DBUS_TYPE_STRING, &etag,
- DBUS_TYPE_BOOLEAN, &make_backup,
- DBUS_TYPE_UINT32, &dbus_flags,
- DBUS_TYPE_UINT32, &pid,
- 0);
+ file_open_write_async (file,
+ 1, "", FALSE, flags, io_priority,
+ cancellable,
+ callback, user_data);
}
static GFileOutputStream *
@@ -2742,40 +3142,6 @@ g_daemon_file_append_to_finish (GFile *file,
}
static void
-create_async_cb (DBusMessage *reply,
- DBusConnection *connection,
- GMountInfo *mount_info,
- GSimpleAsyncResult *result,
- GCancellable *cancellable,
- gpointer callback_data)
-{
- guint32 fd_id;
- StreamOpenParams *open_params;
-
- open_params = g_slice_new0 (StreamOpenParams);
-
- if (!dbus_message_get_args (reply, NULL,
- DBUS_TYPE_UINT32, &fd_id,
- DBUS_TYPE_BOOLEAN, &open_params->can_seek,
- DBUS_TYPE_UINT64, &open_params->initial_offset,
- DBUS_TYPE_INVALID))
- {
- g_simple_async_result_set_error (result, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Invalid return value from %s"), "open");
- goto failure;
- }
-
- open_params->result = g_object_ref (result);
- _g_dbus_connection_get_fd_async (connection, fd_id,
- (GetFdAsyncCallback) stream_open_cb, open_params);
- return;
-
-failure:
- g_slice_free (StreamOpenParams, open_params);
- _g_simple_async_result_complete_with_cancellable (result, cancellable);
-}
-
-static void
g_daemon_file_create_async (GFile *file,
GFileCreateFlags flags,
int io_priority,
@@ -2783,30 +3149,12 @@ g_daemon_file_create_async (GFile *file,
GAsyncReadyCallback callback,
gpointer user_data)
{
- guint16 mode;
- dbus_bool_t make_backup;
- char *etag;
- guint32 dbus_flags;
- guint32 pid;
-
- pid = get_pid_for_file (file);
-
- mode = 0;
- etag = "";
- make_backup = FALSE;
- dbus_flags = flags;
+ g_print ("g_daemon_file_create_async\n");
- do_async_path_call (file,
- G_VFS_DBUS_MOUNT_OP_OPEN_FOR_WRITE,
- cancellable,
- callback, user_data,
- create_async_cb, NULL, NULL,
- DBUS_TYPE_UINT16, &mode,
- DBUS_TYPE_STRING, &etag,
- DBUS_TYPE_BOOLEAN, &make_backup,
- DBUS_TYPE_UINT32, &dbus_flags,
- DBUS_TYPE_UINT32, &pid,
- 0);
+ file_open_write_async (file,
+ 0, "", FALSE, flags, io_priority,
+ cancellable,
+ callback, user_data);
}
static GFileOutputStream *
@@ -2824,29 +3172,95 @@ g_daemon_file_create_finish (GFile *file,
return NULL;
}
+
+typedef struct {
+ GFile *file;
+ char *attributes;
+ GFileQueryInfoFlags flags;
+ int io_priority;
+ GSimpleAsyncResult *result;
+ GCancellable *cancellable;
+ GDaemonFileEnumerator *enumerator;
+} AsyncCallEnumerate;
+
static void
-enumerate_children_async_cb (DBusMessage *reply,
- DBusConnection *connection,
- GMountInfo *mount_info,
- GSimpleAsyncResult *result,
- GCancellable *cancellable,
- gpointer callback_data)
+async_call_enumerate_free (AsyncCallEnumerate *data)
{
- GDaemonFileEnumerator *enumerator = callback_data;
+ g_print ("async_call_enumerate_free\n");
+
+ if (data->file)
+ g_object_unref (data->file);
+ if (data->result)
+ g_object_unref (data->result);
+ if (data->cancellable)
+ g_object_unref (data->cancellable);
+ if (data->enumerator)
+ g_object_unref (data->enumerator);
+ g_free (data->attributes);
+ g_free (data);
+}
- if (reply == NULL || connection == NULL)
- {
- g_simple_async_result_set_error (result, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Invalid return value from %s"), "enumerate_children");
- goto out;
- }
+static void
+enumerate_children_async_cb (GVfsDBusMount *proxy,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ AsyncCallEnumerate *data = user_data;
+ GError *error = NULL;
+ GSimpleAsyncResult *orig_result;
- g_object_ref (enumerator);
+ g_print ("enumerate_children_async_cb\n");
+ orig_result = data->result;
+
+ if (! gvfs_dbus_mount_call_enumerate_finish (proxy, res, &error))
+ {
+ g_simple_async_result_take_error (orig_result, error);
+ goto out;
+ }
+
+ g_object_ref (data->enumerator);
- g_simple_async_result_set_op_res_gpointer (result, enumerator, g_object_unref);
+ g_simple_async_result_set_op_res_gpointer (orig_result, data->enumerator, g_object_unref);
out:
- _g_simple_async_result_complete_with_cancellable (result, cancellable);
+ _g_simple_async_result_complete_with_cancellable (orig_result, data->cancellable);
+ data->result = NULL;
+ g_object_unref (orig_result); /* trigger async_proxy_create_free() */
+}
+
+static void
+enumerate_children_async_get_proxy_cb (GVfsDBusMount *proxy,
+ GDBusConnection *connection,
+ GMountInfo *mount_info,
+ const gchar *path,
+ GSimpleAsyncResult *result,
+ GError *error,
+ GCancellable *cancellable,
+ gpointer callback_data)
+{
+ AsyncCallEnumerate *data = callback_data;
+ char *obj_path;
+ char *uri;
+
+ g_print ("enumerate_children_async_get_proxy_cb, proxy = %p\n", proxy);
+
+ obj_path = g_daemon_file_enumerator_get_object_path (data->enumerator);
+ uri = g_file_get_uri (data->file);
+
+ data->result = g_object_ref (result);
+
+ gvfs_dbus_mount_call_enumerate (proxy,
+ path,
+ obj_path,
+ data->attributes ? data->attributes : "",
+ data->flags,
+ uri,
+ cancellable,
+ (GAsyncReadyCallback) enumerate_children_async_cb,
+ data);
+
+ g_free (uri);
+ g_free (obj_path);
}
static void
@@ -2858,31 +3272,24 @@ g_daemon_file_enumerate_children_async (GFile *file,
GAsyncReadyCallback callback,
gpointer user_data)
{
- dbus_uint32_t flags_dbus;
- char *obj_path;
- GDaemonFileEnumerator *enumerator;
- char *uri;
+ AsyncCallEnumerate *data;
- enumerator = g_daemon_file_enumerator_new (file, attributes);
- obj_path = g_daemon_file_enumerator_get_object_path (enumerator);
+ g_print ("g_daemon_file_enumerate_children_async\n");
- uri = g_file_get_uri (file);
+ data = g_new0 (AsyncCallEnumerate, 1);
+ data->file = g_object_ref (file);
+ data->attributes = g_strdup (attributes);
+ data->flags = flags;
+ data->io_priority = io_priority;
+ if (cancellable)
+ data->cancellable = g_object_ref (cancellable);
+ data->enumerator = g_daemon_file_enumerator_new (data->file, data->attributes);
- if (attributes == NULL)
- attributes = "";
- flags_dbus = flags;
- do_async_path_call (file,
- G_VFS_DBUS_MOUNT_OP_ENUMERATE,
- cancellable,
- callback, user_data,
- enumerate_children_async_cb, enumerator, g_object_unref,
- DBUS_TYPE_STRING, &obj_path,
- DBUS_TYPE_STRING, &attributes,
- DBUS_TYPE_UINT32, &flags_dbus,
- DBUS_TYPE_STRING, &uri,
- 0);
- g_free (uri);
- g_free (obj_path);
+ create_proxy_for_file_async (file,
+ cancellable,
+ callback, user_data,
+ enumerate_children_async_get_proxy_cb,
+ data, (GDestroyNotify) async_call_enumerate_free);
}
static GFileEnumerator *
@@ -3007,40 +3414,6 @@ g_daemon_file_find_enclosing_mount_finish (GFile *file,
}
static void
-replace_async_cb (DBusMessage *reply,
- DBusConnection *connection,
- GMountInfo *mount_info,
- GSimpleAsyncResult *result,
- GCancellable *cancellable,
- gpointer callback_data)
-{
- guint32 fd_id;
- StreamOpenParams *open_params;
-
- open_params = g_slice_new0 (StreamOpenParams);
-
- if (!dbus_message_get_args (reply, NULL,
- DBUS_TYPE_UINT32, &fd_id,
- DBUS_TYPE_BOOLEAN, &open_params->can_seek,
- DBUS_TYPE_UINT64, &open_params->initial_offset,
- DBUS_TYPE_INVALID))
- {
- g_simple_async_result_set_error (result, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Invalid return value from %s"), "open");
- goto failure;
- }
-
- open_params->result = g_object_ref (result);
- _g_dbus_connection_get_fd_async (connection, fd_id,
- (GetFdAsyncCallback) stream_open_cb, open_params);
- return;
-
-failure:
- g_slice_free (StreamOpenParams, open_params);
- _g_simple_async_result_complete_with_cancellable (result, cancellable);
-}
-
-static void
g_daemon_file_replace_async (GFile *file,
const char *etag,
gboolean make_backup,
@@ -3050,27 +3423,12 @@ g_daemon_file_replace_async (GFile *file,
GAsyncReadyCallback callback,
gpointer user_data)
{
- dbus_bool_t dbus_make_backup = make_backup;
- guint32 dbus_flags = flags;
- guint16 mode = 2;
- guint32 pid;
-
- pid = get_pid_for_file (file);
+ g_print ("g_daemon_file_replace_async\n");
- if (etag == NULL)
- etag = "";
-
- do_async_path_call (file,
- G_VFS_DBUS_MOUNT_OP_OPEN_FOR_WRITE,
- cancellable,
- callback, user_data,
- replace_async_cb, NULL, NULL,
- DBUS_TYPE_UINT16, &mode,
- DBUS_TYPE_STRING, &etag,
- DBUS_TYPE_BOOLEAN, &dbus_make_backup,
- DBUS_TYPE_UINT32, &dbus_flags,
- DBUS_TYPE_UINT32, &pid,
- 0);
+ file_open_write_async (file,
+ 2, etag, make_backup, flags, io_priority,
+ cancellable,
+ callback, user_data);
}
static GFileOutputStream *
@@ -3088,38 +3446,86 @@ g_daemon_file_replace_finish (GFile *file,
return NULL;
}
+typedef struct {
+ GFile *file;
+ char *display_name;
+ int io_priority;
+ GMountInfo *mount_info;
+ GSimpleAsyncResult *result;
+ GCancellable *cancellable;
+} AsyncCallSetDisplayName;
+
+static void
+async_call_set_display_name_free (AsyncCallSetDisplayName *data)
+{
+ if (data->file)
+ g_object_unref (data->file);
+ if (data->result)
+ g_object_unref (data->result);
+ if (data->cancellable)
+ g_object_unref (data->cancellable);
+ if (data->mount_info)
+ g_mount_info_unref (data->mount_info);
+ g_free (data->display_name);
+ g_free (data);
+}
+
static void
-set_display_name_async_cb (DBusMessage *reply,
- DBusConnection *connection,
- GMountInfo *mount_info,
- GSimpleAsyncResult *result,
- GCancellable *cancellable,
- gpointer callback_data)
+set_display_name_async_cb (GVfsDBusMount *proxy,
+ GAsyncResult *res,
+ gpointer user_data)
{
- GDaemonFile *daemon_file = callback_data;
+ AsyncCallSetDisplayName *data = user_data;
GFile *file;
- DBusMessageIter iter;
+ GError *error = NULL;
gchar *new_path;
+ GSimpleAsyncResult *orig_result;
- if (!dbus_message_iter_init (reply, &iter) ||
- !_g_dbus_message_iter_get_args (&iter, NULL,
- G_DBUS_TYPE_CSTRING, &new_path,
- 0))
+ g_print ("set_display_name_async_cb\n");
+ orig_result = data->result;
+
+ if (! gvfs_dbus_mount_call_set_display_name_finish (proxy, &new_path, res, &error))
{
- g_simple_async_result_set_error (result, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Invalid return value from %s"), "set_display_name");
+ g_simple_async_result_take_error (orig_result, error);
goto out;
}
- g_mount_info_apply_prefix (mount_info, &new_path);
- file = new_file_for_new_path (daemon_file, new_path);
+ g_mount_info_apply_prefix (data->mount_info, &new_path);
+ file = new_file_for_new_path (G_DAEMON_FILE (data->file), new_path);
g_free (new_path);
- g_simple_async_result_set_op_res_gpointer (result, file, g_object_unref);
+ g_simple_async_result_set_op_res_gpointer (orig_result, file, g_object_unref);
-out:
- _g_simple_async_result_complete_with_cancellable (result, cancellable);
+ out:
+ _g_simple_async_result_complete_with_cancellable (orig_result, data->cancellable);
+ data->result = NULL;
+ g_object_unref (orig_result); /* trigger async_proxy_create_free() */
+}
+
+static void
+set_display_name_async_get_proxy_cb (GVfsDBusMount *proxy,
+ GDBusConnection *connection,
+ GMountInfo *mount_info,
+ const gchar *path,
+ GSimpleAsyncResult *result,
+ GError *error,
+ GCancellable *cancellable,
+ gpointer callback_data)
+{
+ AsyncCallSetDisplayName *data = callback_data;
+
+ g_print ("set_display_name_async_get_proxy_cb, proxy = %p\n", proxy);
+
+ data->result = g_object_ref (result);
+ data->mount_info = g_mount_info_ref (mount_info);
+
+ gvfs_dbus_mount_call_set_display_name (proxy,
+ path,
+ data->display_name,
+ cancellable,
+ (GAsyncReadyCallback) set_display_name_async_cb,
+ data);
}
static void
@@ -3130,15 +3536,22 @@ g_daemon_file_set_display_name_async (GFile *file,
GAsyncReadyCallback callback,
gpointer user_data)
{
- g_object_ref (file);
+ AsyncCallSetDisplayName *data;
+
+ g_print ("g_daemon_file_set_display_name_async\n");
+
+ data = g_new0 (AsyncCallSetDisplayName, 1);
+ data->file = g_object_ref (file);
+ data->display_name = g_strdup (display_name);
+ data->io_priority = io_priority;
+ if (cancellable)
+ data->cancellable = g_object_ref (cancellable);
- do_async_path_call (file,
- G_VFS_DBUS_MOUNT_OP_SET_DISPLAY_NAME,
- cancellable,
- callback, user_data,
- set_display_name_async_cb, file, g_object_unref,
- DBUS_TYPE_STRING, &display_name,
- 0);
+ create_proxy_for_file_async (file,
+ cancellable,
+ callback, user_data,
+ set_display_name_async_get_proxy_cb,
+ data, (GDestroyNotify) async_call_set_display_name_free);
}
static GFile *
diff --git a/client/gdaemonfileenumerator.c b/client/gdaemonfileenumerator.c
index 9e8722a2..80502f71 100644
--- a/client/gdaemonfileenumerator.c
+++ b/client/gdaemonfileenumerator.c
@@ -32,6 +32,7 @@
#include <gvfsdaemonprotocol.h>
#include "gdaemonfile.h"
#include "metatree.h"
+#include <gvfsdbus.h>
#define OBJ_PATH_PREFIX "/org/gtk/vfs/client/enumerator/"
@@ -45,7 +46,7 @@ struct _GDaemonFileEnumerator
GFileEnumerator parent;
gint id;
- DBusConnection *sync_connection; /* NULL if async, i.e. we're listening on main dbus connection */
+ GDBusConnection *sync_connection; /* NULL if async, i.e. we're listening on main dbus connection */
/* protected by infos lock */
GList *infos;
@@ -56,6 +57,9 @@ struct _GDaemonFileEnumerator
gulong cancelled_tag;
guint timeout_tag;
GSimpleAsyncResult *async_res;
+ GMainLoop *next_files_mainloop;
+ guint next_files_sync_timeout_tag;
+ GMutex next_files_mutex;
GFileAttributeMatcher *matcher;
MetaTree *metadata_tree;
@@ -86,9 +90,8 @@ static void g_daemon_file_enumerator_close_async (GFileEnumerator
static gboolean g_daemon_file_enumerator_close_finish (GFileEnumerator *enumerator,
GAsyncResult *result,
GError **error);
-static DBusHandlerResult g_daemon_file_enumerator_dbus_filter (DBusConnection *connection,
- DBusMessage *message,
- void *user_data);
+static void trigger_async_done (GDaemonFileEnumerator *daemon, gboolean ok);
+
static void
free_info_list (GList *infos)
@@ -105,6 +108,8 @@ g_daemon_file_enumerator_finalize (GObject *object)
daemon = G_DAEMON_FILE_ENUMERATOR (object);
+ g_print ("g_daemon_file_enumerator_finalize: daemon = %p\n", daemon);
+
path = g_daemon_file_enumerator_get_object_path (daemon);
_g_dbus_unregister_vfs_filter (path);
g_free (path);
@@ -116,7 +121,9 @@ g_daemon_file_enumerator_finalize (GObject *object)
meta_tree_unref (daemon->metadata_tree);
if (daemon->sync_connection)
- dbus_connection_unref (daemon->sync_connection);
+ g_object_unref (daemon->sync_connection);
+
+ g_mutex_clear (&daemon->next_files_mutex);
if (G_OBJECT_CLASS (g_daemon_file_enumerator_parent_class)->finalize)
(*G_OBJECT_CLASS (g_daemon_file_enumerator_parent_class)->finalize) (object);
@@ -140,14 +147,127 @@ g_daemon_file_enumerator_class_init (GDaemonFileEnumeratorClass *klass)
}
static void
+next_files_sync_check (GDaemonFileEnumerator *enumerator)
+{
+ g_print ("next_files_sync_check: enumerator->infos = %p, enumerator->done = %d, loop = %p, daemon = %p\n", enumerator->infos, enumerator->done, enumerator->next_files_mainloop, enumerator);
+
+ g_mutex_lock (&enumerator->next_files_mutex);
+ if ((enumerator->infos || enumerator->done) &&
+ enumerator->next_files_mainloop != NULL)
+ {
+ g_print ("next_files_sync_check: calling quit\n");
+ g_main_loop_quit (enumerator->next_files_mainloop);
+ }
+ g_mutex_unlock (&enumerator->next_files_mutex);
+}
+
+static gboolean
+handle_done (GVfsDBusEnumerator *object,
+ GDBusMethodInvocation *invocation,
+ gpointer user_data)
+{
+ GDaemonFileEnumerator *enumerator = user_data;
+
+ g_print ("handle_done: daemon = %p, async_requested_files = %d\n", enumerator, enumerator->async_requested_files);
+
+ G_LOCK (infos);
+ enumerator->done = TRUE;
+ if (enumerator->async_requested_files > 0)
+ trigger_async_done (enumerator, TRUE);
+ next_files_sync_check (enumerator);
+ G_UNLOCK (infos);
+
+ gvfs_dbus_enumerator_complete_done (object, invocation);
+
+ return TRUE;
+}
+
+static gboolean
+handle_got_info (GVfsDBusEnumerator *object,
+ GDBusMethodInvocation *invocation,
+ GVariant *arg_infos,
+ gpointer user_data)
+{
+ GDaemonFileEnumerator *enumerator = user_data;
+ GList *infos;
+ GFileInfo *info;
+ GVariantIter iter;
+ GVariant *child;
+
+ g_print ("handle_got_info: daemon = %p\n", enumerator);
+
+ infos = NULL;
+
+ g_variant_iter_init (&iter, arg_infos);
+ while ((child = g_variant_iter_next_value (&iter)))
+ {
+ info = _g_dbus_get_file_info (child, NULL);
+ if (info)
+ g_assert (G_IS_FILE_INFO (info));
+
+ if (info)
+ infos = g_list_prepend (infos, info);
+
+ g_variant_unref (child);
+ }
+
+ infos = g_list_reverse (infos);
+
+ G_LOCK (infos);
+ enumerator->infos = g_list_concat (enumerator->infos, infos);
+ if (enumerator->async_requested_files > 0 &&
+ g_list_length (enumerator->infos) >= enumerator->async_requested_files)
+ trigger_async_done (enumerator, TRUE);
+ next_files_sync_check (enumerator);
+ G_UNLOCK (infos);
+
+ gvfs_dbus_enumerator_complete_got_info (object, invocation);
+
+ return TRUE;
+}
+
+static GDBusInterfaceSkeleton *
+register_vfs_filter_cb (GDBusConnection *connection,
+ const char *obj_path,
+ gpointer callback_data)
+{
+ GError *error;
+ GVfsDBusEnumerator *skeleton;
+
+ skeleton = gvfs_dbus_enumerator_skeleton_new ();
+ g_signal_connect (skeleton, "handle-done", G_CALLBACK (handle_done), callback_data);
+ g_signal_connect (skeleton, "handle-got-info", G_CALLBACK (handle_got_info), callback_data);
+
+ g_print ("register_vfs_filter_cb: callback_data = %p, skeleton = %p, obj_path = '%s'\n", callback_data, skeleton, obj_path);
+
+ error = NULL;
+ if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (skeleton),
+ connection,
+ obj_path,
+ &error))
+ {
+ g_warning ("Error registering path: %s (%s, %d)\n",
+ error->message, g_quark_to_string (error->domain), error->code);
+ g_error_free (error);
+ }
+
+ return G_DBUS_INTERFACE_SKELETON (skeleton);
+}
+
+static void
g_daemon_file_enumerator_init (GDaemonFileEnumerator *daemon)
{
char *path;
daemon->id = g_atomic_int_add (&path_counter, 1);
+ g_mutex_init (&daemon->next_files_mutex);
+
path = g_daemon_file_enumerator_get_object_path (daemon);
- _g_dbus_register_vfs_filter (path, g_daemon_file_enumerator_dbus_filter,
+ g_print ("g_daemon_file_enumerator_init: daemon = %p, obj_path = '%s'\n", daemon, path);
+
+ _g_dbus_register_vfs_filter (path,
+ register_vfs_filter_cb,
G_OBJECT (daemon));
g_free (path);
}
@@ -243,7 +363,7 @@ static void
trigger_async_done (GDaemonFileEnumerator *daemon, gboolean ok)
{
GList *rest, *l;
-
+
if (daemon->cancelled_tag != 0)
{
GCancellable *cancellable = simple_async_result_get_cancellable (daemon->async_res);
@@ -309,65 +429,6 @@ trigger_async_done (GDaemonFileEnumerator *daemon, gboolean ok)
daemon->async_res = NULL;
}
-static DBusHandlerResult
-g_daemon_file_enumerator_dbus_filter (DBusConnection *connection,
- DBusMessage *message,
- void *user_data)
-{
- GDaemonFileEnumerator *enumerator = user_data;
- const char *member;
- DBusMessageIter iter, array_iter;
- GList *infos;
- GFileInfo *info;
-
- member = dbus_message_get_member (message);
-
- if (strcmp (member, G_VFS_DBUS_ENUMERATOR_OP_DONE) == 0)
- {
- G_LOCK (infos);
- enumerator->done = TRUE;
- if (enumerator->async_requested_files > 0)
- trigger_async_done (enumerator, TRUE);
- G_UNLOCK (infos);
- return DBUS_HANDLER_RESULT_HANDLED;
- }
- else if (strcmp (member, G_VFS_DBUS_ENUMERATOR_OP_GOT_INFO) == 0)
- {
- infos = NULL;
-
- dbus_message_iter_init (message, &iter);
- if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_ARRAY &&
- dbus_message_iter_get_element_type (&iter) == DBUS_TYPE_STRUCT)
- {
- dbus_message_iter_recurse (&iter, &array_iter);
-
- while (dbus_message_iter_get_arg_type (&array_iter) == DBUS_TYPE_STRUCT)
- {
- info = _g_dbus_get_file_info (&array_iter, NULL);
- if (info)
- g_assert (G_IS_FILE_INFO (info));
-
- if (info)
- infos = g_list_prepend (infos, info);
-
- dbus_message_iter_next (&iter);
- }
- }
-
- infos = g_list_reverse (infos);
-
- G_LOCK (infos);
- enumerator->infos = g_list_concat (enumerator->infos, infos);
- if (enumerator->async_requested_files > 0 &&
- g_list_length (enumerator->infos) >= enumerator->async_requested_files)
- trigger_async_done (enumerator, TRUE);
- G_UNLOCK (infos);
- return DBUS_HANDLER_RESULT_HANDLED;
- }
-
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-}
-
char *
g_daemon_file_enumerator_get_object_path (GDaemonFileEnumerator *enumerator)
{
@@ -376,9 +437,23 @@ g_daemon_file_enumerator_get_object_path (GDaemonFileEnumerator *enumerator)
void
g_daemon_file_enumerator_set_sync_connection (GDaemonFileEnumerator *enumerator,
- DBusConnection *connection)
+ GDBusConnection *connection)
{
- enumerator->sync_connection = dbus_connection_ref (connection);
+ enumerator->sync_connection = g_object_ref (connection);
+}
+
+static gboolean
+sync_timeout (gpointer data)
+{
+ GDaemonFileEnumerator *daemon = G_DAEMON_FILE_ENUMERATOR (data);
+
+ g_print ("sync_timeout\n");
+
+ g_mutex_lock (&daemon->next_files_mutex);
+ g_main_loop_quit (daemon->next_files_mainloop);
+ g_mutex_unlock (&daemon->next_files_mutex);
+
+ return FALSE;
}
static GFileInfo *
@@ -388,71 +463,61 @@ g_daemon_file_enumerator_next_file (GFileEnumerator *enumerator,
{
GDaemonFileEnumerator *daemon = G_DAEMON_FILE_ENUMERATOR (enumerator);
GFileInfo *info;
- gboolean done;
- int count;
- info = NULL;
- done = FALSE;
- count = 0;
- while (count++ < G_VFS_DBUS_TIMEOUT_MSECS / 100)
+ if (daemon->sync_connection == NULL)
{
- G_LOCK (infos);
- if (daemon->infos)
- {
- done = TRUE;
- info = daemon->infos->data;
- if (info)
- {
- g_assert (G_IS_FILE_INFO (info));
- add_metadata (G_FILE_INFO (info), daemon);
- }
- daemon->infos = g_list_delete_link (daemon->infos, daemon->infos);
- }
- else if (daemon->done)
- done = TRUE;
- G_UNLOCK (infos);
+ /* The enumerator was initialized by an async call, so responses will
+ come to the async dbus connection. We can't pump that as that would
+ cause all sort of filters and stuff to run, possibly on the wrong
+ thread. If you want to do async next_files you must create the
+ enumerator asynchrounously.
+ */
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Can't do synchronous next_files() on a file enumerator created asynchronously");
+ return NULL;
+ }
- if (info)
- g_assert (G_IS_FILE_INFO (info));
+ g_print ("g_daemon_file_enumerator_next_file: done = %d\n", daemon->done);
+
+ if (! daemon->infos && ! daemon->done)
+ {
+ /* Wait for incoming data */
+ daemon->next_files_sync_timeout_tag = g_timeout_add (G_VFS_DBUS_TIMEOUT_MSECS,
+ sync_timeout, daemon);
+
+ g_mutex_lock (&daemon->next_files_mutex);
+ g_print ("g_daemon_file_enumerator_next_file: starting loop, daemon = %p\n", daemon);
+ daemon->next_files_mainloop = g_main_loop_new (NULL, FALSE);
+ g_mutex_unlock (&daemon->next_files_mutex);
- if (done)
- break;
+ g_main_loop_run (daemon->next_files_mainloop);
+
+ g_mutex_lock (&daemon->next_files_mutex);
+ g_print ("g_daemon_file_enumerator_next_file: loop done.\n");
+ g_source_remove (daemon->next_files_sync_timeout_tag);
+ g_main_loop_unref (daemon->next_files_mainloop);
+ daemon->next_files_mainloop = NULL;
+ g_mutex_unlock (&daemon->next_files_mutex);
+ }
+
+ info = NULL;
- /* We sleep only 100 msecs here, not the full time because we might have
- * raced with the filter func being called after unlocking
- * and setting done or ->infos. So, we want to check it again reasonaby soon.
- */
- if (daemon->sync_connection != NULL)
- {
- /* The initializing call for the enumerator was a sync one, and we
- have a reference to its private connection. In order to ensure we
- get the responses sent to that originating connection we pump it
- here.
- This should be safe as we're either on the thread that did the call
- so its our connection, or its the private connection for another
- thread. If that thread is idle the pumping won't affect anything, and
- if it is doing something thats ok to, because we don't use filters
- on the private sync connections so we won't cause any reentrancy
- (except the file enumerator filter, but that is safe to run in
- some other thread).
- */
- if (!dbus_connection_read_write_dispatch (daemon->sync_connection, 100))
- break;
- }
- else
- {
- /* The enumerator was initialized by an async call, so responses will
- come to the async dbus connection. We can't pump that as that would
- cause all sort of filters and stuff to run, possibly on the wrong
- thread. If you want to do async next_files you must create the
- enumerator asynchrounously.
- */
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Can't do synchronous next_files() on a file enumerator created asynchronously");
- return NULL;
- }
+ G_LOCK (infos);
+ if (daemon->infos)
+ {
+ info = daemon->infos->data;
+ if (info)
+ {
+ g_assert (G_IS_FILE_INFO (info));
+ add_metadata (G_FILE_INFO (info), daemon);
+ }
+ daemon->infos = g_list_delete_link (daemon->infos, daemon->infos);
}
+ G_UNLOCK (infos);
+ if (info)
+ g_assert (G_IS_FILE_INFO (info));
+
return info;
}
diff --git a/client/gdaemonfileenumerator.h b/client/gdaemonfileenumerator.h
index 17e7ddbe..32c61609 100644
--- a/client/gdaemonfileenumerator.h
+++ b/client/gdaemonfileenumerator.h
@@ -24,7 +24,6 @@
#define __G_DAEMON_FILE_ENUMERATOR_H__
#include <gio/gio.h>
-#include <dbus/dbus.h>
G_BEGIN_DECLS
@@ -50,7 +49,7 @@ GDaemonFileEnumerator *g_daemon_file_enumerator_new (GFile *file
const char *attributes);
char * g_daemon_file_enumerator_get_object_path (GDaemonFileEnumerator *enumerator);
void g_daemon_file_enumerator_set_sync_connection (GDaemonFileEnumerator *enumerator,
- DBusConnection *connection);
+ GDBusConnection *connection);
G_END_DECLS
diff --git a/client/gdaemonmount.c b/client/gdaemonmount.c
index f1b82a7d..1104f9b6 100644
--- a/client/gdaemonmount.c
+++ b/client/gdaemonmount.c
@@ -31,10 +31,9 @@
#include "gdaemonmount.h"
#include "gvfsdaemondbus.h"
#include "gdaemonfile.h"
-#include "gvfsdaemonprotocol.h"
-#include "gvfsdbusutils.h"
#include "gmountsource.h"
#include "gmountoperationdbus.h"
+#include <gvfsdbus.h>
/* Protects all fields of GDaemonMount that can change
which at this point is just foreign_volume */
@@ -173,19 +172,148 @@ g_daemon_mount_can_eject (GMount *mount)
return FALSE;
}
+
+typedef struct {
+ GMount *mount;
+ GCancellable *cancellable;
+ GSimpleAsyncResult *result;
+ GMountInfo *mount_info;
+ GMountOperation *mount_operation;
+ GMountUnmountFlags flags;
+ GDBusConnection *connection;
+ GVfsDBusMount *proxy;
+} AsyncProxyCreate;
+
+static void
+async_proxy_create_free (AsyncProxyCreate *data)
+{
+ if (data->mount)
+ g_object_unref (data->mount);
+ if (data->result)
+ g_object_unref (data->result);
+ if (data->cancellable)
+ g_object_unref (data->cancellable);
+ if (data->mount_operation)
+ g_object_unref (data->mount_operation);
+ if (data->connection)
+ g_object_unref (data->connection);
+ if (data->proxy)
+ g_object_unref (data->proxy);
+ g_free (data);
+}
+
+static void
+unmount_reply (GVfsDBusMount *proxy,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ AsyncProxyCreate *data = user_data;
+ GError *error = NULL;
+
+ g_print ("gdaemonmount.c: unmount_reply, proxy = %p\n", proxy);
+
+ if (! gvfs_dbus_mount_call_unmount_finish (proxy, res, &error))
+ {
+ g_simple_async_result_take_error (data->result, error);
+ }
+
+ _g_simple_async_result_complete_with_cancellable (data->result, data->cancellable);
+ async_proxy_create_free (data);
+}
+
+static void
+async_proxy_new_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ AsyncProxyCreate *data = user_data;
+ GVfsDBusMount *proxy;
+ GError *error = NULL;
+ GMountSource *mount_source;
+
+ proxy = gvfs_dbus_mount_proxy_new_finish (res, &error);
+ g_print ("gdaemonmount.c: async_proxy_new_cb, proxy = %p\n", proxy);
+ if (proxy == NULL)
+ {
+ g_simple_async_result_take_error (data->result, error);
+ _g_simple_async_result_complete_with_cancellable (data->result, data->cancellable);
+ async_proxy_create_free (data);
+ return;
+ }
+
+ data->proxy = proxy;
+ _g_dbus_connect_vfs_filters (data->connection);
+
+ mount_source = g_mount_operation_dbus_wrap (data->mount_operation, _g_daemon_vfs_get_async_bus ());
+
+ gvfs_dbus_mount_call_unmount (proxy,
+ g_mount_source_get_dbus_id (mount_source),
+ g_mount_source_get_obj_path (mount_source),
+ data->flags,
+ data->cancellable,
+ (GAsyncReadyCallback) unmount_reply,
+ data);
+
+ g_object_unref (mount_source);
+}
+
+static void
+async_construct_proxy (GDBusConnection *connection,
+ AsyncProxyCreate *data)
+{
+ data->connection = g_object_ref (connection);
+ gvfs_dbus_mount_proxy_new (connection,
+ G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
+ data->mount_info->dbus_id,
+ data->mount_info->object_path,
+ data->cancellable,
+ async_proxy_new_cb,
+ data);
+}
+
static void
-unmount_reply (DBusMessage *reply,
- DBusConnection *connection,
- GError *io_error,
- gpointer _data)
+bus_get_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
{
- GSimpleAsyncResult *result = _data;
+ AsyncProxyCreate *data = user_data;
+ GDBusConnection *connection;
+ GError *error = NULL;
+
+ connection = g_bus_get_finish (res, &error);
+
+ if (connection == NULL)
+ {
+ g_simple_async_result_set_from_error (data->result, error);
+ _g_simple_async_result_complete_with_cancellable (data->result, data->cancellable);
+ async_proxy_create_free (data);
+ return;
+ }
+
+ async_construct_proxy (connection, data);
+}
- if (io_error != NULL)
- g_simple_async_result_set_from_error (result, io_error);
+static void
+async_got_connection_cb (GDBusConnection *connection,
+ GError *io_error,
+ gpointer callback_data)
+{
+ AsyncProxyCreate *data = callback_data;
+
+ g_print ("gdaemonmount.c: async_got_connection_cb, connection = %p\n", connection);
+
+ if (connection == NULL)
+ {
+ /* TODO: we should probably test if we really want a session bus;
+ * for now, this code is on par with the old dbus code */
+ g_bus_get (G_BUS_TYPE_SESSION,
+ data->cancellable,
+ bus_get_cb,
+ data);
+ return;
+ }
- g_simple_async_result_complete (result);
- g_object_unref (result);
+ async_construct_proxy (connection, data);
}
static void
@@ -197,42 +325,26 @@ g_daemon_mount_unmount_with_operation (GMount *mount,
gpointer user_data)
{
GDaemonMount *daemon_mount = G_DAEMON_MOUNT (mount);
- DBusMessage *message;
- GMountInfo *mount_info;
- GSimpleAsyncResult *res;
- guint32 dbus_flags;
- GMountSource *mount_source;
- const char *dbus_id, *obj_path;
+ AsyncProxyCreate *data;
- mount_info = daemon_mount->mount_info;
+ g_print ("g_daemon_mount_unmount_with_operation\n");
- message =
- dbus_message_new_method_call (mount_info->dbus_id,
- mount_info->object_path,
- G_VFS_DBUS_MOUNT_INTERFACE,
- G_VFS_DBUS_MOUNT_OP_UNMOUNT);
+ data = g_new0 (AsyncProxyCreate, 1);
+ data->mount = g_object_ref (mount);
+ data->mount_info = daemon_mount->mount_info;
+ data->mount_operation = g_object_ref (mount_operation);
+ data->flags = flags;
+ if (cancellable)
+ data->cancellable = g_object_ref (cancellable);
- mount_source = g_mount_operation_dbus_wrap (mount_operation, _g_daemon_vfs_get_async_bus ());
- dbus_id = g_mount_source_get_dbus_id (mount_source);
- obj_path = g_mount_source_get_obj_path (mount_source);
-
- dbus_flags = flags;
- _g_dbus_message_append_args (message,
- DBUS_TYPE_STRING, &dbus_id, DBUS_TYPE_OBJECT_PATH, &obj_path,
- DBUS_TYPE_UINT32, &dbus_flags,
- 0);
-
- res = g_simple_async_result_new (G_OBJECT (mount),
- callback, user_data,
- g_daemon_mount_unmount_with_operation);
-
- _g_vfs_daemon_call_async (message,
- unmount_reply, res,
- cancellable);
+ data->result = g_simple_async_result_new (G_OBJECT (mount),
+ callback, user_data,
+ g_daemon_mount_unmount_with_operation);
- dbus_message_unref (message);
-
- g_object_unref (mount_source);
+ _g_dbus_connection_get_for_async (data->mount_info->dbus_id,
+ async_got_connection_cb,
+ data,
+ data->cancellable);
}
static gboolean
diff --git a/client/gdaemonvfs.c b/client/gdaemonvfs.c
index 6930a284..0bdee720 100644
--- a/client/gdaemonvfs.c
+++ b/client/gdaemonvfs.c
@@ -25,15 +25,12 @@
#include <signal.h>
#include <stdlib.h>
#include <errno.h>
-#include <dbus/dbus.h>
#include "gdaemonvfs.h"
#include "gvfsuriutils.h"
#include "gdaemonfile.h"
#include <gio/gio.h>
#include <gvfsdaemonprotocol.h>
#include <gmodule.h>
-#include "gvfsdaemondbus.h"
-#include "gvfsdbusutils.h"
#include "gmountspec.h"
#include "gvfsurimapper.h"
#include "gdaemonvolumemonitor.h"
@@ -41,6 +38,7 @@
#include "gvfsiconloadable.h"
#include <glib/gi18n-lib.h>
#include <glib/gstdio.h>
+#include <gvfsdbus.h>
typedef struct {
char *type;
@@ -54,7 +52,7 @@ struct _GDaemonVfs
{
GVfs parent;
- DBusConnection *async_bus;
+ GDBusConnection *async_bus;
GVfs *wrapped_vfs;
GList *mount_cache;
@@ -101,10 +99,7 @@ g_daemon_vfs_finalize (GObject *object)
g_strfreev (vfs->supported_uri_schemes);
if (vfs->async_bus)
- {
- dbus_connection_close (vfs->async_bus);
- dbus_connection_unref (vfs->async_bus);
- }
+ g_object_unref (vfs->async_bus);
if (vfs->wrapped_vfs)
g_object_unref (vfs->wrapped_vfs);
@@ -302,9 +297,7 @@ g_daemon_vfs_init (GDaemonVfs *vfs)
bindtextdomain (GETTEXT_PACKAGE, GVFS_LOCALEDIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
- dbus_threads_init_default ();
-
- vfs->async_bus = dbus_bus_get_private (DBUS_BUS_SESSION, NULL);
+ vfs->async_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
if (vfs->async_bus == NULL)
return; /* Not supported, return here and return false in vfs_is_active() */
@@ -336,9 +329,7 @@ g_daemon_vfs_init (GDaemonVfs *vfs)
vfs->fuse_root = g_vfs_get_file_for_path (vfs->wrapped_vfs, file);
g_free (file);
- dbus_connection_set_exit_on_disconnect (vfs->async_bus, FALSE);
-
- _g_dbus_connection_integrate_with_main (vfs->async_bus);
+ g_dbus_connection_set_exit_on_close (vfs->async_bus, FALSE);
modules = g_io_modules_load_all_in_directory (GVFS_MODULE_DIR);
@@ -611,107 +602,101 @@ find_string (GPtrArray *array, const char *find_me)
return -1;
}
+static GVfsDBusMountTracker *
+create_mount_tracker_proxy ()
+{
+ GVfsDBusMountTracker *proxy;
+ GError *error;
+
+ error = NULL;
+ proxy = gvfs_dbus_mount_tracker_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
+ G_DBUS_PROXY_FLAGS_NONE,
+ G_VFS_DBUS_DAEMON_NAME,
+ G_VFS_DBUS_MOUNTTRACKER_PATH,
+ NULL,
+ &error);
+ if (proxy == NULL)
+ {
+ g_printerr ("Error creating proxy: %s (%s, %d)\n",
+ error->message, g_quark_to_string (error->domain), error->code);
+ g_error_free (error);
+ }
+
+ return proxy;
+}
static void
fill_mountable_info (GDaemonVfs *vfs)
{
- DBusMessage *message, *reply;
- DBusError error;
- DBusMessageIter iter, array_iter, struct_iter;
MountableInfo *info;
GPtrArray *infos, *uri_schemes;
gint i;
-
- message = dbus_message_new_method_call (G_VFS_DBUS_DAEMON_NAME,
- G_VFS_DBUS_MOUNTTRACKER_PATH,
- G_VFS_DBUS_MOUNTTRACKER_INTERFACE,
- G_VFS_DBUS_MOUNTTRACKER_OP_LIST_MOUNTABLE_INFO);
-
- if (message == NULL)
- _g_dbus_oom ();
-
- dbus_message_set_auto_start (message, TRUE);
-
- dbus_error_init (&error);
- reply = dbus_connection_send_with_reply_and_block (vfs->async_bus,
- message,
- G_VFS_DBUS_TIMEOUT_MSECS,
- &error);
- dbus_message_unref (message);
+ GVfsDBusMountTracker *proxy;
+ GVariant *iter_mountables;
+ GError *error;
+ GVariantIter iter;
+ const gchar *type, *scheme, **scheme_aliases;
+ guint scheme_aliases_len;
+ gint32 default_port;
+ gboolean host_is_inet;
- if (dbus_error_is_set (&error))
+ proxy = create_mount_tracker_proxy ();
+ g_return_if_fail (proxy != NULL);
+
+ error = NULL;
+ if (!gvfs_dbus_mount_tracker_call_list_mountable_info_sync (proxy,
+ &iter_mountables,
+ NULL,
+ &error))
{
- dbus_error_free (&error);
+ g_printerr ("org.gtk.vfs.MountTracker.listMountableInfo call failed: %s (%s, %d)\n",
+ error->message, g_quark_to_string (error->domain), error->code);
+ g_error_free (error);
return;
}
-
- if (reply == NULL)
- _g_dbus_oom ();
-
- dbus_message_iter_init (reply, &iter);
-
- dbus_message_iter_recurse (&iter, &array_iter);
infos = g_ptr_array_new ();
uri_schemes = g_ptr_array_new ();
g_ptr_array_add (uri_schemes, g_strdup ("file"));
- do
- {
- char *type, *scheme, **scheme_aliases;
- int scheme_aliases_len;
- gint32 default_port;
- dbus_bool_t host_is_inet;
-
- if (dbus_message_iter_get_arg_type (&array_iter) != DBUS_TYPE_STRUCT)
- break;
-
- dbus_message_iter_recurse (&array_iter, &struct_iter);
-
- if (!_g_dbus_message_iter_get_args (&struct_iter, NULL,
- DBUS_TYPE_STRING, &type,
- DBUS_TYPE_STRING, &scheme,
- DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &scheme_aliases, &scheme_aliases_len,
- DBUS_TYPE_INT32, &default_port,
- DBUS_TYPE_BOOLEAN, &host_is_inet,
- 0))
- break;
+ g_variant_iter_init (&iter, iter_mountables);
+ while (g_variant_iter_loop (&iter, "(&s&s^a&sib)", &type, &scheme, &scheme_aliases, &default_port, &host_is_inet))
+ {
info = g_new0 (MountableInfo, 1);
info->type = g_strdup (type);
if (*scheme != 0)
- {
- info->scheme = g_strdup (scheme);
- if (find_string (uri_schemes, scheme) == -1)
- g_ptr_array_add (uri_schemes, g_strdup (scheme));
- }
+ {
+ info->scheme = g_strdup (scheme);
+ if (find_string (uri_schemes, scheme) == -1)
+ g_ptr_array_add (uri_schemes, g_strdup (scheme));
+ }
+ scheme_aliases_len = g_strv_length ((gchar **) scheme_aliases);
if (scheme_aliases_len > 0)
- {
- info->scheme_aliases = g_new (char *, scheme_aliases_len + 1);
- for (i = 0; i < scheme_aliases_len; i++)
- {
- info->scheme_aliases[i] = g_strdup (scheme_aliases[i]);
- if (find_string (uri_schemes, scheme_aliases[i]) == -1)
- g_ptr_array_add (uri_schemes, g_strdup (scheme_aliases[i]));
- }
- info->scheme_aliases[scheme_aliases_len] = NULL;
- }
-
+ {
+ info->scheme_aliases = g_new (char *, scheme_aliases_len + 1);
+ for (i = 0; i < scheme_aliases_len; i++)
+ {
+ info->scheme_aliases[i] = g_strdup (scheme_aliases[i]);
+ if (find_string (uri_schemes, scheme_aliases[i]) == -1)
+ g_ptr_array_add (uri_schemes, g_strdup (scheme_aliases[i]));
+ }
+ info->scheme_aliases[scheme_aliases_len] = NULL;
+ }
+
info->default_port = default_port;
info->host_is_inet = host_is_inet;
g_ptr_array_add (infos, info);
-
- g_strfreev (scheme_aliases);
}
- while (dbus_message_iter_next (&array_iter));
-
- dbus_message_unref (reply);
g_ptr_array_add (uri_schemes, NULL);
g_ptr_array_add (infos, NULL);
vfs->mountable_info = (MountableInfo **)g_ptr_array_free (infos, FALSE);
vfs->supported_uri_schemes = (char **)g_ptr_array_free (uri_schemes, FALSE);
+
+ g_variant_unref (iter_mountables);
+ g_object_unref (proxy);
}
@@ -814,23 +799,14 @@ _g_daemon_vfs_invalidate_dbus_id (const char *dbus_id)
static GMountInfo *
-handler_lookup_mount_reply (DBusMessage *reply,
+handler_lookup_mount_reply (GVariant *iter,
GError **error)
{
- DBusError derror;
GMountInfo *info;
- DBusMessageIter iter;
GList *l;
gboolean in_cache;
-
- if (_g_error_from_message (reply, error))
- return NULL;
-
- dbus_error_init (&derror);
- dbus_message_iter_init (reply, &iter);
-
- info = g_mount_info_from_dbus (&iter);
+ info = g_mount_info_from_dbus (iter);
if (info == NULL)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
@@ -869,34 +845,57 @@ typedef struct {
GMountInfoLookupCallback callback;
gpointer user_data;
GMountInfo *info;
+ GMountSpec *spec;
+ char *path;
} GetMountInfoData;
static void
-async_get_mount_info_response (DBusMessage *reply,
- GError *io_error,
- void *_data)
+free_get_mount_info_data (GetMountInfoData *data)
{
- GetMountInfoData *data = _data;
+ if (data->info)
+ g_mount_info_unref (data->info);
+ if (data->spec)
+ g_mount_spec_unref (data->spec);
+ g_free (data->path);
+ g_free (data);
+}
+
+static void
+async_get_mount_info_response (GVfsDBusMountTracker *proxy,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GetMountInfoData *data = user_data;
GMountInfo *info;
GError *error;
-
- if (reply == NULL)
- data->callback (NULL, data->user_data, io_error);
+ GVariant *iter_mount;
+
+ error = NULL;
+ if (! gvfs_dbus_mount_tracker_call_lookup_mount_finish (proxy,
+ &iter_mount,
+ res,
+ &error))
+ {
+ g_warning ("Error from org.gtk.vfs.MountTracker.lookupMount(): %s", error->message);
+ data->callback (NULL, data->user_data, error);
+ g_error_free (error);
+ }
else
{
- error = NULL;
- info = handler_lookup_mount_reply (reply, &error);
+ info = handler_lookup_mount_reply (iter_mount, &error);
data->callback (info, data->user_data, error);
if (info)
- g_mount_info_unref (info);
+ g_mount_info_unref (info);
+ g_variant_unref (iter_mount);
+
if (error)
- g_error_free (error);
+ g_error_free (error);
}
- g_free (data);
+ free_get_mount_info_data (data);
}
static gboolean
@@ -904,11 +903,37 @@ async_get_mount_info_cache_hit (gpointer _data)
{
GetMountInfoData *data = _data;
data->callback (data->info, data->user_data, NULL);
- g_mount_info_unref (data->info);
- g_free (data);
+ free_get_mount_info_data (data);
return FALSE;
}
+static void
+get_mount_info_async_got_proxy_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GetMountInfoData *data = user_data;
+ GVfsDBusMountTracker *proxy;
+ GError *error = NULL;
+
+ proxy = gvfs_dbus_mount_tracker_proxy_new_for_bus_finish (res, &error);
+ if (proxy == NULL)
+ {
+ g_warning ("Error creating MountTracker proxy: %s", error->message);
+ data->callback (NULL, data->user_data, error);
+ free_get_mount_info_data (data);
+ g_error_free (error);
+ return;
+ }
+
+ gvfs_dbus_mount_tracker_call_lookup_mount (proxy,
+ g_mount_spec_to_dbus_with_path (data->spec, data->path),
+ NULL,
+ (GAsyncReadyCallback) async_get_mount_info_response,
+ data);
+ g_object_unref (proxy);
+}
+
void
_g_daemon_vfs_get_mount_info_async (GMountSpec *spec,
const char *path,
@@ -917,12 +942,12 @@ _g_daemon_vfs_get_mount_info_async (GMountSpec *spec,
{
GMountInfo *info;
GetMountInfoData *data;
- DBusMessage *message;
- DBusMessageIter iter;
data = g_new0 (GetMountInfoData, 1);
data->callback = callback;
data->user_data = user_data;
+ data->spec = g_mount_spec_ref (spec);
+ data->path = g_strdup (path);
info = lookup_mount_info_in_cache (spec, path);
@@ -933,70 +958,44 @@ _g_daemon_vfs_get_mount_info_async (GMountSpec *spec,
return;
}
- message =
- dbus_message_new_method_call (G_VFS_DBUS_DAEMON_NAME,
- G_VFS_DBUS_MOUNTTRACKER_PATH,
- G_VFS_DBUS_MOUNTTRACKER_INTERFACE,
- G_VFS_DBUS_MOUNTTRACKER_OP_LOOKUP_MOUNT);
- dbus_message_set_auto_start (message, TRUE);
-
- dbus_message_iter_init_append (message, &iter);
- g_mount_spec_to_dbus_with_path (&iter, spec, path);
-
-
- _g_dbus_connection_call_async (the_vfs->async_bus, message, G_VFS_DBUS_TIMEOUT_MSECS,
- async_get_mount_info_response,
- data);
-
- dbus_message_unref (message);
+ gvfs_dbus_mount_tracker_proxy_new_for_bus (G_BUS_TYPE_SESSION,
+ G_DBUS_PROXY_FLAGS_NONE,
+ G_VFS_DBUS_DAEMON_NAME,
+ G_VFS_DBUS_MOUNTTRACKER_PATH,
+ NULL,
+ get_mount_info_async_got_proxy_cb,
+ data);
}
-
GMountInfo *
_g_daemon_vfs_get_mount_info_sync (GMountSpec *spec,
const char *path,
+ GCancellable *cancellable,
GError **error)
{
GMountInfo *info;
- DBusConnection *conn;
- DBusMessage *message, *reply;
- DBusMessageIter iter;
- DBusError derror;
-
+ GVfsDBusMountTracker *proxy;
+ GVariant *iter_mount;
+
info = lookup_mount_info_in_cache (spec, path);
-
if (info != NULL)
return info;
- conn = _g_dbus_connection_get_sync (NULL, error);
- if (conn == NULL)
- return NULL;
-
- message =
- dbus_message_new_method_call (G_VFS_DBUS_DAEMON_NAME,
- G_VFS_DBUS_MOUNTTRACKER_PATH,
- G_VFS_DBUS_MOUNTTRACKER_INTERFACE,
- G_VFS_DBUS_MOUNTTRACKER_OP_LOOKUP_MOUNT);
- dbus_message_set_auto_start (message, TRUE);
+ proxy = create_mount_tracker_proxy ();
+ g_return_val_if_fail (proxy != NULL, NULL);
- dbus_message_iter_init_append (message, &iter);
- g_mount_spec_to_dbus_with_path (&iter, spec, path);
-
- dbus_error_init (&derror);
- reply = dbus_connection_send_with_reply_and_block (conn, message, -1, &derror);
- dbus_message_unref (message);
-
- if (!reply)
+ if (gvfs_dbus_mount_tracker_call_lookup_mount_sync (proxy,
+ g_mount_spec_to_dbus_with_path (spec, path),
+ &iter_mount,
+ cancellable,
+ error))
{
- _g_error_from_dbus (&derror, error);
- dbus_error_free (&derror);
- return NULL;
+ info = handler_lookup_mount_reply (iter_mount, error);
+ g_variant_unref (iter_mount);
}
-
- info = handler_lookup_mount_reply (reply, error);
-
- dbus_message_unref (reply);
+ g_object_unref (proxy);
+
return info;
}
@@ -1005,43 +1004,28 @@ _g_daemon_vfs_get_mount_info_by_fuse_sync (const char *fuse_path,
char **mount_path)
{
GMountInfo *info;
- DBusConnection *conn;
- DBusMessage *message, *reply;
- DBusMessageIter iter;
- DBusError derror;
int len;
const char *mount_path_end;
-
+ GVfsDBusMountTracker *proxy;
+ GVariant *iter_mount;
+
info = lookup_mount_info_by_fuse_path_in_cache (fuse_path,
mount_path);
if (info != NULL)
return info;
- conn = _g_dbus_connection_get_sync (NULL, NULL);
- if (conn == NULL)
- return NULL;
-
- message =
- dbus_message_new_method_call (G_VFS_DBUS_DAEMON_NAME,
- G_VFS_DBUS_MOUNTTRACKER_PATH,
- G_VFS_DBUS_MOUNTTRACKER_INTERFACE,
- G_VFS_DBUS_MOUNTTRACKER_OP_LOOKUP_MOUNT_BY_FUSE_PATH);
- dbus_message_set_auto_start (message, TRUE);
+ proxy = create_mount_tracker_proxy ();
+ g_return_val_if_fail (proxy != NULL, NULL);
- dbus_message_iter_init_append (message, &iter);
- _g_dbus_message_iter_append_cstring (&iter, fuse_path);
-
- dbus_error_init (&derror);
- reply = dbus_connection_send_with_reply_and_block (conn, message, -1, &derror);
- dbus_message_unref (message);
- if (!reply)
+ if (gvfs_dbus_mount_tracker_call_lookup_mount_by_fuse_path_sync (proxy,
+ fuse_path,
+ &iter_mount,
+ NULL,
+ NULL))
{
- dbus_error_free (&derror);
- return NULL;
+ info = handler_lookup_mount_reply (iter_mount, NULL);
+ g_variant_unref (iter_mount);
}
-
- info = handler_lookup_mount_reply (reply, NULL);
- dbus_message_unref (reply);
if (info)
{
@@ -1065,7 +1049,8 @@ _g_daemon_vfs_get_mount_info_by_fuse_sync (const char *fuse_path,
}
}
-
+ g_object_unref (proxy);
+
return info;
}
@@ -1173,44 +1158,6 @@ g_daemon_vfs_add_writable_namespaces (GVfs *vfs,
G_FILE_ATTRIBUTE_INFO_COPY_WHEN_MOVED);
}
-/* Sends a message on the session bus and blocks for the reply,
- using the thread local connection */
-gboolean
-_g_daemon_vfs_send_message_sync (DBusMessage *message,
- GCancellable *cancellable,
- GError **error)
-{
- DBusConnection *connection;
- DBusError derror;
- DBusMessage *reply;
-
- connection = _g_dbus_connection_get_sync (NULL, NULL);
- if (connection == NULL)
- {
- g_set_error (error, G_IO_ERROR,
- G_IO_ERROR_FAILED,
- _("Error setting file metadata: %s"),
- _("Can't contact session bus"));
- return FALSE;
- }
-
- dbus_error_init (&derror);
- /* TODO: Handle cancellable */
- reply = dbus_connection_send_with_reply_and_block (connection, message,
- G_VFS_DBUS_TIMEOUT_MSECS,
- &derror);
- if (!reply)
- {
- _g_error_from_dbus (&derror, error);
- dbus_error_free (&derror);
- return FALSE;
- }
-
- dbus_message_unref (reply);
-
- return TRUE;
-}
-
static gboolean
strv_equal (char **a, char **b)
{
@@ -1529,7 +1476,7 @@ g_daemon_vfs_local_file_moved (GVfs *vfs,
meta_lookup_cache_free (cache);
}
-DBusConnection *
+GDBusConnection *
_g_daemon_vfs_get_async_bus (void)
{
return the_vfs->async_bus;
diff --git a/client/gdaemonvfs.h b/client/gdaemonvfs.h
index e656a1cf..c5ecefc5 100644
--- a/client/gdaemonvfs.h
+++ b/client/gdaemonvfs.h
@@ -24,7 +24,6 @@
#define __G_DAEMON_VFS_H__
#include <gio/gio.h>
-#include <dbus/dbus.h>
#include "gmountspec.h"
#include "gmounttracker.h"
#include "gvfsuriutils.h"
@@ -61,6 +60,7 @@ void _g_daemon_vfs_get_mount_info_async (GMountSpec
gpointer user_data);
GMountInfo * _g_daemon_vfs_get_mount_info_sync (GMountSpec *spec,
const char *path,
+ GCancellable *cancellable,
GError **error);
GMountInfo * _g_daemon_vfs_get_mount_info_by_fuse_sync (const char *fuse_path,
char **mount_path);
@@ -68,10 +68,7 @@ GMountSpec * _g_daemon_vfs_get_mount_spec_for_path (GMountSpec
const char *path,
const char *new_path);
void _g_daemon_vfs_invalidate_dbus_id (const char *dbus_id);
-DBusConnection *_g_daemon_vfs_get_async_bus (void);
-gboolean _g_daemon_vfs_send_message_sync (DBusMessage *message,
- GCancellable *cancellable,
- GError **error);
+GDBusConnection *_g_daemon_vfs_get_async_bus (void);
int _g_daemon_vfs_append_metadata_for_set (GVariantBuilder *builder,
MetaTree *tree,
const char *path,
diff --git a/client/gvfsdaemondbus.c b/client/gvfsdaemondbus.c
index e8f59e28..670827ad 100644
--- a/client/gvfsdaemondbus.c
+++ b/client/gvfsdaemondbus.c
@@ -38,6 +38,7 @@
#include <gdaemonvfs.h>
#include "gvfsdbusutils.h"
#include "gsysutils.h"
+#include <gvfsdbus.h>
/* Extra vfs-specific data for DBusConnections */
typedef struct {
@@ -50,9 +51,6 @@ typedef struct {
GSource *extra_fd_source;
} VfsConnectionData;
-static gint32 vfs_data_slot = -1;
-static GOnce once_init_dbus = G_ONCE_INIT;
-
typedef struct _ThreadLocalConnections ThreadLocalConnections;
static void free_local_connections (ThreadLocalConnections *local);
@@ -66,10 +64,6 @@ G_LOCK_DEFINE_STATIC(async_map);
static GHashTable *obj_path_map = NULL;
G_LOCK_DEFINE_STATIC(obj_path_map);
-static void setup_async_fd_receive (VfsConnectionData *connection_data);
-static void invalidate_local_connection (const char *dbus_id,
- GError **error);
-
GQuark
_g_vfs_error_quark (void)
@@ -77,42 +71,55 @@ _g_vfs_error_quark (void)
return g_quark_from_static_string ("g-vfs-error-quark");
}
-static gpointer
-vfs_dbus_init (gpointer arg)
-{
- if (!dbus_connection_allocate_data_slot (&vfs_data_slot))
- g_error ("Unable to allocate data slot");
-
- return NULL;
-}
-
/**************************************************************************
* message filters for vfs dbus connections *
*************************************************************************/
typedef struct {
- DBusHandleMessageFunction callback;
+ GVfsRegisterVfsFilterCallback callback;
GObject *data;
+ GHashTable *skeletons;
} PathMapEntry;
+static void
+free_path_map_entry (PathMapEntry *entry)
+{
+ g_hash_table_destroy (entry->skeletons);
+ g_free (entry);
+}
+
+static void
+unref_skeleton (gpointer object)
+{
+ GDBusInterfaceSkeleton *skeleton = object;
+
+ g_print ("unref_skeleton: unreffing skeleton %p\n", skeleton);
+ g_dbus_interface_skeleton_unexport (skeleton);
+ g_object_unref (skeleton);
+}
+
+/* Please note the obj_path has to be unique even for different interfaces */
void
_g_dbus_register_vfs_filter (const char *obj_path,
- DBusHandleMessageFunction callback,
+ GVfsRegisterVfsFilterCallback callback,
GObject *data)
{
- PathMapEntry * entry;
+ PathMapEntry *entry;
+ g_print ("_g_dbus_register_vfs_filter: obj_path = '%s'\n", obj_path);
+
G_LOCK (obj_path_map);
if (obj_path_map == NULL)
obj_path_map = g_hash_table_new_full (g_str_hash, g_str_equal,
- g_free, g_free);
+ g_free, (GDestroyNotify)free_path_map_entry);
- entry = g_new (PathMapEntry,1 );
+ entry = g_new (PathMapEntry, 1);
entry->callback = callback;
entry->data = data;
+ entry->skeletons = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify)unref_skeleton);
- g_hash_table_insert (obj_path_map, g_strdup (obj_path), entry);
+ g_hash_table_insert (obj_path_map, g_strdup (obj_path), entry);
G_UNLOCK (obj_path_map);
}
@@ -121,68 +128,58 @@ void
_g_dbus_unregister_vfs_filter (const char *obj_path)
{
G_LOCK (obj_path_map);
-
+
if (obj_path_map)
g_hash_table_remove (obj_path_map, obj_path);
G_UNLOCK (obj_path_map);
}
-static DBusHandlerResult
-vfs_connection_filter (DBusConnection *connection,
- DBusMessage *message,
- void *user_data)
+static void
+register_skeleton (const char *obj_path,
+ PathMapEntry *entry,
+ GDBusConnection *dbus_conn)
{
- PathMapEntry *entry;
- DBusHandlerResult res;
- DBusHandleMessageFunction callback;
- GObject *data;
- VfsConnectionData *connection_data;
- const char *path;
+ GDBusInterfaceSkeleton *skeleton;
- callback = NULL;
- data = NULL;
-
- if (dbus_message_is_signal (message,
- DBUS_INTERFACE_LOCAL,
- "Disconnected"))
+ if (! g_hash_table_contains (entry->skeletons, dbus_conn))
{
- connection_data = dbus_connection_get_data (connection, vfs_data_slot);
- if (connection_data->async_dbus_id)
- {
- _g_daemon_vfs_invalidate_dbus_id (connection_data->async_dbus_id);
- G_LOCK (async_map);
- g_hash_table_remove (async_map, connection_data->async_dbus_id);
- G_UNLOCK (async_map);
- }
+ /* Note that the newly created GDBusInterfaceSkeleton instance refs the connection so it's not needed to watch for connection being destroyed */
+ skeleton = entry->callback (dbus_conn, obj_path, entry->data);
+ g_print ("registering interface skeleton %p for path '%s' on the %p connection\n", skeleton, obj_path, dbus_conn);
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ g_hash_table_insert (entry->skeletons, dbus_conn, skeleton);
}
-
- path = dbus_message_get_path (message);
- G_LOCK (obj_path_map);
- if (obj_path_map && path)
+ else
{
- entry = g_hash_table_lookup (obj_path_map,
- path);
-
- if (entry)
- {
- callback = entry->callback;
- data = g_object_ref (entry->data);
- }
+ g_print ("interface skeleton '%s' already registered on the %p connection, skipping\n", obj_path, dbus_conn);
}
- G_UNLOCK (obj_path_map);
+}
- res = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+/*
+ * Export registered interface skeletons on this connection. This should ideally
+ * be called only once for every connection, but we often share/reuse existing
+ * connections.
+ *
+ * Already exported interface skeletons should live as long as possible
+ * since there might be ongoing data transfer and re-exporting (unreffing + creation)
+ * breaks running jobs randomly.
+ *
+ */
+void
+_g_dbus_connect_vfs_filters (GDBusConnection *connection)
+{
+ g_print ("_g_dbus_connect_vfs_filters: connection = %p\n", connection);
+
+ G_LOCK (obj_path_map);
- if (callback)
+ if (obj_path_map)
{
- res = callback (connection, message, data);
- g_object_unref (data);
+ /* Export new interface skeletons */
+ g_hash_table_foreach (obj_path_map, (GHFunc) register_skeleton, connection);
}
- return res;
+ G_UNLOCK (obj_path_map);
}
static void
@@ -208,164 +205,43 @@ connection_data_free (gpointer p)
}
static void
-vfs_connection_setup (DBusConnection *connection,
- int extra_fd,
- gboolean async)
+vfs_connection_closed (GDBusConnection *connection,
+ gboolean remote_peer_vanished,
+ GError *error,
+ gpointer user_data)
{
VfsConnectionData *connection_data;
- connection_data = g_new0 (VfsConnectionData, 1);
- connection_data->extra_fd = extra_fd;
- connection_data->extra_fd_count = 0;
-
- if (async)
- setup_async_fd_receive (connection_data);
+ g_print ("gvfsdaemondbus.c: vfs_connection_closed()\n");
- if (!dbus_connection_set_data (connection, vfs_data_slot, connection_data, connection_data_free))
- _g_dbus_oom ();
+ connection_data = g_object_get_data (G_OBJECT (connection), "connection_data");
+ g_assert (connection_data != NULL);
- if (!dbus_connection_add_filter (connection, vfs_connection_filter, NULL, NULL))
- _g_dbus_oom ();
-}
+ g_print (" async_dbus_id = '%s'\n", connection_data->async_dbus_id);
-/**************************************************************************
- * Functions to get fds from vfs dbus connections *
- *************************************************************************/
-
-typedef struct {
- int fd;
- GetFdAsyncCallback callback;
- gpointer callback_data;
-} OutstandingFD;
-
-static void
-outstanding_fd_free (OutstandingFD *outstanding)
-{
- if (outstanding->fd != -1)
- close (outstanding->fd);
-
- g_free (outstanding);
-}
-
-static gboolean
-async_connection_accept_new_fd (VfsConnectionData *data,
- GIOCondition condition,
- int fd)
-{
- int new_fd;
- int fd_id;
- OutstandingFD *outstanding_fd;
-
- if (condition & G_IO_HUP)
+ if (connection_data->async_dbus_id)
{
- close (data->extra_fd);
- data->extra_fd = -1;
- g_source_destroy (data->extra_fd_source);
- g_source_unref (data->extra_fd_source);
- data->extra_fd_source = NULL;
- return FALSE;
- }
-
- fd_id = data->extra_fd_count;
- new_fd = _g_socket_receive_fd (data->extra_fd);
- if (new_fd != -1)
- {
- data->extra_fd_count++;
-
- outstanding_fd = g_hash_table_lookup (data->outstanding_fds, GINT_TO_POINTER (fd_id));
-
- if (outstanding_fd)
- {
- outstanding_fd->callback (new_fd, outstanding_fd->callback_data);
- g_hash_table_remove (data->outstanding_fds, GINT_TO_POINTER (fd_id));
- }
- else
- {
- outstanding_fd = g_new0 (OutstandingFD, 1);
- outstanding_fd->fd = new_fd;
- outstanding_fd->callback = NULL;
- outstanding_fd->callback_data = NULL;
- g_hash_table_insert (data->outstanding_fds,
- GINT_TO_POINTER (fd_id),
- outstanding_fd);
- }
+ _g_daemon_vfs_invalidate_dbus_id (connection_data->async_dbus_id);
+ G_LOCK (async_map);
+ g_hash_table_remove (async_map, connection_data->async_dbus_id);
+ G_UNLOCK (async_map);
}
-
- return TRUE;
}
static void
-setup_async_fd_receive (VfsConnectionData *connection_data)
-{
- connection_data->outstanding_fds =
- g_hash_table_new_full (g_direct_hash,
- g_direct_equal,
- NULL,
- (GDestroyNotify)outstanding_fd_free);
-
-
- connection_data->extra_fd_source =
- __g_fd_source_new (connection_data->extra_fd, G_IO_IN|G_IO_ERR, NULL);
- g_source_set_callback (connection_data->extra_fd_source,
- (GSourceFunc)async_connection_accept_new_fd,
- connection_data, NULL);
- g_source_attach (connection_data->extra_fd_source, NULL);
-}
-
-int
-_g_dbus_connection_get_fd_sync (DBusConnection *connection,
- int fd_id)
+vfs_connection_setup (GDBusConnection *connection,
+ int extra_fd,
+ gboolean async)
{
- VfsConnectionData *data;
- int fd;
-
- data = dbus_connection_get_data (connection, vfs_data_slot);
- g_assert (data != NULL);
-
- /* I don't think we can get reorders here, can we?
- * Its a sync per-thread connection after all
- */
- g_assert (fd_id == data->extra_fd_count);
-
- fd = _g_socket_receive_fd (data->extra_fd);
- if (fd != -1)
- data->extra_fd_count++;
-
- return fd;
-}
+ VfsConnectionData *connection_data;
-void
-_g_dbus_connection_get_fd_async (DBusConnection *connection,
- int fd_id,
- GetFdAsyncCallback callback,
- gpointer callback_data)
-{
- VfsConnectionData *data;
- OutstandingFD *outstanding_fd;
- int fd;
+ connection_data = g_new0 (VfsConnectionData, 1);
+ connection_data->extra_fd = extra_fd;
+ connection_data->extra_fd_count = 0;
- data = dbus_connection_get_data (connection, vfs_data_slot);
- g_assert (data != NULL);
-
- outstanding_fd = g_hash_table_lookup (data->outstanding_fds, GINT_TO_POINTER (fd_id));
+ g_object_set_data_full (G_OBJECT (connection), "connection_data", connection_data, connection_data_free);
- if (outstanding_fd)
- {
- fd = outstanding_fd->fd;
- outstanding_fd->fd = -1;
- g_hash_table_remove (data->outstanding_fds, GINT_TO_POINTER (fd_id));
- callback (fd, callback_data);
- }
- else
- {
- outstanding_fd = g_new0 (OutstandingFD, 1);
- outstanding_fd->fd = -1;
- outstanding_fd->callback = callback;
- outstanding_fd->callback_data = callback_data;
- g_hash_table_insert (data->outstanding_fds,
- GINT_TO_POINTER (fd_id),
- outstanding_fd);
- }
+ g_signal_connect (connection, "closed", G_CALLBACK (vfs_connection_closed), NULL);
}
/*******************************************************************
@@ -373,17 +249,17 @@ _g_dbus_connection_get_fd_async (DBusConnection *connection,
*******************************************************************/
-static DBusConnection *
+static GDBusConnection *
get_connection_for_async (const char *dbus_id)
{
- DBusConnection *connection;
+ GDBusConnection *connection;
connection = NULL;
G_LOCK (async_map);
if (async_map != NULL)
connection = g_hash_table_lookup (async_map, dbus_id);
if (connection)
- dbus_connection_ref (connection);
+ g_object_ref (connection);
G_UNLOCK (async_map);
return connection;
@@ -392,26 +268,31 @@ get_connection_for_async (const char *dbus_id)
static void
close_and_unref_connection (void *data)
{
- DBusConnection *connection = data;
+ GDBusConnection *connection = data;
+
+ g_print ("close_and_unref_connection: closing connection\n");
- dbus_connection_close (connection);
- dbus_connection_unref (connection);
+ /* TODO: watch for the need to manually call g_dbus_connection_close_sync () */
+ g_object_unref (connection);
}
static void
-set_connection_for_async (DBusConnection *connection, const char *dbus_id)
+set_connection_for_async (GDBusConnection *connection, const char *dbus_id)
{
VfsConnectionData *data;
+ g_print ("set_connection_for_async: connection = %p, dbus_id = '%s'\n", connection, dbus_id);
+
G_LOCK (async_map);
- data = dbus_connection_get_data (connection, vfs_data_slot);
+ data = g_object_get_data (G_OBJECT (connection), "connection_data");
+ g_assert (data != NULL);
data->async_dbus_id = g_strdup (dbus_id);
if (async_map == NULL)
async_map = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, close_and_unref_connection);
g_hash_table_insert (async_map, g_strdup (dbus_id), connection);
- dbus_connection_ref (connection);
+ g_object_ref (connection);
G_UNLOCK (async_map);
}
@@ -422,8 +303,8 @@ set_connection_for_async (DBusConnection *connection, const char *dbus_id)
typedef struct {
const char *dbus_id;
- DBusMessage *message;
- DBusConnection *connection;
+ GDBusConnection *connection;
+ int extra_fd;
GCancellable *cancellable;
GVfsAsyncDBusCallback callback;
@@ -434,17 +315,15 @@ typedef struct {
} AsyncDBusCall;
static void
-async_call_finish (AsyncDBusCall *async_call,
- DBusMessage *reply)
+async_call_finish (AsyncDBusCall *async_call)
{
if (async_call->callback)
- async_call->callback (reply, async_call->connection,
+ async_call->callback (async_call->io_error ? NULL : async_call->connection,
async_call->io_error,
async_call->callback_data);
if (async_call->connection)
- dbus_connection_unref (async_call->connection);
- dbus_message_unref (async_call->message);
+ g_object_unref (async_call->connection);
if (async_call->cancellable)
g_object_unref (async_call->cancellable);
if (async_call->io_error)
@@ -453,148 +332,26 @@ async_call_finish (AsyncDBusCall *async_call,
}
static void
-async_dbus_response (DBusMessage *reply,
- GError *error,
- gpointer data)
+async_got_private_connection_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
{
- AsyncDBusCall *async_call = data;
-
- if (async_call->cancelled_tag)
- g_signal_handler_disconnect (async_call->cancellable,
- async_call->cancelled_tag);
-
- if (reply == NULL)
- async_call->io_error = g_error_copy (error);
+ AsyncDBusCall *async_call = user_data;
+ GDBusConnection *connection, *existing_connection;
+ GError *error = NULL;
- async_call_finish (async_call, reply);
-}
-
-typedef struct {
- DBusConnection *connection;
- dbus_uint32_t serial;
-} AsyncCallCancelData;
-
-static void
-async_call_cancel_data_free (gpointer _data)
-{
- AsyncCallCancelData *data = _data;
-
- dbus_connection_unref (data->connection);
- g_free (data);
-}
-
-/* Might be called on another thread */
-static void
-async_call_cancelled_cb (GCancellable *cancellable,
- gpointer _data)
-{
- AsyncCallCancelData *data = _data;
- DBusMessage *cancel_message;
-
- /* Send cancellation message, this just queues it, sending
- * will happen in mainloop */
- cancel_message = dbus_message_new_method_call (NULL,
- G_VFS_DBUS_DAEMON_PATH,
- G_VFS_DBUS_DAEMON_INTERFACE,
- G_VFS_DBUS_OP_CANCEL);
- if (cancel_message != NULL)
- {
- if (dbus_message_append_args (cancel_message,
- DBUS_TYPE_UINT32, &data->serial,
- DBUS_TYPE_INVALID))
- dbus_connection_send (data->connection,
- cancel_message, NULL);
- dbus_message_unref (cancel_message);
- }
-}
-
-static void
-async_call_send (AsyncDBusCall *async_call)
-{
- AsyncCallCancelData *cancel_data;
-
- _g_dbus_connection_call_async (async_call->connection,
- async_call->message,
- G_VFS_DBUS_TIMEOUT_MSECS,
- async_dbus_response,
- async_call);
-
- if (async_call->cancellable)
- {
- cancel_data = g_new0 (AsyncCallCancelData, 1);
- cancel_data->connection = dbus_connection_ref (async_call->connection);
- /* make sure we get the serial *after* the message has been sent, otherwise
- * it will be 0
- */
- cancel_data->serial = dbus_message_get_serial (async_call->message);
- async_call->cancelled_tag =
- g_signal_connect_data (async_call->cancellable, "cancelled",
- (GCallback)async_call_cancelled_cb,
- cancel_data,
- (GClosureNotify)async_call_cancel_data_free,
- 0);
- }
-}
-
-static void
-async_get_connection_response (DBusMessage *reply,
- GError *error,
- void *data)
-{
- AsyncDBusCall *async_call = data;
- DBusError derror;
- char *address1, *address2;
- int extra_fd;
- DBusConnection *connection, *existing_connection;
-
- if (reply == NULL)
+ connection = g_dbus_connection_new_for_address_finish (res, &error);
+ g_print ("async_got_private_connection_cb, connection = %p\n", connection);
+ if (!connection)
{
+ close (async_call->extra_fd);
async_call->io_error = g_error_copy (error);
- async_call_finish (async_call, NULL);
- return;
- }
-
- dbus_error_init (&derror);
- if (!dbus_message_get_args (reply, &derror,
- DBUS_TYPE_STRING, &address1,
- DBUS_TYPE_STRING, &address2,
- DBUS_TYPE_INVALID))
- {
- _g_error_from_dbus (&derror, &async_call->io_error);
- dbus_error_free (&derror);
- async_call_finish (async_call, NULL);
- return;
- }
-
- /* I don't know of any way to do an async connect */
- error = NULL;
- extra_fd = _g_socket_connect (address2, &error);
- if (extra_fd == -1)
- {
- g_set_error (&async_call->io_error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Error connecting to daemon: %s"), error->message);
g_error_free (error);
- async_call_finish (async_call, NULL);
+ async_call_finish (async_call);
return;
}
- /* Unfortunately dbus doesn't have an async open */
- dbus_error_init (&derror);
- connection = dbus_connection_open_private (address1, &derror);
- if (!connection)
- {
- close (extra_fd);
- dbus_message_unref (reply);
-
- g_set_error (&async_call->io_error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Error while getting peer-to-peer dbus connection: %s",
- derror.message);
- dbus_error_free (&derror);
- async_call_finish (async_call, NULL);
- return;
- }
-
- vfs_connection_setup (connection, extra_fd, TRUE);
+ vfs_connection_setup (connection, async_call->extra_fd, TRUE);
/* Maybe we already had a connection? This happens if we requested
* the same owner several times in parallel.
@@ -605,12 +362,11 @@ async_get_connection_response (DBusMessage *reply,
if (existing_connection != NULL)
{
async_call->connection = existing_connection;
- dbus_connection_close (connection);
- dbus_connection_unref (connection);
+ /* TODO: watch for the need to manually call g_dbus_connection_close_sync () */
+ g_object_unref (connection);
}
else
{
- _g_dbus_connection_integrate_with_main (connection);
set_connection_for_async (connection, async_call->dbus_id);
async_call->connection = connection;
}
@@ -619,49 +375,109 @@ async_get_connection_response (DBusMessage *reply,
* avoid doing the operation */
if (g_cancellable_set_error_if_cancelled (async_call->cancellable, &async_call->io_error))
{
- async_call_finish (async_call, NULL);
+ async_call_finish (async_call);
return;
}
- async_call_send (async_call);
+ async_call_finish (async_call);
}
static void
-open_connection_async (AsyncDBusCall *async_call)
+async_get_connection_response (GVfsDBusDaemon *proxy,
+ GAsyncResult *res,
+ gpointer user_data)
{
- DBusMessage *get_connection_message;
+ AsyncDBusCall *async_call = user_data;
+ GError *error = NULL;
+ gchar *address1, *address2;
- get_connection_message = dbus_message_new_method_call (async_call->dbus_id,
- G_VFS_DBUS_DAEMON_PATH,
- G_VFS_DBUS_DAEMON_INTERFACE,
- G_VFS_DBUS_OP_GET_CONNECTION);
-
- if (get_connection_message == NULL)
- _g_dbus_oom ();
+ g_print ("async_get_connection_response\n");
+ if (! gvfs_dbus_daemon_call_get_connection_finish (proxy,
+ &address1, &address2,
+ res,
+ &error))
+ {
+ async_call->io_error = g_error_copy (error);
+ g_error_free (error);
+ async_call_finish (async_call);
+ return;
+ }
+
+ /* I don't know of any way to do an async connect */
+ error = NULL;
+ async_call->extra_fd = _g_socket_connect (address2, &error);
+ if (async_call->extra_fd == -1)
+ {
+ g_set_error (&async_call->io_error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ _("Error connecting to daemon: %s"), error->message);
+ g_error_free (error);
+ async_call_finish (async_call);
+ return;
+ }
+
+ g_dbus_connection_new_for_address (address1,
+ G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
+ NULL, /* GDBusAuthObserver */
+ async_call->cancellable,
+ async_got_private_connection_cb,
+ async_call);
+}
- _g_dbus_connection_call_async (_g_daemon_vfs_get_async_bus (),
- get_connection_message,
- G_VFS_DBUS_TIMEOUT_MSECS,
- async_get_connection_response,
- async_call);
+static void
+open_connection_async_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GVfsDBusDaemon *proxy;
+ AsyncDBusCall *async_call = user_data;
+ GError *error = NULL;
+
+ proxy = gvfs_dbus_daemon_proxy_new_finish (res, &error);
+ g_print ("open_connection_async_cb, proxy = %p\n", proxy);
+
+ if (proxy == NULL)
+ {
+ async_call->io_error = g_error_copy (error);
+ g_error_free (error);
+ async_call_finish (async_call);
+ return;
+ }
+
+ g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (proxy), G_VFS_DBUS_TIMEOUT_MSECS);
- dbus_message_unref (get_connection_message);
+ gvfs_dbus_daemon_call_get_connection (proxy,
+ async_call->cancellable,
+ (GAsyncReadyCallback) async_get_connection_response,
+ async_call);
+
+ g_object_unref (proxy);
+}
+
+static void
+open_connection_async (AsyncDBusCall *async_call)
+{
+ gvfs_dbus_daemon_proxy_new (_g_daemon_vfs_get_async_bus (),
+ G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
+ async_call->dbus_id,
+ G_VFS_DBUS_DAEMON_PATH,
+ async_call->cancellable,
+ open_connection_async_cb,
+ async_call);
}
void
-_g_vfs_daemon_call_async (DBusMessage *message,
- GVfsAsyncDBusCallback callback,
- gpointer callback_data,
- GCancellable *cancellable)
+_g_dbus_connection_get_for_async (const char *dbus_id,
+ GVfsAsyncDBusCallback callback,
+ gpointer callback_data,
+ GCancellable *cancellable)
{
AsyncDBusCall *async_call;
- g_once (&once_init_dbus, vfs_dbus_init, NULL);
-
+ g_print ("_g_dbus_connection_get_for_async\n");
+
async_call = g_new0 (AsyncDBusCall, 1);
- async_call->dbus_id = dbus_message_get_destination (message);
- async_call->message = dbus_message_ref (message);
+ async_call->dbus_id = g_strdup (dbus_id);
if (cancellable)
async_call->cancellable = g_object_ref (cancellable);
async_call->callback = callback;
@@ -671,194 +487,10 @@ _g_vfs_daemon_call_async (DBusMessage *message,
if (async_call->connection == NULL)
open_connection_async (async_call);
else
- async_call_send (async_call);
-}
-
-/**************************************************************************
- * Synchronous daemon calls *
- *************************************************************************/
-
-DBusMessage *
-_g_vfs_daemon_call_sync (DBusMessage *message,
- DBusConnection **connection_out,
- const char *callback_obj_path,
- DBusObjectPathMessageFunction callback,
- gpointer callback_user_data,
- GCancellable *cancellable,
- GError **error)
-{
- DBusConnection *connection;
- DBusError derror;
- DBusMessage *reply;
- DBusPendingCall *pending;
- int dbus_fd;
- int cancel_fd;
- gboolean sent_cancel;
- DBusMessage *cancel_message;
- dbus_uint32_t serial;
- gboolean handle_callbacks;
- const char *dbus_id = dbus_message_get_destination (message);
-
- if (g_cancellable_set_error_if_cancelled (cancellable, error))
- return NULL;
-
- connection = _g_dbus_connection_get_sync (dbus_id, error);
- if (connection == NULL)
- return NULL;
-
- if (g_cancellable_set_error_if_cancelled (cancellable, error))
- return NULL;
-
- handle_callbacks = FALSE;
- if (callback_obj_path != NULL && callback != NULL)
- {
- struct DBusObjectPathVTable vtable = { NULL, callback };
- handle_callbacks = dbus_connection_register_object_path (connection,
- callback_obj_path,
- &vtable,
- callback_user_data);
- }
-
- reply = NULL;
- cancel_fd = g_cancellable_get_fd (cancellable);
- if (cancel_fd != -1 || handle_callbacks)
- {
- if (!dbus_connection_send_with_reply (connection, message,
- &pending,
- G_VFS_DBUS_TIMEOUT_MSECS))
- _g_dbus_oom ();
-
- if (pending == NULL ||
- !dbus_connection_get_is_connected (connection))
- {
- if (pending)
- dbus_pending_call_unref (pending);
- invalidate_local_connection (dbus_id, error);
- goto out;
- }
-
- /* Make sure the message is sent */
- dbus_connection_flush (connection);
-
- if (!dbus_connection_get_unix_fd (connection, &dbus_fd))
- {
- dbus_pending_call_unref (pending);
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Error while getting peer-to-peer dbus connection: %s",
- "No fd");
- goto out;
- }
-
- sent_cancel = (cancel_fd == -1);
- while (!dbus_pending_call_get_completed (pending))
- {
- GPollFD poll_fds[2];
- int poll_ret;
-
- do
- {
- poll_fds[0].events = G_IO_IN;
- poll_fds[0].fd = dbus_fd;
- poll_fds[1].events = G_IO_IN;
- poll_fds[1].fd = cancel_fd;
- poll_ret = g_poll (poll_fds, sent_cancel?1:2, -1);
- }
- while (poll_ret == -1 && errno == EINTR);
-
- if (poll_ret == -1)
- {
- dbus_pending_call_unref (pending);
- g_cancellable_release_fd (cancellable);
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Error while getting peer-to-peer dbus connection: %s",
- "poll error");
- goto out;
- }
-
- if (poll_fds[0].revents & (G_IO_NVAL | G_IO_ERR | G_IO_HUP))
- {
- dbus_pending_call_unref (pending);
- g_cancellable_release_fd (cancellable);
- invalidate_local_connection (dbus_id, error);
- goto out;
- }
-
- if (!sent_cancel && g_cancellable_is_cancelled (cancellable))
- {
- sent_cancel = TRUE;
- serial = dbus_message_get_serial (message);
- cancel_message =
- dbus_message_new_method_call (NULL,
- G_VFS_DBUS_DAEMON_PATH,
- G_VFS_DBUS_DAEMON_INTERFACE,
- G_VFS_DBUS_OP_CANCEL);
- if (cancel_message != NULL)
- {
- if (dbus_message_append_args (cancel_message,
- DBUS_TYPE_UINT32, &serial,
- DBUS_TYPE_INVALID))
- {
- dbus_connection_send (connection, cancel_message, NULL);
- dbus_connection_flush (connection);
- }
-
- dbus_message_unref (cancel_message);
- }
- }
-
- if (poll_fds[0].revents != 0)
- {
- dbus_connection_read_write (connection,
- G_VFS_DBUS_TIMEOUT_MSECS);
-
- while (dbus_connection_dispatch (connection) == DBUS_DISPATCH_DATA_REMAINS)
- ;
- }
- }
-
- reply = dbus_pending_call_steal_reply (pending);
- dbus_pending_call_unref (pending);
- g_cancellable_release_fd (cancellable);
- }
- else
- {
- dbus_error_init (&derror);
- reply = dbus_connection_send_with_reply_and_block (connection, message,
- G_VFS_DBUS_TIMEOUT_MSECS,
- &derror);
- if (!reply)
- {
- if (dbus_error_has_name (&derror, DBUS_ERROR_NO_REPLY) &&
- !dbus_connection_get_is_connected (connection))
- {
- /* The mount for this connection died, we invalidate
- * the caches, and then caller needs to retry.
- */
-
- invalidate_local_connection (dbus_id, error);
- }
- else
- _g_error_from_dbus (&derror, error);
- dbus_error_free (&derror);
- goto out;
- }
- }
-
- if (connection_out)
- *connection_out = connection;
-
- out:
-
- if (handle_callbacks)
- dbus_connection_unregister_object_path (connection, callback_obj_path);
-
- if (reply != NULL && _g_error_from_message (reply, error))
{
- dbus_message_unref (reply);
- return NULL;
+ g_print ("got connection from cache\n");
+ async_call_finish (async_call);
}
-
- return reply;
}
/*************************************************************************
@@ -867,22 +499,16 @@ _g_vfs_daemon_call_sync (DBusMessage *message,
struct _ThreadLocalConnections {
GHashTable *connections;
- DBusConnection *session_bus;
+ GDBusConnection *session_bus;
};
static void
-free_mount_connection (DBusConnection *conn)
-{
- dbus_connection_close (conn);
- dbus_connection_unref (conn);
-}
-
-static void
free_local_connections (ThreadLocalConnections *local)
{
+ g_print ("free_local_connections()\n");
g_hash_table_destroy (local->connections);
if (local->session_bus)
- free_mount_connection (local->session_bus);
+ g_object_unref (local->session_bus);
g_free (local);
}
@@ -904,27 +530,29 @@ invalidate_local_connection (const char *dbus_id,
"Cache invalid, retry (internally handled)");
}
-DBusConnection *
+GDBusConnection *
_g_dbus_connection_get_sync (const char *dbus_id,
+ GCancellable *cancellable,
GError **error)
{
- DBusConnection *bus;
+ GDBusConnection *bus;
ThreadLocalConnections *local;
GError *local_error;
- DBusConnection *connection;
- DBusMessage *message, *reply;
- DBusError derror;
- char *address1, *address2;
+ GDBusConnection *connection;
+ gchar *address1, *address2;
int extra_fd;
+ GVfsDBusDaemon *daemon_proxy;
+ gboolean res;
- g_once (&once_init_dbus, vfs_dbus_init, NULL);
+ if (g_cancellable_set_error_if_cancelled (cancellable, error))
+ return NULL;
local = g_private_get (&local_connections);
if (local == NULL)
{
local = g_new0 (ThreadLocalConnections, 1);
local->connections = g_hash_table_new_full (g_str_hash, g_str_equal,
- g_free, (GDestroyNotify)free_mount_connection);
+ g_free, (GDestroyNotify)g_object_unref);
g_private_set (&local_connections, local);
}
@@ -934,11 +562,11 @@ _g_dbus_connection_get_sync (const char *dbus_id,
if (local->session_bus)
{
- if (dbus_connection_get_is_connected (local->session_bus))
+ if (! g_dbus_connection_is_closed (local->session_bus))
return local->session_bus;
/* Session bus was disconnected, re-connect */
- dbus_connection_unref (local->session_bus);
+ g_object_unref (local->session_bus);
local->session_bus = NULL;
}
}
@@ -949,7 +577,7 @@ _g_dbus_connection_get_sync (const char *dbus_id,
connection = g_hash_table_lookup (local->connections, dbus_id);
if (connection != NULL)
{
- if (!dbus_connection_get_is_connected (connection))
+ if (g_dbus_connection_is_closed (connection))
{
/* The mount for this connection died, we invalidate
* the caches, and then caller needs to retry.
@@ -963,50 +591,37 @@ _g_dbus_connection_get_sync (const char *dbus_id,
}
}
- dbus_error_init (&derror);
-
if (local->session_bus == NULL)
{
- bus = dbus_bus_get_private (DBUS_BUS_SESSION, &derror);
+ bus = g_bus_get_sync (G_BUS_TYPE_SESSION, cancellable, error);
if (bus == NULL)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Couldn't get main dbus connection: %s",
- derror.message);
- dbus_error_free (&derror);
- return NULL;
- }
+ return NULL;
local->session_bus = bus;
if (dbus_id == NULL)
return bus; /* We actually wanted the session bus, so done */
}
-
- message = dbus_message_new_method_call (dbus_id,
- G_VFS_DBUS_DAEMON_PATH,
- G_VFS_DBUS_DAEMON_INTERFACE,
- G_VFS_DBUS_OP_GET_CONNECTION);
- reply = dbus_connection_send_with_reply_and_block (local->session_bus, message, -1,
- &derror);
- dbus_message_unref (message);
-
- if (!reply)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Error while getting peer-to-peer dbus connection: %s",
- derror.message);
- dbus_error_free (&derror);
- return NULL;
- }
- if (_g_error_from_message (reply, error))
+ address1 = address2 = NULL;
+ daemon_proxy = gvfs_dbus_daemon_proxy_new_sync (local->session_bus,
+ G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
+ dbus_id,
+ G_VFS_DBUS_DAEMON_PATH,
+ cancellable,
+ error);
+ if (daemon_proxy == NULL)
+ return NULL;
+
+ res = gvfs_dbus_daemon_call_get_connection_sync (daemon_proxy,
+ &address1,
+ &address2,
+ cancellable,
+ error);
+ g_object_unref (daemon_proxy);
+
+ if (!res)
return NULL;
-
- dbus_message_get_args (reply, NULL,
- DBUS_TYPE_STRING, &address1,
- DBUS_TYPE_STRING, &address2,
- DBUS_TYPE_INVALID);
local_error = NULL;
extra_fd = _g_socket_connect (address2, &local_error);
@@ -1015,23 +630,27 @@ _g_dbus_connection_get_sync (const char *dbus_id,
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
_("Error connecting to daemon: %s"), local_error->message);
g_error_free (local_error);
- dbus_message_unref (reply);
+ g_free (address1);
+ g_free (address2);
return NULL;
}
- dbus_error_init (&derror);
- connection = dbus_connection_open_private (address1, &derror);
+ connection = g_dbus_connection_new_for_address_sync (address1,
+ G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
+ NULL, /* GDBusAuthObserver */
+ cancellable,
+ &local_error);
if (!connection)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Error while getting peer-to-peer dbus connection: %s",
- derror.message);
+ local_error->message);
close (extra_fd);
- dbus_message_unref (reply);
- dbus_error_free (&derror);
+ g_error_free (local_error);
+ g_free (address1);
+ g_free (address2);
return NULL;
}
- dbus_message_unref (reply);
vfs_connection_setup (connection, extra_fd, FALSE);
diff --git a/client/gvfsdaemondbus.h b/client/gvfsdaemondbus.h
index 3683eaf9..d1cd6660 100644
--- a/client/gvfsdaemondbus.h
+++ b/client/gvfsdaemondbus.h
@@ -24,7 +24,6 @@
#define __G_VFS_DAEMON_DBUS_H__
#include <glib.h>
-#include <dbus/dbus.h>
#include <gio/gio.h>
G_BEGIN_DECLS
@@ -39,42 +38,28 @@ typedef enum
} GVfsError;
-typedef void (*GVfsAsyncDBusCallback) (DBusMessage *reply,
- DBusConnection *connection,
+typedef void (*GVfsAsyncDBusCallback) (GDBusConnection *connection,
GError *io_error,
gpointer callback_data);
typedef void (*GetFdAsyncCallback) (int fd,
gpointer callback_data);
+typedef GDBusInterfaceSkeleton * (*GVfsRegisterVfsFilterCallback) (GDBusConnection *connection,
+ const char *obj_path,
+ gpointer callback_data);
+
void _g_dbus_register_vfs_filter (const char *obj_path,
- DBusHandleMessageFunction callback,
+ GVfsRegisterVfsFilterCallback callback,
GObject *data);
void _g_dbus_unregister_vfs_filter (const char *obj_path);
-GList * _g_dbus_bus_list_names_with_prefix_sync (DBusConnection *connection,
- const char *prefix,
- DBusError *error);
-DBusConnection *_g_dbus_connection_get_sync (const char *dbus_id,
- GError **error);
-int _g_dbus_connection_get_fd_sync (DBusConnection *conn,
- int fd_id);
-void _g_dbus_connection_get_fd_async (DBusConnection *connection,
- int fd_id,
- GetFdAsyncCallback callback,
- gpointer callback_data);
-void _g_vfs_daemon_call_async (DBusMessage *message,
- GVfsAsyncDBusCallback callback,
- gpointer callback_data,
- GCancellable *cancellable);
-DBusMessage * _g_vfs_daemon_call_sync (DBusMessage *message,
- DBusConnection **connection_out,
- const char *callback_obj_path,
- DBusObjectPathMessageFunction callback,
- gpointer callback_user_data,
- GCancellable *cancellable,
- GError **error);
-GFileInfo * _g_dbus_get_file_info (DBusMessageIter *iter,
+void _g_dbus_connect_vfs_filters (GDBusConnection *connection);
+GDBusConnection *_g_dbus_connection_get_sync (const char *dbus_id,
+ GCancellable *cancellable,
GError **error);
-
+void _g_dbus_connection_get_for_async (const char *dbus_id,
+ GVfsAsyncDBusCallback callback,
+ gpointer callback_data,
+ GCancellable *cancellable);
void _g_simple_async_result_complete_with_cancellable
(GSimpleAsyncResult *result,
GCancellable *cancellable);