oops, real patch



Hi,

I forgot to regenerate the latest diff before sending it, here it is.

? daemon/gnome-vfs-daemon
? libgnomevfs/gnome-vfs-async-ops-private.h
? libgnomevfs/s-enum-types-c
? libgnomevfs/s-enum-types-h
Index: libgnomevfs/Makefile.am
===================================================================
RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/Makefile.am,v
retrieving revision 1.122
diff -u -d -u -r1.122 Makefile.am
--- libgnomevfs/Makefile.am	1 Mar 2004 09:43:30 -0000	1.122
+++ libgnomevfs/Makefile.am	17 May 2004 12:41:25 -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			\
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 -u -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 12:41:25 -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>
@@ -47,7 +48,7 @@
 }
 
 GnomeVFSJob *
-_gnome_vfs_async_job_map_get_job (const GnomeVFSAsyncHandle *handle)
+_gnome_vfs_async_job_map_get_job (GnomeVFSHandle *handle)
 {
 	_gnome_vfs_async_job_map_assert_locked ();
 	
@@ -59,6 +60,8 @@
 		return NULL;
 	}
 
+	g_assert (_gnome_vfs_handle_get_asynchronous (handle));
+
 	return g_hash_table_lookup (async_job_map, handle);
 }
 
@@ -69,14 +72,16 @@
 
 	g_assert (!async_job_map_shutting_down);
 
-	/* Assign a unique id to each job. The GnomeVFSAsyncHandle pointers each
-	 * async op call deals with this will really be these unique IDs
+	/* Assign a unique id to each job. The GnomeVFSHandle pointers each
+	 * async op call deals with will hold these unique IDs
 	 */
-	job->job_handle = GUINT_TO_POINTER (++async_job_map_next_id);
+	job->job_handle = _gnome_vfs_handle_new_asynchronous (++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);
+		async_job_map = g_hash_table_new_full (NULL, NULL,
+						       (GDestroyNotify) _gnome_vfs_handle_destroy,
+						       NULL);
 	}
 
 	g_hash_table_insert (async_job_map, job->job_handle, job);
@@ -109,19 +114,22 @@
 }
 
 gboolean 
