Hi, So this weekend I hacked a bit on allowing synchronous operations on handles that were opened asynchronously. It's kind of a hack. The general approach right now is instead of returning an integer as a GnomeVFSAsyncHandle, we simply make GnomeVFSAsyncHandle be a #define to GnomeVFSHandle. Then we add a boolean to GnomeVFSHandle saying whether it's async. The various synchronous operations dispatch off this to their asynchronous counterparts, followed by a synchronous wait. It sort-of passes 'make check', but I think there's a major bug with cancellation, if the user tries to cancel an operation that's already completed, the async GnomeVFSHandle will have been destroyed and things go badly from there. I think what I'm going to have to do to fix that is flip things around, and make both GnomeVFSHandle and GnomeVFSAsyncHandle an integer ID that maps to a GnomeVFSRealHandle or something. Anyways so this patch isn't applyable, I'm mostly posting it now to claim this task and get feedback on it...
Index: libgnomevfs/gnome-vfs-ops.c
===================================================================
RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-ops.c,v
retrieving revision 1.37
diff -u -d -r1.37 gnome-vfs-ops.c
--- libgnomevfs/gnome-vfs-ops.c 12 Feb 2003 12:40:02 -0000 1.37
+++ libgnomevfs/gnome-vfs-ops.c 17 May 2004 00:22:39 -0000
@@ -246,7 +246,9 @@
{
g_return_val_if_fail (handle != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS);
- return _gnome_vfs_handle_do_tell (handle, offset_return);
+ if (!_gnome_vfs_handle_get_asynchronous (handle))
+ return _gnome_vfs_handle_do_tell (handle, offset_return);
+ return GNOME_VFS_ERROR_NOT_SUPPORTED; /* FIXME: need to map to async operation */
}
/**
Index: libgnomevfs/gnome-vfs-job.h
===================================================================
RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-job.h,v
retrieving revision 1.52
diff -u -d -r1.52 gnome-vfs-job.h
--- libgnomevfs/gnome-vfs-job.h 20 Oct 2003 11:55:54 -0000 1.52
+++ libgnomevfs/gnome-vfs-job.h 17 May 2004 00:22:39 -0000
@@ -330,10 +330,15 @@
/* ID of the job (e.g. open, create, close...). */
GnomeVFSOpType type;
+
/* The callback for when the op is completed. */
GFunc callback;
gpointer callback_data;
+ /* Whether to directly invoke the callback instead of queueing
+ an idle handler */
+ gboolean direct_callback;
+
/* Details of the op. */
GnomeVFSSpecificOp specifics;
@@ -404,20 +409,19 @@
*/
GnomeVFSOp *op;
- /* Unique identifier of this job (a uint, really) */
- GnomeVFSAsyncHandle *job_handle;
-
/* The priority of this job */
int priority;
};
GnomeVFSJob *_gnome_vfs_job_new (GnomeVFSOpType type,
int priority,
+ gboolean direct_callback,
GFunc callback,
gpointer callback_data);
void _gnome_vfs_job_destroy (GnomeVFSJob *job);
void _gnome_vfs_job_set (GnomeVFSJob *job,
GnomeVFSOpType type,
+ gboolean direct_callback,
GFunc callback,
gpointer callback_data);
void _gnome_vfs_job_go (GnomeVFSJob *job);
Index: libgnomevfs/gnome-vfs-job.c
===================================================================
RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-job.c,v
retrieving revision 1.100
diff -u -d -r1.100 gnome-vfs-job.c
--- libgnomevfs/gnome-vfs-job.c 1 Apr 2004 10:58:37 -0000 1.100
+++ libgnomevfs/gnome-vfs-job.c 17 May 2004 00:22:41 -0000
@@ -34,6 +34,7 @@
#include "gnome-vfs-job-slave.h"
#include "gnome-vfs-job-queue.h"
#include "gnome-vfs-private-utils.h"
+#include "gnome-vfs-handle-private.h"
#include <errno.h>
#include <glib/gmessages.h>
#include <glib/gstrfuncs.h>
@@ -111,22 +112,32 @@
}
}
-/* This notifies the master thread asynchronously, without waiting for an
- * acknowledgment.
- */
static void
job_oneway_notify (GnomeVFSJob *job, GnomeVFSNotifyResult *notify_result)
{
- if (_gnome_vfs_async_job_add_callback (job, notify_result)) {
+ if (job->op->direct_callback) {
+ JOB_DEBUG (("job %u, direct callback %u type '%s'",
+ _gnome_vfs_handle_get_async_id (notify_result->job_handle),
+ notify_result->callback_id,
+ JOB_DEBUG_TYPE (job->op->type)));
+ /* This operation is an asynchronous call that we're waiting
+ * for synchronously internally. Thus we directly invoke
+ * the callback here.
+ */
+ dispatch_job_callback (notify_result);
+ } else if (_gnome_vfs_async_job_add_callback (job, notify_result)) {
JOB_DEBUG (("job %u, callback %u type '%s'",
- GPOINTER_TO_UINT (notify_result->job_handle),
+ _gnome_vfs_handle_get_async_id (notify_result->job_handle),
notify_result->callback_id,
JOB_DEBUG_TYPE (job->op->type)));
+ /* This notifies the master thread asynchronously, without waiting for an
+ * acknowledgment.
+ */
g_idle_add (dispatch_job_callback, notify_result);
} else {
JOB_DEBUG (("Barfing on oneway cancel %u (%d) type '%s'",
- GPOINTER_TO_UINT (notify_result->job_handle),
+ _gnome_vfs_handle_get_async_id (notify_result->job_handle),
job->op->type, JOB_DEBUG_TYPE (job->op->type)));
/* TODO: We can leak handle here, if an open succeded.
* See bug #123472 */
@@ -141,7 +152,7 @@
{
if (!_gnome_vfs_async_job_add_callback (job, notify_result)) {
JOB_DEBUG (("Barfing on sync cancel %u (%d)",
- GPOINTER_TO_UINT (notify_result->job_handle),
+ _gnome_vfs_handle_get_async_id (notify_result->job_handle),
job->op->type));
_gnome_vfs_job_destroy_notify_result (notify_result);
return;
@@ -152,11 +163,12 @@
*/
g_idle_add (dispatch_sync_job_callback, notify_result);
- JOB_DEBUG (("Wait notify condition %u", GPOINTER_TO_UINT (notify_result->job_handle)));
+ JOB_DEBUG (("Wait notify condition %u", _gnome_vfs_handle_get_async_id (notify_result->job_handle)));
+
/* Wait for the notify condition. */
g_cond_wait (job->notify_ack_condition, job->job_lock);
- JOB_DEBUG (("Got notify ack condition %u", GPOINTER_TO_UINT (notify_result->job_handle)));
+ JOB_DEBUG (("Got notify ack condition %u", _gnome_vfs_handle_get_async_id (notify_result->job_handle)));
}
static void
@@ -318,7 +330,7 @@
handle_cancelled_open (GnomeVFSJob *job)
{
/* schedule a silent close to make sure the handle does not leak */
- _gnome_vfs_job_set (job, GNOME_VFS_OP_CLOSE,
+ _gnome_vfs_job_set (job, GNOME_VFS_OP_CLOSE, job->op->direct_callback,
(GFunc) empty_close_callback, NULL);
_gnome_vfs_job_go (job);
}
@@ -462,7 +474,7 @@
g_assert (job != NULL);
- JOB_DEBUG (("signalling %u", GPOINTER_TO_UINT (notify_result->job_handle)));
+ JOB_DEBUG (("signalling %u", _gnome_vfs_handle_get_async_id (notify_result->job_handle)));
/* Signal the async thread that we are done with the notification. */
g_cond_signal (job->notify_ack_condition);
@@ -483,7 +495,7 @@
notify_result = (GnomeVFSNotifyResult *) data;
- JOB_DEBUG (("%u type '%s'", GPOINTER_TO_UINT (notify_result->job_handle),
+ JOB_DEBUG (("%u type '%s'", _gnome_vfs_handle_get_async_id (notify_result->job_handle),
JOB_DEBUG_TYPE (notify_result->type)));
_gnome_vfs_async_job_callback_valid (notify_result->callback_id, &valid, &cancelled);
@@ -500,7 +512,7 @@
if (cancelled) {
/* cancel the job in progress */
JOB_DEBUG (("cancelling job %u %u",
- GPOINTER_TO_UINT (notify_result->job_handle),
+ _gnome_vfs_handle_get_async_id (notify_result->job_handle),
notify_result->callback_id));
_gnome_vfs_async_job_map_lock ();
@@ -520,7 +532,7 @@
g_mutex_unlock (job->job_lock);
handle_cancelled_open (job);
JOB_DEBUG (("handle cancel open job %u",
- GPOINTER_TO_UINT (notify_result->job_handle)));
+ _gnome_vfs_handle_get_async_id (notify_result->job_handle)));
break;
} /* else drop through */
default:
@@ -537,7 +549,7 @@
}
- JOB_DEBUG (("executing callback %u", GPOINTER_TO_UINT (notify_result->job_handle)));
+ JOB_DEBUG (("executing callback %u", _gnome_vfs_handle_get_async_id (notify_result->job_handle)));
switch (notify_result->type) {
case GNOME_VFS_OP_CLOSE:
@@ -587,7 +599,7 @@
break;
}
- JOB_DEBUG (("dispatch callback - done %u", GPOINTER_TO_UINT (notify_result->job_handle)));
+ JOB_DEBUG (("dispatch callback - done %u", _gnome_vfs_handle_get_async_id (notify_result->job_handle)));
_gnome_vfs_job_destroy_notify_result (notify_result);
return FALSE;
@@ -595,9 +607,10 @@
void
_gnome_vfs_job_set (GnomeVFSJob *job,
- GnomeVFSOpType type,
- GFunc callback,
- gpointer callback_data)
+ GnomeVFSOpType type,
+ gboolean direct_callback,
+ GFunc callback,
+ gpointer callback_data)
{
GnomeVFSOp *op;
@@ -605,6 +618,7 @@
op->type = type;
op->callback = callback;
op->callback_data = callback_data;
+ op->direct_callback = direct_callback;
op->context = gnome_vfs_context_new ();
op->stack_info = _gnome_vfs_module_callback_get_stack_info ();
@@ -625,7 +639,8 @@
}
GnomeVFSJob *
-_gnome_vfs_job_new (GnomeVFSOpType type, int priority, GFunc callback, gpointer callback_data)
+_gnome_vfs_job_new (GnomeVFSOpType type, int priority, gboolean direct_callback,
+ GFunc callback, gpointer callback_data)
{
GnomeVFSJob *new_job;
@@ -639,7 +654,7 @@
* the job a unique id
*/
_gnome_vfs_async_job_map_add_job (new_job);
- _gnome_vfs_job_set (new_job, type, callback, callback_data);
+ _gnome_vfs_job_set (new_job, type, direct_callback, callback, callback_data);
job_count++;
@@ -965,10 +980,11 @@
open_op->open_mode,
job->op->context);
job->handle = handle;
+ _gnome_vfs_handle_set_asynchronous (handle);
}
notify_result = g_new0 (GnomeVFSNotifyResult, 1);
- notify_result->job_handle = job->job_handle;
+ notify_result->job_handle = job->handle;
notify_result->type = job->op->type;
notify_result->specifics.open.result = result;
notify_result->specifics.open.callback = (GnomeVFSAsyncOpenCallback) job->op->callback;
@@ -1006,7 +1022,7 @@
}
notify_result = g_new0 (GnomeVFSNotifyResult, 1);
- notify_result->job_handle = job->job_handle;
+ notify_result->job_handle = job->handle;
notify_result->type = job->op->type;
notify_result->specifics.open_as_channel.result = result;
notify_result->specifics.open_as_channel.callback =
@@ -1083,10 +1099,11 @@
job->op->context);
job->handle = handle;
+ _gnome_vfs_handle_set_asynchronous (handle);
}
notify_result = g_new0 (GnomeVFSNotifyResult, 1);
- notify_result->job_handle = job->job_handle;
+ notify_result->job_handle = job->handle;
notify_result->type = job->op->type;
notify_result->specifics.create.result = result;
notify_result->specifics.create.callback = (GnomeVFSAsyncCreateCallback) job->op->callback;
@@ -1115,7 +1132,7 @@
job->op->context);
notify_result = g_new0 (GnomeVFSNotifyResult, 1);
- notify_result->job_handle = job->job_handle;
+ notify_result->job_handle = job->handle;
notify_result->type = job->op->type;
notify_result->specifics.create.result = result;
notify_result->specifics.create.callback = (GnomeVFSAsyncCreateCallback) job->op->callback;
@@ -1152,7 +1169,7 @@
}
notify_result = g_new0 (GnomeVFSNotifyResult, 1);
- notify_result->job_handle = job->job_handle;
+ notify_result->job_handle = job->handle;
notify_result->type = job->op->type;
notify_result->specifics.create_as_channel.result = result;
notify_result->specifics.create_as_channel.callback = (GnomeVFSAsyncCreateAsChannelCallback) job->op->callback;
@@ -1194,7 +1211,7 @@
close_op = &job->op->specifics.close;
notify_result = g_new0 (GnomeVFSNotifyResult, 1);
- notify_result->job_handle = job->job_handle;
+ notify_result->job_handle = job->handle;
notify_result->type = job->op->type;
notify_result->specifics.close.callback = (GnomeVFSAsyncCloseCallback) job->op->callback;
notify_result->specifics.close.callback_data = job->op->callback_data;
@@ -1213,7 +1230,7 @@
read_op = &job->op->specifics.read;
notify_result = g_new0 (GnomeVFSNotifyResult, 1);
- notify_result->job_handle = job->job_handle;
+ notify_result->job_handle = job->handle;
notify_result->type = job->op->type;
notify_result->specifics.read.callback = (GnomeVFSAsyncReadCallback) job->op->callback;
notify_result->specifics.read.callback_data = job->op->callback_data;
@@ -1240,7 +1257,7 @@
write_op = &job->op->specifics.write;
notify_result = g_new0 (GnomeVFSNotifyResult, 1);
- notify_result->job_handle = job->job_handle;
+ notify_result->job_handle = job->handle;
notify_result->type = job->op->type;
notify_result->specifics.write.callback = (GnomeVFSAsyncWriteCallback) job->op->callback;
notify_result->specifics.write.callback_data = job->op->callback_data;
@@ -1273,7 +1290,7 @@
job->op->context);
notify_result = g_new0 (GnomeVFSNotifyResult, 1);
- notify_result->job_handle = job->job_handle;
+ notify_result->job_handle = job->handle;
notify_result->type = job->op->type;
notify_result->specifics.seek.result = result;
notify_result->specifics.seek.callback = (GnomeVFSAsyncSeekCallback) job->op->callback;
@@ -1293,7 +1310,7 @@
get_file_info_op = &job->op->specifics.get_file_info;
notify_result = g_new0 (GnomeVFSNotifyResult, 1);
- notify_result->job_handle = job->job_handle;
+ notify_result->job_handle = job->handle;
notify_result->type = job->op->type;
notify_result->specifics.get_file_info.callback =
(GnomeVFSAsyncGetFileInfoCallback) job->op->callback;
@@ -1330,7 +1347,7 @@
set_file_info_op = &job->op->specifics.set_file_info;
notify_result = g_new0 (GnomeVFSNotifyResult, 1);
- notify_result->job_handle = job->job_handle;
+ notify_result->job_handle = job->handle;
notify_result->type = job->op->type;
notify_result->specifics.set_file_info.callback =
(GnomeVFSAsyncSetFileInfoCallback) job->op->callback;
@@ -1386,7 +1403,7 @@
GnomeVFSNotifyResult *notify_result;
notify_result = g_new0 (GnomeVFSNotifyResult, 1);
- notify_result->job_handle = job->job_handle;
+ notify_result->job_handle = job->handle;
notify_result->type = job->op->type;
notify_result->specifics.find_directory.callback
= (GnomeVFSAsyncFindDirectoryCallback) job->op->callback;
@@ -1440,7 +1457,7 @@
if (result != GNOME_VFS_OK) {
notify_result = g_new0 (GnomeVFSNotifyResult, 1);
- notify_result->job_handle = job->job_handle;
+ notify_result->job_handle = job->handle;
notify_result->type = job->op->type;
notify_result->specifics.load_directory.result = result;
notify_result->specifics.load_directory.callback =
@@ -1479,7 +1496,7 @@
|| result != GNOME_VFS_OK) {
notify_result = g_new0 (GnomeVFSNotifyResult, 1);
- notify_result->job_handle = job->job_handle;
+ notify_result->job_handle = job->handle;
notify_result->type = job->op->type;
notify_result->specifics.load_directory.result = result;
notify_result->specifics.load_directory.entries_read = count;
@@ -1525,7 +1542,7 @@
job = (GnomeVFSJob *) data;
/* xfer is fully synchronous, just allocate the notify result struct on the stack */
- notify_result.job_handle = job->job_handle;
+ notify_result.job_handle = job->handle;
notify_result.callback_id = 0;
notify_result.cancelled = FALSE;
notify_result.type = job->op->type;
@@ -1576,7 +1593,7 @@
info.bytes_copied = 0;
info.total_bytes_copied = 0;
- notify_result.job_handle = job->job_handle;
+ notify_result.job_handle = job->handle;
notify_result.callback_id = 0;
notify_result.cancelled = FALSE;
notify_result.type = job->op->type;
@@ -1597,7 +1614,7 @@
file_control_op = &job->op->specifics.file_control;
notify_result = g_new0 (GnomeVFSNotifyResult, 1);
- notify_result->job_handle = job->job_handle;
+ notify_result->job_handle = job->handle;
notify_result->type = job->op->type;
notify_result->specifics.file_control.callback = (GnomeVFSAsyncFileControlCallback) job->op->callback;
notify_result->specifics.file_control.callback_data = job->op->callback_data;
@@ -1627,7 +1644,7 @@
{
guint id;
- id = GPOINTER_TO_UINT (job->job_handle);
+ id = _gnome_vfs_handle_get_async_id (job->handle);
JOB_DEBUG (("exec job %u", id));
@@ -1779,7 +1796,7 @@
memset (¬ify_result, 0, sizeof (notify_result));
- notify_result.job_handle = job->job_handle;
+ notify_result.job_handle = job->handle;
notify_result.type = GNOME_VFS_OP_MODULE_CALLBACK;
Index: libgnomevfs/gnome-vfs-job-slave.c
===================================================================
RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-job-slave.c,v
retrieving revision 1.26
diff -u -d -r1.26 gnome-vfs-job-slave.c
--- libgnomevfs/gnome-vfs-job-slave.c 19 Dec 2002 17:57:19 -0000 1.26
+++ libgnomevfs/gnome-vfs-job-slave.c 17 May 2004 00:22:41 -0000
@@ -96,11 +96,11 @@
return FALSE;
}
- if (_gnome_vfs_thread_create (thread_routine, job->job_handle) != 0) {
+ if (_gnome_vfs_thread_create (thread_routine, job->handle) != 0) {
g_warning ("Impossible to allocate a new GnomeVFSJob thread.");
/* thread did not start up, remove the job from the hash table */
- _gnome_vfs_async_job_completed (job->job_handle);
+ _gnome_vfs_async_job_completed (job->handle);
_gnome_vfs_job_destroy (job);
return FALSE;
}
Index: libgnomevfs/gnome-vfs-handle.c
===================================================================
RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-handle.c,v
retrieving revision 1.23
diff -u -d -r1.23 gnome-vfs-handle.c
--- libgnomevfs/gnome-vfs-handle.c 19 Dec 2002 17:57:19 -0000 1.23
+++ libgnomevfs/gnome-vfs-handle.c 17 May 2004 00:22:41 -0000
@@ -37,6 +37,13 @@
/* Open mode. */
GnomeVFSOpenMode open_mode;
+
+ /* Data for asynchronous operations */
+ gboolean is_async;
+ guint async_id;
+ gboolean async_done;
+ GMutex *async_mutex;
+ GCond *async_cond;
};
#define CHECK_IF_OPEN(handle) \
@@ -77,11 +84,12 @@
g_return_val_if_fail (uri != NULL, NULL);
g_return_val_if_fail (method_handle != NULL, NULL);
- new = g_new (GnomeVFSHandle, 1);
+ new = g_new0 (GnomeVFSHandle, 1);
new->uri = gnome_vfs_uri_ref (uri);
new->method_handle = method_handle;
new->open_mode = open_mode;
+ new->is_async = FALSE;
return new;
}
@@ -93,8 +101,68 @@
gnome_vfs_uri_unref (handle->uri);
+ if (handle->is_async) {
+ g_mutex_free (handle->async_mutex);
+ g_cond_free (handle->async_cond);
+ }
+
g_free (handle);
}
+
+
+/* Asynchronous stuff */
+
+void
+_gnome_vfs_handle_set_asynchronous (GnomeVFSHandle *handle)
+{
+ handle->is_async = TRUE;
+ handle->async_mutex = g_mutex_new ();
+ handle->async_cond = g_cond_new ();
+}
+
+gboolean
+_gnome_vfs_handle_get_asynchronous (GnomeVFSHandle *handle)
+{
+ return handle->is_async;
+}
+
+guint
+_gnome_vfs_handle_get_async_id (const GnomeVFSHandle *handle)
+{
+ return handle->async_id;
+}
+
+void
+_gnome_vfs_handle_set_async_id (GnomeVFSHandle *handle,
+ guint id)
+{
+ handle->async_id = id;
+}
+
+gboolean
+_gnome_vfs_handle_async_wait (GnomeVFSHandle *handle,
+ GnomeVFSContext *context)
+{
+ g_mutex_lock (handle->async_mutex);
+ while (!handle->async_done) {
+ GTimeVal current_time;
+ g_mutex_unlock (handle->async_mutex);
+ g_get_current_time (¤t_time);
+ g_time_val_add (¤t_time, G_USEC_PER_SEC);
+ g_cond_timed_wait (handle->async_cond, handle->async_mutex, ¤t_time);
+ if (gnome_vfs_context_check_cancellation (context)) {
+ g_mutex_unlock (handle->async_mutex);
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+void
+_gnome_vfs_handle_signal_async (GnomeVFSHandle *handle)
+{
+}
+
GnomeVFSOpenMode
Index: libgnomevfs/gnome-vfs-handle-private.h
===================================================================
RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-handle-private.h,v
retrieving revision 1.3
diff -u -d -r1.3 gnome-vfs-handle-private.h
--- libgnomevfs/gnome-vfs-handle-private.h 19 Dec 2002 17:57:19 -0000 1.3
+++ libgnomevfs/gnome-vfs-handle-private.h 17 May 2004 00:22:41 -0000
@@ -30,6 +30,14 @@
GnomeVFSMethodHandle *method_handle,
GnomeVFSOpenMode open_mode);
void _gnome_vfs_handle_destroy (GnomeVFSHandle *handle);
+void _gnome_vfs_handle_set_asynchronous (GnomeVFSHandle *handle);
+gboolean _gnome_vfs_handle_get_asynchronous (GnomeVFSHandle *handle);
+guint _gnome_vfs_handle_get_async_id (const GnomeVFSHandle *handle);
+void _gnome_vfs_handle_set_async_id (GnomeVFSHandle *handle,
+ guint id);
+gboolean _gnome_vfs_handle_async_wait (GnomeVFSHandle *handle,
+ GnomeVFSContext *context);
+void _gnome_vfs_handle_signal_async (GnomeVFSHandle *handle);
GnomeVFSOpenMode _gnome_vfs_handle_get_open_mode (GnomeVFSHandle *handle);
GnomeVFSResult _gnome_vfs_handle_do_close (GnomeVFSHandle *handle,
GnomeVFSContext *context);
Index: libgnomevfs/gnome-vfs-cancellable-ops.c
===================================================================
RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-cancellable-ops.c,v
retrieving revision 1.31
diff -u -d -r1.31 gnome-vfs-cancellable-ops.c
--- libgnomevfs/gnome-vfs-cancellable-ops.c 11 Mar 2004 08:06:30 -0000 1.31
+++ libgnomevfs/gnome-vfs-cancellable-ops.c 17 May 2004 00:22:41 -0000
@@ -27,6 +27,7 @@
#include <config.h>
#include "gnome-vfs-cancellable-ops.h"
+#include "gnome-vfs-async-ops-private.h"
#include "gnome-vfs-method.h"
#include "gnome-vfs-private-utils.h"
#include "gnome-vfs-handle-private.h"
@@ -35,6 +36,47 @@
#include <glib/gutils.h>
#include <string.h>
+static void
+wrap_generic_async_cb (GnomeVFSAsyncHandle *handle,
+ GnomeVFSResult result,
+ gpointer callback_data)
+{
+ GnomeVFSResult *result_ptr = (GnomeVFSResult *) callback_data;
+ *result_ptr = result;
+ _gnome_vfs_handle_signal_async (handle);
+}
+
+struct GnomeVFSWrapAsyncRWData
+{
+ GnomeVFSResult result;
+ GnomeVFSFileSize bytes_read;
+};
+
+static void
+wrap_rw_async_cb (GnomeVFSAsyncHandle *handle,
+ GnomeVFSResult result,
+ gpointer buffer,
+ GnomeVFSFileSize bytes_requested,
+ GnomeVFSFileSize bytes_read,
+ gpointer callback_data)
+{
+ struct GnomeVFSWrapAsyncRWData *data = callback_data;
+ data->result = result;
+ data->bytes_read = bytes_read;
+ _gnome_vfs_handle_signal_async (handle);
+}
+
+static void
+wrap_file_control_async_cb (GnomeVFSAsyncHandle *handle,
+ GnomeVFSResult result,
+ gpointer operation_data, /* ignored */
+ gpointer callback_data)
+{
+ GnomeVFSResult *result_ptr = (GnomeVFSResult *) callback_data;
+ *result_ptr = result;
+ _gnome_vfs_handle_signal_async (handle);
+}
+
GnomeVFSResult
gnome_vfs_open_uri_cancellable (GnomeVFSHandle **handle,
GnomeVFSURI *uri,
@@ -99,12 +141,22 @@
gnome_vfs_close_cancellable (GnomeVFSHandle *handle,
GnomeVFSContext *context)
{
+ GnomeVFSResult result;
g_return_val_if_fail (handle != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS);
if (gnome_vfs_context_check_cancellation (context))
return GNOME_VFS_ERROR_CANCELLED;
- return _gnome_vfs_handle_do_close (handle, context);
+ if (!_gnome_vfs_handle_get_asynchronous (handle))
+ return _gnome_vfs_handle_do_close (handle, context);
+
+ _gnome_vfs_async_close_internal (handle,
+ TRUE,
+ wrap_generic_async_cb,
+ &result);
+ if (!_gnome_vfs_handle_async_wait (handle, context))
+ return GNOME_VFS_ERROR_CANCELLED;
+ return result;
}
GnomeVFSResult
@@ -114,6 +166,7 @@
GnomeVFSFileSize *bytes_read,
GnomeVFSContext *context)
{
+ struct GnomeVFSWrapAsyncRWData async_data;
GnomeVFSFileSize dummy_bytes_read;
g_return_val_if_fail (handle != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS);
@@ -125,8 +178,18 @@
bytes_read = &dummy_bytes_read;
}
- return _gnome_vfs_handle_do_read (handle, buffer, bytes, bytes_read,
- context);
+ if (!_gnome_vfs_handle_get_asynchronous (handle))
+ return _gnome_vfs_handle_do_read (handle, buffer, bytes, bytes_read,
+ context);
+
+ _gnome_vfs_async_read_internal (handle,
+ buffer, bytes,
+ TRUE,
+ (GnomeVFSAsyncReadCallback) wrap_rw_async_cb,
+ &async_data);
+ if (!_gnome_vfs_handle_async_wait (handle, context))
+ return GNOME_VFS_ERROR_CANCELLED;
+ return async_data.result;
}
GnomeVFSResult
@@ -136,6 +199,7 @@
GnomeVFSFileSize *bytes_written,
GnomeVFSContext *context)
{
+ struct GnomeVFSWrapAsyncRWData async_data;
GnomeVFSFileSize dummy_bytes_written;
g_return_val_if_fail (handle != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS);
@@ -147,8 +211,17 @@
bytes_written = &dummy_bytes_written;
}
- return _gnome_vfs_handle_do_write (handle, buffer, bytes,
- bytes_written, context);
+ if (!_gnome_vfs_handle_get_asynchronous (handle))
+ return _gnome_vfs_handle_do_write (handle, buffer, bytes,
+ bytes_written, context);
+ _gnome_vfs_async_write_internal (handle,
+ buffer, bytes,
+ TRUE,
+ (GnomeVFSAsyncWriteCallback) wrap_rw_async_cb,
+ &async_data);
+ if (!_gnome_vfs_handle_async_wait (handle, context))
+ return GNOME_VFS_ERROR_CANCELLED;
+ return async_data.result;
}
GnomeVFSResult
@@ -157,12 +230,23 @@
GnomeVFSFileOffset offset,
GnomeVFSContext *context)
{
+ GnomeVFSResult result;
+
g_return_val_if_fail (handle != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS);
if (gnome_vfs_context_check_cancellation (context))
return GNOME_VFS_ERROR_CANCELLED;
- return _gnome_vfs_handle_do_seek (handle, whence, offset, context);
+ if (!_gnome_vfs_handle_get_asynchronous (handle))
+ return _gnome_vfs_handle_do_seek (handle, whence, offset, context);
+ _gnome_vfs_async_seek_internal (handle,
+ whence, offset,
+ TRUE,
+ wrap_generic_async_cb,
+ &result);
+ if (!_gnome_vfs_handle_async_wait (handle, context))
+ return GNOME_VFS_ERROR_CANCELLED;
+ return result;
}
GnomeVFSResult
@@ -171,8 +255,6 @@
GnomeVFSFileInfoOptions options,
GnomeVFSContext *context)
{
- GnomeVFSResult result;
-
g_return_val_if_fail (uri != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS);
if (gnome_vfs_context_check_cancellation (context))
@@ -181,10 +263,8 @@
if (!VFS_METHOD_HAS_FUNC(uri->method, get_file_info))
return GNOME_VFS_ERROR_NOT_SUPPORTED;
- result = uri->method->get_file_info (uri->method, uri, info, options,
- context);
-
- return result;
+ return uri->method->get_file_info (uri->method, uri, info, options,
+ context);
}
GnomeVFSResult
@@ -194,19 +274,17 @@
GnomeVFSContext *context)
{
- GnomeVFSResult result;
-
g_return_val_if_fail (handle != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS);
if (gnome_vfs_context_check_cancellation (context))
return GNOME_VFS_ERROR_CANCELLED;
- result = _gnome_vfs_handle_do_get_file_info (handle, info,
- options,
- context);
-
- return result;
+ if (!_gnome_vfs_handle_get_asynchronous (handle))
+ return _gnome_vfs_handle_do_get_file_info (handle, info,
+ options,
+ context);
+ return GNOME_VFS_ERROR_NOT_SUPPORTED; /* FIXME: need to map to async operation */
}
GnomeVFSResult
@@ -235,7 +313,9 @@
if (gnome_vfs_context_check_cancellation (context))
return GNOME_VFS_ERROR_CANCELLED;
- return _gnome_vfs_handle_do_truncate (handle, length, context);
+ if (!_gnome_vfs_handle_get_asynchronous (handle))
+ return _gnome_vfs_handle_do_truncate (handle, length, context);
+ return GNOME_VFS_ERROR_NOT_SUPPORTED; /* FIXME: need to map to async operation */
}
GnomeVFSResult
@@ -448,12 +528,25 @@
gpointer operation_data,
GnomeVFSContext *context)
{
+ GnomeVFSResult result;
+
g_return_val_if_fail (handle != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS);
g_return_val_if_fail (operation != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS);
if (gnome_vfs_context_check_cancellation (context))
return GNOME_VFS_ERROR_CANCELLED;
- return _gnome_vfs_handle_do_file_control (handle, operation, operation_data, context);
+ if (!_gnome_vfs_handle_get_asynchronous (handle))
+ return _gnome_vfs_handle_do_file_control (handle, operation, operation_data, context);
+
+ _gnome_vfs_async_file_control_internal (handle,
+ operation, operation_data,
+ NULL,
+ TRUE,
+ wrap_file_control_async_cb,
+ &result);
+ if (!_gnome_vfs_handle_async_wait (handle, context))
+ return GNOME_VFS_ERROR_CANCELLED;
+ return result;
}
Index: libgnomevfs/gnome-vfs-async-ops.h
===================================================================
RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-async-ops.h,v
retrieving revision 1.36
diff -u -d -r1.36 gnome-vfs-async-ops.h
--- libgnomevfs/gnome-vfs-async-ops.h 20 Oct 2003 11:55:54 -0000 1.36
+++ libgnomevfs/gnome-vfs-async-ops.h 17 May 2004 00:22:41 -0000
@@ -54,7 +54,10 @@
#define GNOME_VFS_PRIORITY_MAX 10
#define GNOME_VFS_PRIORITY_DEFAULT 0
-typedef struct GnomeVFSAsyncHandle GnomeVFSAsyncHandle;
+/* This used to be a typedef for struct GnomeVFSAsyncHandle,
+ * but now an async handle is just a special kind of GnomeVFSHandle.
+ */
+#define GnomeVFSAsyncHandle GnomeVFSHandle
/**
* GnomeVFSAsyncCallback:
Index: libgnomevfs/gnome-vfs-async-ops.c
===================================================================
RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-async-ops.c,v
retrieving revision 1.10
diff -u -d -r1.10 gnome-vfs-async-ops.c
--- libgnomevfs/gnome-vfs-async-ops.c 20 Oct 2003 11:55:54 -0000 1.10
+++ libgnomevfs/gnome-vfs-async-ops.c 17 May 2004 00:22:42 -0000
@@ -23,7 +23,7 @@
#include <config.h>
-#include "gnome-vfs-async-ops.h"
+#include "gnome-vfs-async-ops-private.h"
#include "gnome-vfs-async-job-map.h"
#include "gnome-vfs-job.h"
#include "gnome-vfs-job-queue.h"
@@ -48,7 +48,6 @@
job = _gnome_vfs_async_job_map_get_job (handle);
if (job == NULL) {
- JOB_DEBUG (("job %u - job no longer exists", GPOINTER_TO_UINT (handle)));
/* have to cancel the callbacks because they still can be pending */
_gnome_vfs_async_job_cancel_job_and_callbacks (handle, NULL);
} else {
@@ -73,14 +72,15 @@
GnomeVFSOpenOp *open_op;
GnomeVFSAsyncHandle *result;
- job = _gnome_vfs_job_new (GNOME_VFS_OP_OPEN, priority, (GFunc) callback, callback_data);
+ job = _gnome_vfs_job_new (GNOME_VFS_OP_OPEN, priority,
+ FALSE, (GFunc) callback, callback_data);
open_op = &job->op->specifics.open;
open_op->uri = uri == NULL ? NULL : gnome_vfs_uri_ref (uri);
open_op->open_mode = open_mode;
- result = job->job_handle;
+ result = job->handle;
_gnome_vfs_job_go (job);
return result;
@@ -172,14 +172,15 @@
GnomeVFSOpenAsChannelOp *open_as_channel_op;
GnomeVFSAsyncHandle *result;
- job = _gnome_vfs_job_new (GNOME_VFS_OP_OPEN_AS_CHANNEL, priority, (GFunc) callback, callback_data);
+ job = _gnome_vfs_job_new (GNOME_VFS_OP_OPEN_AS_CHANNEL, priority,
+ FALSE, (GFunc) callback, callback_data);
open_as_channel_op = &job->op->specifics.open_as_channel;
open_as_channel_op->uri = uri == NULL ? NULL : gnome_vfs_uri_ref (uri);
open_as_channel_op->open_mode = open_mode;
open_as_channel_op->advised_block_size = advised_block_size;
- result = job->job_handle;
+ result = job->handle;
_gnome_vfs_job_go (job);
return result;
@@ -276,7 +277,8 @@
GnomeVFSCreateOp *create_op;
GnomeVFSAsyncHandle *result;
- job = _gnome_vfs_job_new (GNOME_VFS_OP_CREATE, priority, (GFunc) callback, callback_data);
+ job = _gnome_vfs_job_new (GNOME_VFS_OP_CREATE, priority,
+ FALSE, (GFunc) callback, callback_data);
create_op = &job->op->specifics.create;
create_op->uri = uri == NULL ? NULL : gnome_vfs_uri_ref (uri);
@@ -284,7 +286,7 @@
create_op->exclusive = exclusive;
create_op->perm = perm;
- result = job->job_handle;
+ result = job->handle;
_gnome_vfs_job_go (job);
return result;
@@ -416,8 +418,8 @@
g_return_if_fail (priority >= GNOME_VFS_PRIORITY_MIN);
g_return_if_fail (priority <= GNOME_VFS_PRIORITY_MAX);
- job = _gnome_vfs_job_new (GNOME_VFS_OP_CREATE_AS_CHANNEL, priority, (GFunc) callback, callback_data);
-
+ job = _gnome_vfs_job_new (GNOME_VFS_OP_CREATE_AS_CHANNEL, priority,
+ FALSE, (GFunc) callback, callback_data);
create_as_channel_op = &job->op->specifics.create_as_channel;
create_as_channel_op->uri = gnome_vfs_uri_new (text_uri);
@@ -425,24 +427,16 @@
create_as_channel_op->exclusive = exclusive;
create_as_channel_op->perm = perm;
- result = job->job_handle;
+ result = job->handle;
_gnome_vfs_job_go (job);
}
-/**
- * gnome_vfs_async_close:
- * @handle: async handle to close
- * @callback: function to be called when the operation is complete
- * @callback_data: data to pass @callback
- *
- * Close a handle opened with gnome_vfs_async_open(). When the close
- * has completed, @callback will be called with @callback_data and
- * the result of the operation.
- **/
+
void
-gnome_vfs_async_close (GnomeVFSAsyncHandle *handle,
- GnomeVFSAsyncCloseCallback callback,
- gpointer callback_data)
+_gnome_vfs_async_close_internal (GnomeVFSAsyncHandle *handle,
+ gboolean direct_callback,
+ GnomeVFSAsyncCloseCallback callback,
+ gpointer callback_data)
{
GnomeVFSJob *job;
@@ -461,7 +455,8 @@
if (job->op->type != GNOME_VFS_OP_READ &&
job->op->type != GNOME_VFS_OP_WRITE) {
_gnome_vfs_job_set (job, GNOME_VFS_OP_CLOSE,
- (GFunc) callback, callback_data);
+ direct_callback,
+ (GFunc) callback, callback_data);
_gnome_vfs_job_go (job);
_gnome_vfs_async_job_map_unlock ();
return;
@@ -479,6 +474,58 @@
}
/**
+ * gnome_vfs_async_close:
+ * @handle: async handle to close
+ * @callback: function to be called when the operation is complete
+ * @callback_data: data to pass @callback
+ *
+ * Close a handle opened with gnome_vfs_async_open(). When the close
+ * has completed, @callback will be called with @callback_data and
+ * the result of the operation.
+ **/
+void
+gnome_vfs_async_close (GnomeVFSAsyncHandle *handle,
+ GnomeVFSAsyncCloseCallback callback,
+ gpointer callback_data)
+{
+ _gnome_vfs_async_close_internal (handle, FALSE, callback, callback_data);
+}
+
+void
+_gnome_vfs_async_read_internal (GnomeVFSAsyncHandle *handle,
+ gpointer buffer,
+ guint bytes,
+ gboolean direct_callback,
+ GnomeVFSAsyncReadCallback callback,
+ gpointer callback_data)
+{
+ GnomeVFSJob *job;
+ GnomeVFSReadOp *read_op;
+
+ g_return_if_fail (handle != NULL);
+ g_return_if_fail (buffer != NULL);
+ g_return_if_fail (callback != NULL);
+
+ _gnome_vfs_async_job_map_lock ();
+ job = _gnome_vfs_async_job_map_get_job (handle);
+ if (job == NULL) {
+ g_warning ("trying to read from a non-existing handle");
+ _gnome_vfs_async_job_map_unlock ();
+ return;
+ }
+
+ _gnome_vfs_job_set (job, GNOME_VFS_OP_READ, direct_callback,
+ (GFunc) callback, callback_data);
+
+ read_op = &job->op->specifics.read;
+ read_op->buffer = buffer;
+ read_op->num_bytes = bytes;
+
+ _gnome_vfs_job_go (job);
+ _gnome_vfs_async_job_map_unlock ();
+}
+
+/**
* gnome_vfs_async_read:
* @handle: handle for the file to be read
* @buffer: allocated block of memory to read into
@@ -497,8 +544,19 @@
GnomeVFSAsyncReadCallback callback,
gpointer callback_data)
{
+ _gnome_vfs_async_read_internal (handle, buffer, bytes, FALSE, callback, callback_data);
+}
+
+void
+_gnome_vfs_async_write_internal (GnomeVFSAsyncHandle *handle,
+ gconstpointer buffer,
+ guint bytes,
+ gboolean direct_callback,
+ GnomeVFSAsyncWriteCallback callback,
+ gpointer callback_data)
+{
GnomeVFSJob *job;
- GnomeVFSReadOp *read_op;
+ GnomeVFSWriteOp *write_op;
g_return_if_fail (handle != NULL);
g_return_if_fail (buffer != NULL);
@@ -507,17 +565,17 @@
_gnome_vfs_async_job_map_lock ();
job = _gnome_vfs_async_job_map_get_job (handle);
if (job == NULL) {
- g_warning ("trying to read from a non-existing handle");
+ g_warning ("trying to write to a non-existing handle");
_gnome_vfs_async_job_map_unlock ();
return;
}
- _gnome_vfs_job_set (job, GNOME_VFS_OP_READ,
+ _gnome_vfs_job_set (job, GNOME_VFS_OP_WRITE, direct_callback,
(GFunc) callback, callback_data);
- read_op = &job->op->specifics.read;
- read_op->buffer = buffer;
- read_op->num_bytes = bytes;
+ write_op = &job->op->specifics.write;
+ write_op->buffer = buffer;
+ write_op->num_bytes = bytes;
_gnome_vfs_job_go (job);
_gnome_vfs_async_job_map_unlock ();
@@ -542,27 +600,37 @@
GnomeVFSAsyncWriteCallback callback,
gpointer callback_data)
{
+ _gnome_vfs_async_write_internal (handle, buffer, bytes, FALSE, callback, callback_data);
+}
+
+void
+_gnome_vfs_async_seek_internal (GnomeVFSAsyncHandle *handle,
+ GnomeVFSSeekPosition whence,
+ GnomeVFSFileOffset offset,
+ gboolean direct_callback,
+ GnomeVFSAsyncSeekCallback callback,
+ gpointer callback_data)
+{
GnomeVFSJob *job;
- GnomeVFSWriteOp *write_op;
+ GnomeVFSSeekOp *seek_op;
g_return_if_fail (handle != NULL);
- g_return_if_fail (buffer != NULL);
g_return_if_fail (callback != NULL);
_gnome_vfs_async_job_map_lock ();
job = _gnome_vfs_async_job_map_get_job (handle);
if (job == NULL) {
- g_warning ("trying to write to a non-existing handle");
+ g_warning ("trying to seek in a non-existing handle");
_gnome_vfs_async_job_map_unlock ();
return;
}
- _gnome_vfs_job_set (job, GNOME_VFS_OP_WRITE,
+ _gnome_vfs_job_set (job, GNOME_VFS_OP_SEEK, direct_callback,
(GFunc) callback, callback_data);
- write_op = &job->op->specifics.write;
- write_op->buffer = buffer;
- write_op->num_bytes = bytes;
+ seek_op = &job->op->specifics.seek;
+ seek_op->whence = whence;
+ seek_op->offset = offset;
_gnome_vfs_job_go (job);
_gnome_vfs_async_job_map_unlock ();
@@ -588,29 +656,7 @@
GnomeVFSAsyncSeekCallback callback,
gpointer callback_data)
{
- GnomeVFSJob *job;
- GnomeVFSSeekOp *seek_op;
-
- g_return_if_fail (handle != NULL);
- g_return_if_fail (callback != NULL);
-
- _gnome_vfs_async_job_map_lock ();
- job = _gnome_vfs_async_job_map_get_job (handle);
- if (job == NULL) {
- g_warning ("trying to seek in a non-existing handle");
- _gnome_vfs_async_job_map_unlock ();
- return;
- }
-
- _gnome_vfs_job_set (job, GNOME_VFS_OP_SEEK,
- (GFunc) callback, callback_data);
-
- seek_op = &job->op->specifics.seek;
- seek_op->whence = whence;
- seek_op->offset = offset;
-
- _gnome_vfs_job_go (job);
- _gnome_vfs_async_job_map_unlock ();
+ _gnome_vfs_async_seek_internal (handle, whence, offset, FALSE, callback, callback_data);
}
/**
@@ -646,13 +692,43 @@
g_return_if_fail (priority >= GNOME_VFS_PRIORITY_MIN);
g_return_if_fail (priority <= GNOME_VFS_PRIORITY_MAX);
- job = _gnome_vfs_job_new (GNOME_VFS_OP_CREATE_SYMBOLIC_LINK, priority, (GFunc) callback, callback_data);
+ job = _gnome_vfs_job_new (GNOME_VFS_OP_CREATE_SYMBOLIC_LINK, priority, FALSE,
+ (GFunc) callback, callback_data);
create_op = &job->op->specifics.create_symbolic_link;
create_op->uri = gnome_vfs_uri_ref (uri);
create_op->uri_reference = g_strdup (uri_reference);
- *handle_return = job->job_handle;
+ *handle_return = job->handle;
+ _gnome_vfs_job_go (job);
+}
+
+void
+_gnome_vfs_async_get_file_info_internal (GnomeVFSAsyncHandle **handle_return,
+ GList *uri_list,
+ GnomeVFSFileInfoOptions options,
+ int priority,
+ gboolean direct_callback,
+ GnomeVFSAsyncGetFileInfoCallback callback,
+ gpointer callback_data)
+{
+ GnomeVFSJob *job;
+ GnomeVFSGetFileInfoOp *get_info_op;
+
+ g_return_if_fail (handle_return != NULL);
+ g_return_if_fail (callback != NULL);
+ g_return_if_fail (priority >= GNOME_VFS_PRIORITY_MIN);
+ g_return_if_fail (priority <= GNOME_VFS_PRIORITY_MAX);
+
+ job = _gnome_vfs_job_new (GNOME_VFS_OP_GET_FILE_INFO, priority,
+ direct_callback, (GFunc) callback, callback_data);
+
+ get_info_op = &job->op->specifics.get_file_info;
+
+ get_info_op->uris = gnome_vfs_uri_list_copy (uri_list);
+ get_info_op->options = options;
+
+ *handle_return = job->handle;
_gnome_vfs_job_go (job);
}
@@ -680,22 +756,44 @@
GnomeVFSAsyncGetFileInfoCallback callback,
gpointer callback_data)
{
+ _gnome_vfs_async_get_file_info_internal (handle_return, uri_list, options,
+ priority, FALSE,
+ callback, callback_data);
+}
+
+void
+_gnome_vfs_async_set_file_info_internal (GnomeVFSAsyncHandle **handle_return,
+ GnomeVFSURI *uri,
+ GnomeVFSFileInfo *info,
+ GnomeVFSSetFileInfoMask mask,
+ GnomeVFSFileInfoOptions options,
+ int priority,
+ gboolean direct_callback,
+ GnomeVFSAsyncSetFileInfoCallback callback,
+ gpointer callback_data)
+{
GnomeVFSJob *job;
- GnomeVFSGetFileInfoOp *get_info_op;
+ GnomeVFSSetFileInfoOp *op;
g_return_if_fail (handle_return != NULL);
+ g_return_if_fail (uri != NULL);
+ g_return_if_fail (info != NULL);
g_return_if_fail (callback != NULL);
g_return_if_fail (priority >= GNOME_VFS_PRIORITY_MIN);
g_return_if_fail (priority <= GNOME_VFS_PRIORITY_MAX);
- job = _gnome_vfs_job_new (GNOME_VFS_OP_GET_FILE_INFO, priority, (GFunc) callback, callback_data);
+ job = _gnome_vfs_job_new (GNOME_VFS_OP_SET_FILE_INFO, priority, direct_callback,
+ (GFunc) callback, callback_data);
- get_info_op = &job->op->specifics.get_file_info;
+ op = &job->op->specifics.set_file_info;
- get_info_op->uris = gnome_vfs_uri_list_copy (uri_list);
- get_info_op->options = options;
+ op->uri = gnome_vfs_uri_ref (uri);
+ op->info = gnome_vfs_file_info_new ();
+ gnome_vfs_file_info_copy (op->info, info);
+ op->mask = mask;
+ op->options = options;
- *handle_return = job->job_handle;
+ *handle_return = job->handle;
_gnome_vfs_job_go (job);
}
@@ -727,27 +825,43 @@
GnomeVFSAsyncSetFileInfoCallback callback,
gpointer callback_data)
{
+ _gnome_vfs_async_set_file_info_internal (handle_return, uri, info, mask,
+ options, priority, FALSE,
+ callback, callback_data);
+}
+
+void
+_gnome_vfs_async_find_directory_internal (GnomeVFSAsyncHandle **handle_return,
+ GList *near_uri_list,
+ GnomeVFSFindDirectoryKind kind,
+ gboolean create_if_needed,
+ gboolean find_if_needed,
+ guint permissions,
+ int priority,
+ gboolean direct_callback,
+ GnomeVFSAsyncFindDirectoryCallback callback,
+ gpointer user_data)
+{
GnomeVFSJob *job;
- GnomeVFSSetFileInfoOp *op;
+ GnomeVFSFindDirectoryOp *get_info_op;
g_return_if_fail (handle_return != NULL);
- g_return_if_fail (uri != NULL);
- g_return_if_fail (info != NULL);
g_return_if_fail (callback != NULL);
g_return_if_fail (priority >= GNOME_VFS_PRIORITY_MIN);
g_return_if_fail (priority <= GNOME_VFS_PRIORITY_MAX);
- job = _gnome_vfs_job_new (GNOME_VFS_OP_SET_FILE_INFO, priority, (GFunc) callback, callback_data);
+ job = _gnome_vfs_job_new (GNOME_VFS_OP_FIND_DIRECTORY, priority,
+ direct_callback, (GFunc) callback, user_data);
- op = &job->op->specifics.set_file_info;
+ get_info_op = &job->op->specifics.find_directory;
- op->uri = gnome_vfs_uri_ref (uri);
- op->info = gnome_vfs_file_info_new ();
- gnome_vfs_file_info_copy (op->info, info);
- op->mask = mask;
- op->options = options;
+ get_info_op->uris = gnome_vfs_uri_list_copy (near_uri_list);
+ get_info_op->kind = kind;
+ get_info_op->create_if_needed = create_if_needed;
+ get_info_op->find_if_needed = find_if_needed;
+ get_info_op->permissions = permissions;
- *handle_return = job->job_handle;
+ *handle_return = job->handle;
_gnome_vfs_job_go (job);
}
@@ -793,55 +907,40 @@
GnomeVFSAsyncFindDirectoryCallback callback,
gpointer user_data)
{
- GnomeVFSJob *job;
- GnomeVFSFindDirectoryOp *get_info_op;
-
- g_return_if_fail (handle_return != NULL);
- g_return_if_fail (callback != NULL);
- g_return_if_fail (priority >= GNOME_VFS_PRIORITY_MIN);
- g_return_if_fail (priority <= GNOME_VFS_PRIORITY_MAX);
-
- job = _gnome_vfs_job_new (GNOME_VFS_OP_FIND_DIRECTORY, priority, (GFunc) callback, user_data);
-
- get_info_op = &job->op->specifics.find_directory;
-
- get_info_op->uris = gnome_vfs_uri_list_copy (near_uri_list);
- get_info_op->kind = kind;
- get_info_op->create_if_needed = create_if_needed;
- get_info_op->find_if_needed = find_if_needed;
- get_info_op->permissions = permissions;
-
- *handle_return = job->job_handle;
- _gnome_vfs_job_go (job);
+ _gnome_vfs_async_find_directory_internal (handle_return, near_uri_list, kind,
+ create_if_needed, find_if_needed,
+ permissions, priority, FALSE,
+ callback, user_data);
}
-static GnomeVFSAsyncHandle *
-async_load_directory (GnomeVFSURI *uri,
- GnomeVFSFileInfoOptions options,
- guint items_per_notification,
- int priority,
- GnomeVFSAsyncDirectoryLoadCallback callback,
- gpointer callback_data)
+void
+_gnome_vfs_async_load_directory_uri_internal (GnomeVFSAsyncHandle **handle_return,
+ GnomeVFSURI *uri,
+ GnomeVFSFileInfoOptions options,
+ guint items_per_notification,
+ int priority,
+ gboolean direct_callback,
+ GnomeVFSAsyncDirectoryLoadCallback callback,
+ gpointer callback_data)
{
GnomeVFSJob *job;
GnomeVFSLoadDirectoryOp *load_directory_op;
GnomeVFSAsyncHandle *result;
- job = _gnome_vfs_job_new (GNOME_VFS_OP_LOAD_DIRECTORY, priority, (GFunc) callback, callback_data);
+ job = _gnome_vfs_job_new (GNOME_VFS_OP_LOAD_DIRECTORY, priority,
+ direct_callback, (GFunc) callback, callback_data);
load_directory_op = &job->op->specifics.load_directory;
load_directory_op->uri = uri == NULL ? NULL : gnome_vfs_uri_ref (uri);
load_directory_op->options = options;
load_directory_op->items_per_notification = items_per_notification;
- result = job->job_handle;
+ result = job->handle;
_gnome_vfs_job_go (job);
- return result;
+ *handle_return = result;
}
-
-
/**
* gnome_vfs_async_load_directory:
* @handle_return: when the function returns will point to a handle for
@@ -878,10 +977,11 @@
g_return_if_fail (priority <= GNOME_VFS_PRIORITY_MAX);
uri = gnome_vfs_uri_new (text_uri);
- *handle_return = async_load_directory (uri, options,
- items_per_notification,
- priority,
- callback, callback_data);
+ _gnome_vfs_async_load_directory_uri_internal (handle_return,
+ uri, options,
+ items_per_notification,
+ priority, FALSE,
+ callback, callback_data);
if (uri != NULL) {
gnome_vfs_uri_unref (uri);
}
@@ -920,10 +1020,52 @@
g_return_if_fail (priority >= GNOME_VFS_PRIORITY_MIN);
g_return_if_fail (priority <= GNOME_VFS_PRIORITY_MAX);
- *handle_return = async_load_directory (uri, options,
- items_per_notification,
- priority,
- callback, callback_data);
+ _gnome_vfs_async_load_directory_uri_internal (handle_return, uri, options,
+ items_per_notification,
+ priority, FALSE,
+ callback, callback_data);
+}
+
+GnomeVFSResult
+_gnome_vfs_async_xfer_internal (GnomeVFSAsyncHandle **handle_return,
+ GList *source_uri_list,
+ GList *target_uri_list,
+ GnomeVFSXferOptions xfer_options,
+ GnomeVFSXferErrorMode error_mode,
+ GnomeVFSXferOverwriteMode overwrite_mode,
+ int priority,
+ gboolean direct_callback,
+ GnomeVFSAsyncXferProgressCallback progress_update_callback,
+ gpointer update_callback_data,
+ GnomeVFSXferProgressCallback progress_sync_callback,
+ gpointer sync_callback_data)
+{
+ GnomeVFSJob *job;
+ GnomeVFSXferOp *xfer_op;
+
+ g_return_val_if_fail (handle_return != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS);
+ g_return_val_if_fail (progress_update_callback != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS);
+ g_return_val_if_fail (priority >= GNOME_VFS_PRIORITY_MIN, GNOME_VFS_ERROR_BAD_PARAMETERS);
+ g_return_val_if_fail (priority <= GNOME_VFS_PRIORITY_MAX, GNOME_VFS_ERROR_BAD_PARAMETERS);
+
+ job = _gnome_vfs_job_new (GNOME_VFS_OP_XFER,
+ priority, direct_callback,
+ (GFunc) progress_update_callback,
+ update_callback_data);
+
+ xfer_op = &job->op->specifics.xfer;
+ xfer_op->source_uri_list = gnome_vfs_uri_list_copy (source_uri_list);
+ xfer_op->target_uri_list = gnome_vfs_uri_list_copy (target_uri_list);
+ xfer_op->xfer_options = xfer_options;
+ xfer_op->error_mode = error_mode;
+ xfer_op->overwrite_mode = overwrite_mode;
+ xfer_op->progress_sync_callback = progress_sync_callback;
+ xfer_op->sync_callback_data = sync_callback_data;
+
+ *handle_return = job->handle;
+ _gnome_vfs_job_go (job);
+
+ return GNOME_VFS_OK;
}
/**
@@ -968,33 +1110,51 @@
GnomeVFSXferProgressCallback progress_sync_callback,
gpointer sync_callback_data)
{
+ return _gnome_vfs_async_xfer_internal (handle_return, source_uri_list,
+ target_uri_list, xfer_options,
+ error_mode, overwrite_mode,
+ priority, FALSE,
+ progress_update_callback,
+ update_callback_data,
+ progress_sync_callback,
+ sync_callback_data);
+}
+
+void
+_gnome_vfs_async_file_control_internal (GnomeVFSAsyncHandle *handle,
+ const char *operation,
+ gpointer operation_data,
+ GDestroyNotify operation_data_destroy_func,
+ gboolean direct_callback,
+ GnomeVFSAsyncFileControlCallback callback,
+ gpointer callback_data)
+{
GnomeVFSJob *job;
- GnomeVFSXferOp *xfer_op;
+ GnomeVFSFileControlOp *file_control_op;
- g_return_val_if_fail (handle_return != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS);
- g_return_val_if_fail (progress_update_callback != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS);
- g_return_val_if_fail (priority >= GNOME_VFS_PRIORITY_MIN, GNOME_VFS_ERROR_BAD_PARAMETERS);
- g_return_val_if_fail (priority <= GNOME_VFS_PRIORITY_MAX, GNOME_VFS_ERROR_BAD_PARAMETERS);
+ g_return_if_fail (handle != NULL);
+ g_return_if_fail (operation != NULL);
+ g_return_if_fail (callback != NULL);
- job = _gnome_vfs_job_new (GNOME_VFS_OP_XFER,
- priority,
- (GFunc) progress_update_callback,
- update_callback_data);
+ _gnome_vfs_async_job_map_lock ();
+ job = _gnome_vfs_async_job_map_get_job (handle);
+ if (job == NULL) {
+ g_warning ("trying to call file_control on a non-existing handle");
+ _gnome_vfs_async_job_map_unlock ();
+ return;
+ }
+ _gnome_vfs_job_set (job, GNOME_VFS_OP_FILE_CONTROL,
+ direct_callback,
+ (GFunc) callback, callback_data);
- xfer_op = &job->op->specifics.xfer;
- xfer_op->source_uri_list = gnome_vfs_uri_list_copy (source_uri_list);
- xfer_op->target_uri_list = gnome_vfs_uri_list_copy (target_uri_list);
- xfer_op->xfer_options = xfer_options;
- xfer_op->error_mode = error_mode;
- xfer_op->overwrite_mode = overwrite_mode;
- xfer_op->progress_sync_callback = progress_sync_callback;
- xfer_op->sync_callback_data = sync_callback_data;
+ file_control_op = &job->op->specifics.file_control;
+ file_control_op->operation = g_strdup (operation);
+ file_control_op->operation_data = operation_data;
+ file_control_op->operation_data_destroy_func = operation_data_destroy_func;
- *handle_return = job->job_handle;
_gnome_vfs_job_go (job);
-
- return GNOME_VFS_OK;
+ _gnome_vfs_async_job_map_unlock ();
}
/**
@@ -1025,31 +1185,9 @@
GnomeVFSAsyncFileControlCallback callback,
gpointer callback_data)
{
- GnomeVFSJob *job;
- GnomeVFSFileControlOp *file_control_op;
-
- g_return_if_fail (handle != NULL);
- g_return_if_fail (operation != NULL);
- g_return_if_fail (callback != NULL);
-
- _gnome_vfs_async_job_map_lock ();
- job = _gnome_vfs_async_job_map_get_job (handle);
- if (job == NULL) {
- g_warning ("trying to call file_control on a non-existing handle");
- _gnome_vfs_async_job_map_unlock ();
- return;
- }
-
- _gnome_vfs_job_set (job, GNOME_VFS_OP_FILE_CONTROL,
- (GFunc) callback, callback_data);
-
- file_control_op = &job->op->specifics.file_control;
- file_control_op->operation = g_strdup (operation);
- file_control_op->operation_data = operation_data;
- file_control_op->operation_data_destroy_func = operation_data_destroy_func;
-
- _gnome_vfs_job_go (job);
- _gnome_vfs_async_job_map_unlock ();
+ _gnome_vfs_async_file_control_internal (handle, operation, operation_data,
+ operation_data_destroy_func,
+ FALSE, callback, callback_data);
}
#ifdef OLD_CONTEXT_DEPRECATED
Index: libgnomevfs/gnome-vfs-async-job-map.c
===================================================================
RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-async-job-map.c,v
retrieving revision 1.13
diff -u -d -r1.13 gnome-vfs-async-job-map.c
--- libgnomevfs/gnome-vfs-async-job-map.c 17 Sep 2003 09:11:04 -0000 1.13
+++ libgnomevfs/gnome-vfs-async-job-map.c 17 May 2004 00:22:42 -0000
@@ -22,6 +22,7 @@
#include <config.h>
#include "gnome-vfs-async-job-map.h"
+#include "gnome-vfs-handle-private.h"
#include "gnome-vfs-job.h"
#include <glib/ghash.h>
@@ -59,7 +60,8 @@
return NULL;
}
- return g_hash_table_lookup (async_job_map, handle);
+ return g_hash_table_lookup (async_job_map,
+ GUINT_TO_POINTER (_gnome_vfs_handle_get_async_id (handle)));
}
void
@@ -72,14 +74,16 @@
/* Assign a unique id to each job. The GnomeVFSAsyncHandle pointers each
* async op call deals with this will really be these unique IDs
*/
- job->job_handle = GUINT_TO_POINTER (++async_job_map_next_id);
+ _gnome_vfs_handle_set_async_id (job->handle, ++async_job_map_next_id);
if (async_job_map == NULL) {
/* First job, allocate a new hash table. */
async_job_map = g_hash_table_new (NULL, NULL);
}
- g_hash_table_insert (async_job_map, job->job_handle, job);
+ g_hash_table_insert (async_job_map,
+ GUINT_TO_POINTER (_gnome_vfs_handle_get_async_id (job->handle)),
+ job);
_gnome_vfs_async_job_map_unlock ();
}
@@ -91,7 +95,8 @@
g_assert (async_job_map);
- g_hash_table_remove (async_job_map, job->job_handle);
+ g_hash_table_remove (async_job_map,
+ GUINT_TO_POINTER (_gnome_vfs_handle_get_async_id (job->handle)));
_gnome_vfs_async_job_map_unlock ();
}
Index: libgnomevfs/Makefile.am
===================================================================
RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/Makefile.am,v
retrieving revision 1.122
diff -u -d -r1.122 Makefile.am
--- libgnomevfs/Makefile.am 1 Mar 2004 09:43:30 -0000 1.122
+++ libgnomevfs/Makefile.am 17 May 2004 00:22:42 -0000
@@ -25,6 +25,7 @@
libgnomevfs_headers_to_scan_for_enums = \
gnome-vfs-application-registry.h \
gnome-vfs-async-ops.h \
+ gnome-vfs-async-ops-private.h \
gnome-vfs-cancellation.h \
gnome-vfs-context.h \
gnome-vfs-directory.h \
--- /dev/null 2004-02-23 16:02:56.000000000 -0500
+++ libgnomevfs/gnome-vfs-async-ops-private.h 2004-05-16 21:49:48.501863904 -0400
@@ -0,0 +1,109 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+
+/* gnome-vfs-async-ops-private.h - Private functions for async access
+
+Copyright (C) 1999 Free Software Foundation
+
+The Gnome Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The Gnome Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the Gnome Library; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+
+Author: Colin Walters <walters redhat com> */
+
+#ifndef GNOME_VFS_ASYNC_OPS_PRIVATE_H
+#define GNOME_VFS_ASYNC_OPS_PRIVATE_H
+
+#include <libgnomevfs/gnome-vfs-async-ops.h>
+
+G_BEGIN_DECLS
+
+void _gnome_vfs_async_close_internal (GnomeVFSHandle *handle,
+ gboolean direct_callback,
+ GnomeVFSAsyncCloseCallback callback,
+ gpointer user_data);
+void _gnome_vfs_async_read_internal (GnomeVFSHandle *handle,
+ gpointer buffer,
+ guint bytes,
+ gboolean direct_callback,
+ GnomeVFSAsyncReadCallback callback,
+ gpointer callback_data);
+void _gnome_vfs_async_write_internal (GnomeVFSHandle *handle,
+ gconstpointer buffer,
+ guint bytes,
+ gboolean direct_callback,
+ GnomeVFSAsyncWriteCallback callback,
+ gpointer callback_data);
+void _gnome_vfs_async_seek_internal (GnomeVFSHandle *handle,
+ GnomeVFSSeekPosition whence,
+ GnomeVFSFileOffset offset,
+ gboolean direct_callback,
+ GnomeVFSAsyncSeekCallback callback,
+ gpointer callback_data);
+void _gnome_vfs_async_get_file_info_internal (GnomeVFSHandle **handle_return,
+ GList *uri_list,
+ GnomeVFSFileInfoOptions options,
+ int priority,
+ gboolean direct_callback,
+ GnomeVFSAsyncGetFileInfoCallback callback,
+ gpointer callback_data);
+void _gnome_vfs_async_set_file_info_internal (GnomeVFSHandle **handle_return,
+ GnomeVFSURI *uri,
+ GnomeVFSFileInfo *info,
+ GnomeVFSSetFileInfoMask mask,
+ GnomeVFSFileInfoOptions options,
+ int priority,
+ gboolean direct_callback,
+ GnomeVFSAsyncSetFileInfoCallback callback,
+ gpointer callback_data);
+void _gnome_vfs_async_load_directory_uri_internal (GnomeVFSHandle **handle_return,
+ GnomeVFSURI *uri,
+ GnomeVFSFileInfoOptions options,
+ guint items_per_notification,
+ int priority,
+ gboolean direct_callback,
+ GnomeVFSAsyncDirectoryLoadCallback callback,
+ gpointer callback_data);
+GnomeVFSResult _gnome_vfs_async_xfer_internal (GnomeVFSHandle **handle_return,
+ GList *source_uri_list,
+ GList *target_uri_list,
+ GnomeVFSXferOptions xfer_options,
+ GnomeVFSXferErrorMode error_mode,
+ GnomeVFSXferOverwriteMode overwrite_mode,
+ int priority,
+ gboolean direct_callback,
+ GnomeVFSAsyncXferProgressCallback progress_update_callback,
+ gpointer update_callback_data,
+ GnomeVFSXferProgressCallback progress_sync_callback,
+ gpointer sync_callback_data);
+void _gnome_vfs_async_find_directory_internal (GnomeVFSHandle **handle_return,
+ GList *near_uri_list,
+ GnomeVFSFindDirectoryKind kind,
+ gboolean create_if_needed,
+ gboolean find_if_needed,
+ guint permissions,
+ int priority,
+ gboolean direct_callback,
+ GnomeVFSAsyncFindDirectoryCallback callback,
+ gpointer user_data);
+void _gnome_vfs_async_file_control_internal (GnomeVFSHandle *handle,
+ const char *operation,
+ gpointer operation_data,
+ GDestroyNotify operation_data_destroy_func,
+ gboolean direct_callback,
+ GnomeVFSAsyncFileControlCallback callback,
+ gpointer callback_data);
+
+G_END_DECLS
+
+#endif /* GNOME_VFS_ASYNC_OPS_PRIVATE_H */
Attachment:
signature.asc
Description: This is a digitally signed message part