first cut at synchronous async operations



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 (&notify_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 (&current_time);
+		g_time_val_add (&current_time, G_USEC_PER_SEC);
+		g_cond_timed_wait (handle->async_cond, handle->async_mutex, &current_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



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]