diff options
author | Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com> | 2011-08-09 17:04:51 +0200 |
---|---|---|
committer | Christian Kellner <gicmo@gnome.org> | 2011-08-25 21:19:55 +0200 |
commit | 3a41dcabf49287438953bb4e3622cd493adfc395 (patch) | |
tree | b7be88d5ca6bfbf780e7a552e05ecd3cb5e79067 /daemon | |
parent | 6fb8847eded26016eedd94f55608d56ab7796365 (diff) | |
download | gvfs-3a41dcabf49287438953bb4e3622cd493adfc395.tar.gz |
afp: read directly into the given read buffer
this way we can skip an memcpy and gain some extra performance
Diffstat (limited to 'daemon')
-rw-r--r-- | daemon/gvfsafpconnection.c | 68 | ||||
-rw-r--r-- | daemon/gvfsafpconnection.h | 2 | ||||
-rw-r--r-- | daemon/gvfsbackendafp.c | 8 |
3 files changed, 57 insertions, 21 deletions
diff --git a/daemon/gvfsafpconnection.c b/daemon/gvfsafpconnection.c index e7ad468a..a222cf6c 100644 --- a/daemon/gvfsafpconnection.c +++ b/daemon/gvfsafpconnection.c @@ -387,7 +387,7 @@ struct _GVfsAfpCommand AfpCommandType type; - const char *buf; + char *buf; gsize buf_size; }; @@ -515,7 +515,7 @@ g_vfs_afp_command_get_data (GVfsAfpCommand *comm) } void -g_vfs_afp_command_set_buffer (GVfsAfpCommand *comm, const char *buf, gsize size) +g_vfs_afp_command_set_buffer (GVfsAfpCommand *comm, char *buf, gsize size) { g_return_if_fail (buf != NULL); g_return_if_fail (size > 0); @@ -568,7 +568,6 @@ struct _GVfsAfpConnectionPrivate /* read loop */ gboolean read_loop_running; - gsize bytes_read; DSIHeader read_dsi_header; char *data; }; @@ -818,6 +817,25 @@ dispatch_reply (GVfsAfpConnection *afp_connection) } static void +skip_data_cb (GObject *object, GAsyncResult *res, gpointer user_data) +{ + GInputStream *input = G_INPUT_STREAM (object); + GVfsAfpConnection *afp_connection = G_VFS_AFP_CONNECTION (user_data); + + gsize bytes_skipped; + GError *err = NULL; + + bytes_skipped = g_input_stream_skip_finish (input, res, &err); + if (bytes_skipped == -1) + { + g_warning ("FAIL!!! \"%s\"\n", err->message); + g_error_free (err); + } + + read_reply (afp_connection); +} + +static void read_data_cb (GObject *object, GAsyncResult *res, gpointer user_data) { GInputStream *input = G_INPUT_STREAM (object); @@ -841,11 +859,12 @@ static void read_dsi_header_cb (GObject *object, GAsyncResult *res, gpointer user_data) { GInputStream *input = G_INPUT_STREAM (object); - GVfsAfpConnection *afp_connection = G_VFS_AFP_CONNECTION (user_data); - GVfsAfpConnectionPrivate *priv = afp_connection->priv; + GVfsAfpConnection *afp_conn = G_VFS_AFP_CONNECTION (user_data); + GVfsAfpConnectionPrivate *priv = afp_conn->priv; gboolean result; GError *err = NULL; + DSIHeader *dsi_header; result = read_all_finish (input, res, NULL, &err); if (!result) @@ -854,20 +873,40 @@ read_dsi_header_cb (GObject *object, GAsyncResult *res, gpointer user_data) g_error_free (err); } - priv->read_dsi_header.requestID = GUINT16_FROM_BE (priv->read_dsi_header.requestID); - priv->read_dsi_header.errorCode = GUINT32_FROM_BE (priv->read_dsi_header.errorCode); - priv->read_dsi_header.totalDataLength = GUINT32_FROM_BE (priv->read_dsi_header.totalDataLength); + dsi_header = &priv->read_dsi_header; - if (priv->read_dsi_header.totalDataLength > 0) + dsi_header->requestID = GUINT16_FROM_BE (dsi_header->requestID); + dsi_header->errorCode = GUINT32_FROM_BE (dsi_header->errorCode); + dsi_header->totalDataLength = GUINT32_FROM_BE (dsi_header->totalDataLength); + + if (dsi_header->totalDataLength > 0) { - priv->data = g_malloc (priv->read_dsi_header.totalDataLength); - read_all_async (input, priv->data, priv->read_dsi_header.totalDataLength, - 0, NULL, read_data_cb, afp_connection); + RequestData *req_data; + + req_data = g_hash_table_lookup (priv->request_hash, + GUINT_TO_POINTER ((guint)dsi_header->requestID)); + if (req_data) + { + if (req_data->command->type == AFP_COMMAND_READ_EXT && req_data->command->buf) + priv->data = req_data->command->buf; + else + priv->data = g_malloc (dsi_header->totalDataLength); + + read_all_async (input, priv->data, dsi_header->totalDataLength, + 0, NULL, read_data_cb, afp_conn); + } + else + { + /* TODO: should really do a skip_all */ + g_input_stream_skip_async (input, dsi_header->totalDataLength, 0, NULL, + skip_data_cb, afp_conn); + } + return; } - dispatch_reply (afp_connection); - read_reply (afp_connection); + dispatch_reply (afp_conn); + read_reply (afp_conn); } static void @@ -879,7 +918,6 @@ read_reply (GVfsAfpConnection *afp_connection) input = g_io_stream_get_input_stream (priv->conn); - priv->bytes_read = 0; priv->data = NULL; read_all_async (input, &priv->read_dsi_header, sizeof (DSIHeader), 0, NULL, diff --git a/daemon/gvfsafpconnection.h b/daemon/gvfsafpconnection.h index 6494bc9d..97c8584c 100644 --- a/daemon/gvfsafpconnection.h +++ b/daemon/gvfsafpconnection.h @@ -335,7 +335,7 @@ void g_vfs_afp_command_pad_to_even (GVfsAfpCommand *comm); gsize g_vfs_afp_command_get_size (GVfsAfpCommand *comm); char* g_vfs_afp_command_get_data (GVfsAfpCommand *comm); -void g_vfs_afp_command_set_buffer (GVfsAfpCommand *comm, const char *buf, gsize size); +void g_vfs_afp_command_set_buffer (GVfsAfpCommand *comm, char *buf, gsize size); GType g_vfs_afp_command_get_type (void) G_GNUC_CONST; diff --git a/daemon/gvfsbackendafp.c b/daemon/gvfsbackendafp.c index ae2ad3f8..de814626 100644 --- a/daemon/gvfsbackendafp.c +++ b/daemon/gvfsbackendafp.c @@ -2047,7 +2047,6 @@ read_ext_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) GError *err = NULL; AfpResultCode res_code; gsize size; - char *data; reply = g_vfs_afp_connection_send_command_finish (afp_conn, res, &err); if (!reply) @@ -2080,10 +2079,6 @@ read_ext_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) size = g_vfs_afp_reply_get_size (reply); - /* TODO: Read directly into the data buffer */ - g_vfs_afp_reply_get_data (reply, size, (guint8 **)&data); - memcpy (job->buffer, data, size); - afp_handle->offset += size; g_vfs_job_read_set_size (job, size); @@ -2117,6 +2112,9 @@ try_read (GVfsBackend *backend, req_count = MIN (bytes_requested, G_MAXUINT32); g_vfs_afp_command_put_int64 (comm, req_count); + /* Set buffer to read into */ + g_vfs_afp_command_set_buffer (comm, buffer, bytes_requested); + g_vfs_afp_connection_send_command (afp_backend->server->conn, comm, read_ext_cb, G_VFS_JOB (job)->cancellable, job); |