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