-_gnome_vfs_async_job_completed (GnomeVFSAsyncHandle *handle)
+_gnome_vfs_async_job_completed (GnomeVFSHandle *handle)
 {
 	GnomeVFSJob *job;
 
 	_gnome_vfs_async_job_map_lock ();
 
-	JOB_DEBUG (("%d", GPOINTER_TO_UINT (handle)));
-	/* Job done, remove it's id from the map */
-
 	g_assert (async_job_map != NULL);
 
 	job = _gnome_vfs_async_job_map_get_job (handle);
 	if (job != NULL) {
+		guint job_id;
+
+		job_id = _gnome_vfs_handle_get_async_id (job->job_handle);			
+		JOB_DEBUG (("%d", job_id));
+
+		/* Job done, remove it's id from the map */
 		g_hash_table_remove (async_job_map, handle);
 	}
 	
@@ -258,7 +266,7 @@
 	
 	notify_result = (GnomeVFSNotifyResult *) value;
 	
-	if (notify_result->job_handle == (GnomeVFSAsyncHandle *)user_data) {
+	if (notify_result->job_handle == (GnomeVFSHandle *) user_data) {
 		JOB_DEBUG (("cancelling callback %u - job %u cancelled",
 			    GPOINTER_TO_UINT (key),
 			    GPOINTER_TO_UINT (user_data)));
@@ -267,7 +275,7 @@
 }
 
 void
-_gnome_vfs_async_job_cancel_job_and_callbacks (GnomeVFSAsyncHandle *job_handle, GnomeVFSJob *job)
+_gnome_vfs_async_job_cancel_job_and_callbacks (GnomeVFSHandle *handle, GnomeVFSJob *job)
 {
 	g_static_mutex_lock (&async_job_callback_map_lock);
 	
@@ -276,11 +284,10 @@
 	}
 	
 	if (async_job_callback_map == NULL) {
-		JOB_DEBUG (("job %u, no callbacks scheduled yet",
-			    GPOINTER_TO_UINT (job_handle)));
+		JOB_DEBUG (("job %u, no callbacks scheduled yet", job_id));
 	} else {
 		g_hash_table_foreach (async_job_callback_map,
-				      callback_map_cancel_one, job_handle);
+				      callback_map_cancel_one, handle);
 	}
 
 	g_static_mutex_unlock (&async_job_callback_map_lock);
Index: libgnomevfs/gnome-vfs-async-job-map.h
===================================================================
RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-async-job-map.h,v
retrieving revision 1.6
diff -u -d -u -r1.6 gnome-vfs-async-job-map.h
--- libgnomevfs/gnome-vfs-async-job-map.h	19 Dec 2002 17:57:19 -0000	1.6
+++ libgnomevfs/gnome-vfs-async-job-map.h	17 May 2004 12:41:25 -0000
@@ -1,7 +1,7 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
 /* gnome-vfs-async-job-map.h:
 
-	The async job map, maps GnomeVFSAsyncHandles to GnomeVFSJobs. Many
+	The async job map, maps job ids (guint) to GnomeVFSJobs. Many
    async operations, keep the same 'GnomeVFSJob' over the course of several
    operations. 
 
@@ -32,14 +32,14 @@
 /* async job map calls */
 void		 _gnome_vfs_async_job_map_init		  	(void);
 void	     	 _gnome_vfs_async_job_map_shutdown	  	(void);
-gboolean     	 _gnome_vfs_async_job_completed 	  	  	(GnomeVFSAsyncHandle		*handle);
+gboolean     	 _gnome_vfs_async_job_completed  	  	(GnomeVFSHandle                 *handle);
 void 		 _gnome_vfs_async_job_map_add_job  	  	(GnomeVFSJob			*job);
 void 		 _gnome_vfs_async_job_map_remove_job  	  	(GnomeVFSJob			*job);
-GnomeVFSJob	*_gnome_vfs_async_job_map_get_job	  	(const GnomeVFSAsyncHandle	*handle);
+GnomeVFSJob	*_gnome_vfs_async_job_map_get_job	  	(GnomeVFSHandle                 *handle);
 
 void		 _gnome_vfs_async_job_map_assert_locked	  	(void);
 void		 _gnome_vfs_async_job_map_lock	  	  	(void);
-void		 _gnome_vfs_async_job_map_unlock	  	  	(void);
+void		 _gnome_vfs_async_job_map_unlock	  	(void);
 
 /* async job callback map calls */
 void		 _gnome_vfs_async_job_callback_valid		(guint				 callback_id,
@@ -48,7 +48,7 @@
 gboolean	 _gnome_vfs_async_job_add_callback		(GnomeVFSJob			*job,
 							  	 GnomeVFSNotifyResult		*notify_result);
 void		 _gnome_vfs_async_job_remove_callback		(guint			 	 callback_id);
-void		 _gnome_vfs_async_job_cancel_job_and_callbacks	(GnomeVFSAsyncHandle		*job_handle,
+void		 _gnome_vfs_async_job_cancel_job_and_callbacks	(GnomeVFSHandle                 *handle,
 								 GnomeVFSJob 			*job);
 
 #endif
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 -u -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 12:41:26 -0000
@@ -23,7 +23,8 @@
 
 #include <config.h>
 
-#include "gnome-vfs-async-ops.h"
+#include "gnome-vfs-async-ops-private.h"
+#include "gnome-vfs-handle-private.h"
 #include "gnome-vfs-async-job-map.h"
 #include "gnome-vfs-job.h"
 #include "gnome-vfs-job-queue.h"
@@ -40,7 +41,7 @@
  * Its possible to still receive another call or two on the callback.
  **/
 void
-gnome_vfs_async_cancel (GnomeVFSAsyncHandle *handle)
+gnome_vfs_async_cancel (GnomeVFSHandle *handle)
 {
 	GnomeVFSJob *job;
 	
@@ -48,7 +49,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 {
@@ -62,7 +62,7 @@
 	_gnome_vfs_async_job_map_unlock ();
 }
 
-static GnomeVFSAsyncHandle *
+static GnomeVFSHandle *
 async_open (GnomeVFSURI *uri,
 	    GnomeVFSOpenMode open_mode,
 	    int priority,
@@ -71,9 +71,10 @@
 {
 	GnomeVFSJob *job;
 	GnomeVFSOpenOp *open_op;
-	GnomeVFSAsyncHandle *result;
+	GnomeVFSHandle *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;
 	
@@ -103,7 +104,7 @@
  * 
  **/
 void
-gnome_vfs_async_open_uri (GnomeVFSAsyncHandle **handle_return,
+gnome_vfs_async_open_uri (GnomeVFSHandle **handle_return,
 			  GnomeVFSURI *uri,
 			  GnomeVFSOpenMode open_mode,
 			  int priority,
@@ -137,7 +138,7 @@
  * 
  **/
 void
-gnome_vfs_async_open (GnomeVFSAsyncHandle **handle_return,
+gnome_vfs_async_open (GnomeVFSHandle **handle_return,
 		      const gchar *text_uri,
 		      GnomeVFSOpenMode open_mode,
 		      int priority,
@@ -160,7 +161,7 @@
 	}
 }
 
-static GnomeVFSAsyncHandle *
+static GnomeVFSHandle *
 async_open_as_channel (GnomeVFSURI *uri,
 		       GnomeVFSOpenMode open_mode,
 		       guint advised_block_size,
@@ -170,9 +171,10 @@
 {
 	GnomeVFSJob *job;
 	GnomeVFSOpenAsChannelOp *open_as_channel_op;
-	GnomeVFSAsyncHandle *result;
+	GnomeVFSHandle *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);
@@ -203,7 +205,7 @@
  * at @uri in @open_mode.
  **/
 void
-gnome_vfs_async_open_uri_as_channel (GnomeVFSAsyncHandle **handle_return,
+gnome_vfs_async_open_uri_as_channel (GnomeVFSHandle **handle_return,
 				     GnomeVFSURI *uri,
 				     GnomeVFSOpenMode open_mode,
 				     guint advised_block_size,
@@ -239,7 +241,7 @@
  * at @text_uri in @open_mode.
  **/
 void
-gnome_vfs_async_open_as_channel (GnomeVFSAsyncHandle **handle_return,
+gnome_vfs_async_open_as_channel (GnomeVFSHandle **handle_return,
 				 const gchar *text_uri,
 				 GnomeVFSOpenMode open_mode,
 				 guint advised_block_size,
@@ -263,7 +265,7 @@
 	}
 }
 
-static GnomeVFSAsyncHandle *
+static GnomeVFSHandle *
 async_create (GnomeVFSURI *uri,
 	      GnomeVFSOpenMode open_mode,
 	      gboolean exclusive,
@@ -274,9 +276,10 @@
 {
 	GnomeVFSJob *job;
 	GnomeVFSCreateOp *create_op;
-	GnomeVFSAsyncHandle *result;
+	GnomeVFSHandle *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);
@@ -312,7 +315,7 @@
  * @callback will be called with the result code and @callback_data.
  **/
 void
-gnome_vfs_async_create_uri (GnomeVFSAsyncHandle **handle_return,
+gnome_vfs_async_create_uri (GnomeVFSHandle **handle_return,
 			    GnomeVFSURI *uri,
 			    GnomeVFSOpenMode open_mode,
 			    gboolean exclusive,
@@ -353,7 +356,7 @@
  * @callback will be called with the result code and @callback_data.
  **/
 void
-gnome_vfs_async_create (GnomeVFSAsyncHandle **handle_return,
+gnome_vfs_async_create (GnomeVFSHandle **handle_return,
 			const gchar *text_uri,
 			GnomeVFSOpenMode open_mode,
 			gboolean exclusive,
@@ -397,7 +400,7 @@
  * at @text_uri in @open_mode.
  **/
 void
-gnome_vfs_async_create_as_channel (GnomeVFSAsyncHandle **handle_return,
+gnome_vfs_async_create_as_channel (GnomeVFSHandle **handle_return,
 				   const gchar *text_uri,
 				   GnomeVFSOpenMode open_mode,
 				   gboolean exclusive,
@@ -408,7 +411,7 @@
 {
 	GnomeVFSJob *job;
 	GnomeVFSCreateAsChannelOp *create_as_channel_op;
-	GnomeVFSAsyncHandle *result;
+	GnomeVFSHandle *result;
 
 	g_return_if_fail (handle_return != NULL);
 	g_return_if_fail (text_uri != NULL);
@@ -416,8 +419,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);
@@ -429,20 +432,12 @@
 	_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 (GnomeVFSHandle *handle,
+				 gboolean direct_callback,
+				 GnomeVFSAsyncCloseCallback callback,
+				 gpointer callback_data)
 {
 	GnomeVFSJob *job;
 
@@ -461,7 +456,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,23 +475,30 @@
 }
 
 /**
- * gnome_vfs_async_read:
- * @handle: handle for the file to be read
- * @buffer: allocated block of memory to read into
- * @bytes: number of bytes to read
+ * 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
- * 
- * Read @bytes bytes from the file pointed to be @handle into @buffer.
- * When the operation is complete, @callback will be called with the
- * result of the operation and @callback_data.
+ *
+ * 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_read (GnomeVFSAsyncHandle *handle,
-		      gpointer buffer,
-		      guint bytes,
-		      GnomeVFSAsyncReadCallback callback,
-		      gpointer callback_data)
+gnome_vfs_async_close (GnomeVFSHandle *handle,
+		       GnomeVFSAsyncCloseCallback callback,
+		       gpointer callback_data)
+{
+	_gnome_vfs_async_close_internal (handle, FALSE, callback, callback_data);
+}
+
+void
+_gnome_vfs_async_read_internal (GnomeVFSHandle *handle,
+				gpointer buffer,
+				guint bytes,
+				gboolean direct_callback,
+				GnomeVFSAsyncReadCallback callback,
+				gpointer callback_data)
 {
 	GnomeVFSJob *job;
 	GnomeVFSReadOp *read_op;
@@ -512,7 +515,7 @@
 		return;
 	}
 
-	_gnome_vfs_job_set (job, GNOME_VFS_OP_READ,
+	_gnome_vfs_job_set (job, GNOME_VFS_OP_READ, direct_callback,
 			   (GFunc) callback, callback_data);
 
 	read_op = &job->op->specifics.read;
@@ -524,23 +527,34 @@
 }
 
 /**
- * gnome_vfs_async_write:
- * @handle: handle for the file to be written
- * @buffer: block of memory containing data to be written
- * @bytes: number of bytes to write
+ * gnome_vfs_async_read:
+ * @handle: handle for the file to be read
+ * @buffer: allocated block of memory to read into
+ * @bytes: number of bytes to read
  * @callback: function to be called when the operation is complete
  * @callback_data: data to pass @callback
  * 
- * Write @bytes bytes from @buffer into the file pointed to be @handle.
+ * Read @bytes bytes from the file pointed to be @handle into @buffer.
  * When the operation is complete, @callback will be called with the
  * result of the operation and @callback_data.
  **/
 void
-gnome_vfs_async_write (GnomeVFSAsyncHandle *handle,
-		       gconstpointer buffer,
-		       guint bytes,
-		       GnomeVFSAsyncWriteCallback callback,
-		       gpointer callback_data)
+gnome_vfs_async_read (GnomeVFSHandle *handle,
+		      gpointer buffer,
+		      guint bytes,
+		      GnomeVFSAsyncReadCallback callback,
+		      gpointer callback_data)
+{
+	_gnome_vfs_async_read_internal (handle, buffer, bytes, FALSE, callback, callback_data);
+}
+
+void
+_gnome_vfs_async_write_internal (GnomeVFSHandle *handle,
+				 gconstpointer buffer,
+				 guint bytes,
+				 gboolean direct_callback,
+				 GnomeVFSAsyncWriteCallback callback,
+				 gpointer callback_data)
 {
 	GnomeVFSJob *job;
 	GnomeVFSWriteOp *write_op;
@@ -557,7 +571,7 @@
 		return;
 	}
 
-	_gnome_vfs_job_set (job, GNOME_VFS_OP_WRITE,
+	_gnome_vfs_job_set (job, GNOME_VFS_OP_WRITE, direct_callback,
 			   (GFunc) callback, callback_data);
 
 	write_op = &job->op->specifics.write;
@@ -569,24 +583,34 @@
 }
 
 /**
- * gnome_vfs_async_seek:
- * @handle: Handle for which the current position must be changed
- * @whence: Integer value representing the starting position
- * @offset: Number of bytes to skip from the position specified by @whence
- * (a positive value means to move forward; a negative one to move backwards)
+ * gnome_vfs_async_write:
+ * @handle: handle for the file to be written
+ * @buffer: block of memory containing data to be written
+ * @bytes: number of bytes to write
  * @callback: function to be called when the operation is complete
  * @callback_data: data to pass @callback
  * 
- * Set the current position for reading/writing through @handle.
+ * Write @bytes bytes from @buffer into the file pointed to be @handle.
  * When the operation is complete, @callback will be called with the
  * result of the operation and @callback_data.
  **/
 void
-gnome_vfs_async_seek (GnomeVFSAsyncHandle *handle,
-		      GnomeVFSSeekPosition whence,
-		      GnomeVFSFileOffset offset,
-		      GnomeVFSAsyncSeekCallback callback,
-		      gpointer callback_data)
+gnome_vfs_async_write (GnomeVFSHandle *handle,
+		       gconstpointer buffer,
+		       guint bytes,
+		       GnomeVFSAsyncWriteCallback callback,
+		       gpointer callback_data)
+{
+	_gnome_vfs_async_write_internal (handle, buffer, bytes, FALSE, callback, callback_data);
+}
+
+void
+_gnome_vfs_async_seek_internal (GnomeVFSHandle *handle,
+				GnomeVFSSeekPosition whence,
+				GnomeVFSFileOffset offset,
+				gboolean direct_callback,
+				GnomeVFSAsyncSeekCallback callback,
+				gpointer callback_data)
 {
 	GnomeVFSJob *job;
 	GnomeVFSSeekOp *seek_op;
@@ -602,7 +626,7 @@
 		return;
 	}
 
-	_gnome_vfs_job_set (job, GNOME_VFS_OP_SEEK,
+	_gnome_vfs_job_set (job, GNOME_VFS_OP_SEEK, direct_callback,
 			   (GFunc) callback, callback_data);
 
 	seek_op = &job->op->specifics.seek;
@@ -614,6 +638,29 @@
 }
 
 /**
+ * gnome_vfs_async_seek:
+ * @handle: Handle for which the current position must be changed
+ * @whence: Integer value representing the starting position
+ * @offset: Number of bytes to skip from the position specified by @whence
+ * (a positive value means to move forward; a negative one to move backwards)
+ * @callback: function to be called when the operation is complete
+ * @callback_data: data to pass @callback
+ * 
+ * Set the current position for reading/writing through @handle.
+ * When the operation is complete, @callback will be called with the
+ * result of the operation and @callback_data.
+ **/
+void
+gnome_vfs_async_seek (GnomeVFSHandle *handle,
+		      GnomeVFSSeekPosition whence,
+		      GnomeVFSFileOffset offset,
+		      GnomeVFSAsyncSeekCallback callback,
+		      gpointer callback_data)
+{
+	_gnome_vfs_async_seek_internal (handle, whence, offset, FALSE, callback, callback_data);
+}
+
+/**
  * gnome_vfs_async_create_symbolic_link:
  * @handle_return: when the function returns will point to a handle for
  * the async operation.
@@ -630,7 +677,7 @@
  * @callback_data.
  **/
 void
-gnome_vfs_async_create_symbolic_link (GnomeVFSAsyncHandle **handle_return,
+gnome_vfs_async_create_symbolic_link (GnomeVFSHandle **handle_return,
 				      GnomeVFSURI *uri,
 				      const gchar *uri_reference,
 				      int priority,
@@ -646,7 +693,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_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);
@@ -656,6 +704,35 @@
 	_gnome_vfs_job_go (job);
 }
 
+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)
+{
+	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->job_handle;
+	_gnome_vfs_job_go (job);
+}
+
 /**
  * gnome_vfs_async_get_file_info:
  * @handle_return: when the function returns will point to a handle for
@@ -673,27 +750,49 @@
  * information progressively to @callback.
  **/
 void
-gnome_vfs_async_get_file_info (GnomeVFSAsyncHandle **handle_return,
+gnome_vfs_async_get_file_info (GnomeVFSHandle **handle_return,
 			       GList *uri_list,
 			       GnomeVFSFileInfoOptions options,
 			       int priority,
 			       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 (GnomeVFSHandle **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;
 	_gnome_vfs_job_go (job);
@@ -718,7 +817,7 @@
  * owner, and modification time.
  **/
 void
-gnome_vfs_async_set_file_info (GnomeVFSAsyncHandle **handle_return,
+gnome_vfs_async_set_file_info (GnomeVFSHandle **handle_return,
 			       GnomeVFSURI *uri,
 			       GnomeVFSFileInfo *info,
 			       GnomeVFSSetFileInfoMask mask,
@@ -727,25 +826,41 @@
 			       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 (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)
+{
 	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;
 	_gnome_vfs_job_go (job);
@@ -783,7 +898,7 @@
  * of the operation and @user_data.
  **/
 void
-gnome_vfs_async_find_directory (GnomeVFSAsyncHandle **handle_return,
+gnome_vfs_async_find_directory (GnomeVFSHandle **handle_return,
 				GList *near_uri_list,
 				GnomeVFSFindDirectoryKind kind,
 				gboolean create_if_needed,
@@ -793,41 +908,28 @@
 				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 (GnomeVFSHandle **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;
+	GnomeVFSHandle *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);
@@ -837,11 +939,9 @@
 	result = job->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
@@ -861,7 +961,7 @@
  * files will be processed between each call to @callback.
  **/
 void
-gnome_vfs_async_load_directory (GnomeVFSAsyncHandle **handle_return,
+gnome_vfs_async_load_directory (GnomeVFSHandle **handle_return,
 				const gchar *text_uri,
 				GnomeVFSFileInfoOptions options,
 				guint items_per_notification,
@@ -878,10 +978,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);
 	}
@@ -906,7 +1007,7 @@
  * files will be processed between each call to @callback.
  **/
 void
-gnome_vfs_async_load_directory_uri (GnomeVFSAsyncHandle **handle_return,
+gnome_vfs_async_load_directory_uri (GnomeVFSHandle **handle_return,
 				    GnomeVFSURI *uri,
 				    GnomeVFSFileInfoOptions options,
 				    guint items_per_notification,
@@ -920,10 +1021,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 (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)
+{
+	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->job_handle;
+	_gnome_vfs_job_go (job);
+
+	return GNOME_VFS_OK;
 }
 
 /**
@@ -956,7 +1099,7 @@
  * or %GNOME_VFS_ERROR_BAD_PARAMETERS if something was wrong in the passed in arguments.
  **/
 GnomeVFSResult
-gnome_vfs_async_xfer (GnomeVFSAsyncHandle **handle_return,
+gnome_vfs_async_xfer (GnomeVFSHandle **handle_return,
 		      GList *source_uri_list,
 		      GList *target_uri_list,
 		      GnomeVFSXferOptions xfer_options,
@@ -968,33 +1111,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 (GnomeVFSHandle *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 ();
 }
 
 /**
@@ -1018,44 +1179,22 @@
  * Since: 2.2
  **/
 void
-gnome_vfs_async_file_control (GnomeVFSAsyncHandle *handle,
+gnome_vfs_async_file_control (GnomeVFSHandle *handle,
 			      const char *operation,
 			      gpointer operation_data,
 			      GDestroyNotify operation_data_destroy_func,
 			      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
 
 guint
-gnome_vfs_async_add_status_callback (GnomeVFSAsyncHandle *handle,
+gnome_vfs_async_add_status_callback (GnomeVFSHandle *handle,
 				     GnomeVFSStatusCallback callback,
 				     gpointer user_data)
 {
@@ -1083,7 +1222,7 @@
 }
 
 void
-gnome_vfs_async_remove_status_callback (GnomeVFSAsyncHandle *handle,
+gnome_vfs_async_remove_status_callback (GnomeVFSHandle *handle,
 					guint callback_id)
 {
 	GnomeVFSJob *job;
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 -u -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 12:41:26 -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-cancellable-ops.c
===================================================================
RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-cancellable-ops.c,v
retrieving revision 1.31
diff -u -d -u -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 12:41:26 -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 (GnomeVFSHandle *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 (GnomeVFSHandle *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 (GnomeVFSHandle *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-handle-private.h
===================================================================
RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-handle-private.h,v
retrieving revision 1.3
diff -u -d -u -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 12:41:26 -0000
@@ -29,7 +29,13 @@
 GnomeVFSHandle * _gnome_vfs_handle_new                (GnomeVFSURI             *uri,
 						      GnomeVFSMethodHandle    *method_handle,
 						      GnomeVFSOpenMode         open_mode);
+GnomeVFSHandle * _gnome_vfs_handle_new_asynchronous   (guint job_id);
 void             _gnome_vfs_handle_destroy            (GnomeVFSHandle          *handle);
+gboolean         _gnome_vfs_handle_get_asynchronous   (GnomeVFSHandle          *handle);
+guint            _gnome_vfs_handle_get_async_id       (const GnomeVFSHandle    *handle);
+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-handle.c
===================================================================
RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-handle.c,v
retrieving revision 1.23
diff -u -d -u -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 12:41:26 -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;
 }
@@ -91,9 +99,70 @@
 {
 	g_return_if_fail (handle != NULL);
 
-	gnome_vfs_uri_unref (handle->uri);
+	if (!handle->is_async)
+		gnome_vfs_uri_unref (handle->uri);
+	else {
+		g_mutex_free (handle->async_mutex);
+		g_cond_free (handle->async_cond);
+	}
 
 	g_free (handle);
+}
+
+
+/* Asynchronous stuff */
+
+GnomeVFSHandle *
+_gnome_vfs_handle_new_asynchronous (guint job_id)
+{
+	GnomeVFSHandle *new = g_new0 (GnomeVFSHandle, 1);
+
+	new->is_async = TRUE;
+	new->async_mutex = g_mutex_new ();
+	new->async_cond = g_cond_new ();
+	new->async_id = job_id;
+
+	return 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;
+}
+
+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)
+{
+	g_mutex_lock (handle->async_mutex);
+	handle->async_done = TRUE;
+	g_cond_signal (handle->async_cond);
+	g_mutex_unlock (handle->async_mutex);
 }
 
 
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 -u -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 12:41:26 -0000
@@ -23,6 +23,7 @@
 
 #include <config.h>
 #include "gnome-vfs-job-slave.h"
+#include "gnome-vfs-handle-private.h"
 
 #include "gnome-vfs-async-job-map.h"
 #include "gnome-vfs-thread-pool.h"
@@ -38,18 +39,17 @@
 thread_routine (void *data)
 {
 	guint id;
+	GnomeVFSHandle *handle;
 	GnomeVFSJob *job;
-	GnomeVFSAsyncHandle *job_handle;
 	gboolean complete;
 
-	job_handle = (GnomeVFSAsyncHandle *) data;
-
-	id = GPOINTER_TO_UINT (job_handle);
+	handle = data;
+	id = _gnome_vfs_handle_get_async_id (handle);
 	/* job map must always be locked before the job_lock
 	 * if both locks are needed */
 	_gnome_vfs_async_job_map_lock ();
 	
-	job = _gnome_vfs_async_job_map_get_job (job_handle);
+	job = _gnome_vfs_async_job_map_get_job (handle);
 	
 	if (job == NULL) {
 		JOB_DEBUG (("job already dead, bail %u", id));
@@ -70,7 +70,7 @@
 	if (complete) {
 		_gnome_vfs_async_job_map_lock ();
 		JOB_DEBUG (("job %u done, removing from map and destroying", id));
-		_gnome_vfs_async_job_completed (job_handle);
+		_gnome_vfs_async_job_completed (handle);
 		_gnome_vfs_job_destroy (job);
 		_gnome_vfs_async_job_map_unlock ();
 	}
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 -u -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 12:41:27 -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'",
+			    notify_result->job_id,
+			    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
@@ -308,7 +320,7 @@
 }
 
 static void
-empty_close_callback (GnomeVFSAsyncHandle *handle,
+empty_close_callback (GnomeVFSHandle *handle,
 		      GnomeVFSResult result,
 		      gpointer callback_data)
 {
@@ -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++;
 
@@ -1525,7 +1540,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 +1591,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;
@@ -1627,7 +1642,7 @@
 {
 	guint id;
 
-	id = GPOINTER_TO_UINT (job->job_handle);
+	id = _gnome_vfs_handle_get_async_id (job->job_handle);
 
 	JOB_DEBUG (("exec job %u", id));
 
@@ -1779,7 +1794,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.h
===================================================================
RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-job.h,v
retrieving revision 1.52
diff -u -d -u -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 12:41:27 -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;
 
@@ -361,7 +366,9 @@
 } GnomeVFSSpecificNotifyResult;
 
 typedef struct {
-	GnomeVFSAsyncHandle *job_handle;
+	/* A "fake" GnomeVFSHandle which maps to a job id.
+	 */
+	GnomeVFSHandle *job_handle;
 
 	guint callback_id;
 
@@ -403,21 +410,23 @@
 	 * ready for notification to take place.
 	 */
 	GnomeVFSOp *op;
-	
-	/* Unique identifier of this job (a uint, really) */
-	GnomeVFSAsyncHandle *job_handle;
 
+	/* ID of active job */
+	GnomeVFSHandle *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-ops.c
===================================================================
RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-ops.c,v
retrieving revision 1.37
diff -u -d -u -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 12:41:28 -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 */
 }
 
 /**
--- /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]