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 (¤t_time); + g_time_val_add (¤t_time, G_USEC_PER_SEC); + g_cond_timed_wait (handle->async_cond, handle->async_mutex, ¤t_time); + if (gnome_vfs_context_check_cancellation (context)) { + g_mutex_unlock (handle->async_mutex); + return FALSE; + } + } + return TRUE; +} + +void +_gnome_vfs_handle_signal_async (GnomeVFSHandle *handle) +{ + 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 (¬ify_result, 0, sizeof (notify_result)); - notify_result.job_handle = job->job_handle; + notify_result.job_handle = job->handle; notify_result.type = GNOME_VFS_OP_MODULE_CALLBACK; Index: libgnomevfs/gnome-vfs-job.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