[gvfs] afp: read directly into the given read buffer



commit 3a41dcabf49287438953bb4e3622cd493adfc395
Author: Carl-Anton Ingmarsson <ca ingmarsson gmail com>
Date:   Tue Aug 9 17:04:51 2011 +0200

    afp: read directly into the given read buffer
    
    this way we can skip an memcpy and gain some extra performance

 daemon/gvfsafpconnection.c |   68 ++++++++++++++++++++++++++++++++++---------
 daemon/gvfsafpconnection.h |    2 +-
 daemon/gvfsbackendafp.c    |    8 ++---
 3 files changed, 57 insertions(+), 21 deletions(-)
---
diff --git a/daemon/gvfsafpconnection.c b/daemon/gvfsafpconnection.c
index e7ad468..a222cf6 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 6494bc9..97c8584 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 ae2ad3f..de81462 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);



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