You are viewing a plain text version of this content. The canonical link for it is here.
Posted to general@commons.apache.org by gs...@apache.org on 2003/11/02 06:27:09 UTC

svn commit: rev 70 - in commons/serf/branches/gen2: . buckets

Author: gstein
Date: Sat Nov  1 21:27:08 2003
New Revision: 70

Modified:
   commons/serf/branches/gen2/buckets/aggregate_buckets.c
   commons/serf/branches/gen2/buckets/buckets.c
   commons/serf/branches/gen2/buckets/request_buckets.c
   commons/serf/branches/gen2/buckets/simple_buckets.c
   commons/serf/branches/gen2/serf.h
   commons/serf/branches/gen2/serf_bucket_util.h
Log:
Add a couple new types of functions for reading, to assist with high-perf
zero-copy networking. (specifically: enable writev() and sendfile()).

* gen2/serf.h:
  (serf_response_acceptor_t): avoid the name 'socket' as it shadows a
    global function by that name.
  (serf_bucket_type_t.read_iovec): new function to read values into an
    iovec structure.
  (serf_bucket_type_t.read_for_sendfile): new function to read values into
    variables suitable for passing to apr_socket_sendfile().
  (serf_bucket_type_t.peek): moved to *after* the read_bucket function.
  (serf_bucket_read_iovec): new helper macro
  (serf_bucket_read_for_sendfile): new helper macro

* gen2/serf_bucket_util.h:
  (serf_default_read_iovec): default implementation for the read_iovec
    vtable function.
  (serf_default_read_for_sendfile): default implementation for the
    read_iovec vtable function.

* buckets/buckets.c:
  (serf_default_set_metadata): fix reference to bucket->allocator
  (serf_default_read_iovec): new function.
  (serf_default_read_for_sendfile): new function.

* buckets/aggregate_buckets.c:
  (serf_bucket_type_aggregate): add default functions for iovec and
    sendfile, and reorder peek/read_bucket

* buckets/request_buckets.c:
  (request_context_t): remove 'state' member
  (serf_bucket_request_create): don't initialize the 'state' member
  (serf_bucket_type_request): add default functions for iovec and
    sendfile, and reorder peek/read_bucket

* buckets/simple_buckets.c:
  (serf_bucket_type_simple): add default functions for iovec and
    sendfile, and reorder peek/read_bucket


Modified: commons/serf/branches/gen2/buckets/aggregate_buckets.c
==============================================================================
--- commons/serf/branches/gen2/buckets/aggregate_buckets.c	(original)
+++ commons/serf/branches/gen2/buckets/aggregate_buckets.c	Sat Nov  1 21:27:08 2003
@@ -189,8 +189,10 @@
     "AGGREGATE",
     serf_aggregate_read,
     serf_aggregate_readline,
-    serf_aggregate_peek,
+    serf_default_read_iovec,
+    serf_default_read_for_sendfile,
     serf_aggregate_read_bucket,
+    serf_aggregate_peek,
     serf_default_get_metadata,
     serf_default_set_metadata,
     serf_default_destroy,

Modified: commons/serf/branches/gen2/buckets/buckets.c
==============================================================================
--- commons/serf/branches/gen2/buckets/buckets.c	(original)
+++ commons/serf/branches/gen2/buckets/buckets.c	Sat Nov  1 21:27:08 2003
@@ -151,7 +151,7 @@
         }
 
         /* Create the metadata container. */
-        bucket->metadata = serf_bucket_mem_alloc(allocator,
+        bucket->metadata = serf_bucket_mem_alloc(bucket->allocator,
                                                  sizeof(*bucket->metadata));
 
         /* ### pool usage! */
@@ -205,6 +205,50 @@
     }
 
     return APR_SUCCESS;
+}
+
+SERF_DECLARE(apr_status_t) serf_default_read_iovec(
+    serf_bucket_t *bucket,
+    apr_size_t requested,
+    int vecs_size,
+    struct iovec *vecs,
+    int *vecs_used)
+{
+    const char *data;
+    apr_size_t len;
+
+    /* Read some data from the bucket. */
+    apr_status_t status = serf_bucket_read(bucket, requested, &data, &len);
+
+    /* assert that vecs_size >= 1 ? */
+
+    /* Return that data as a single iovec. */
+    vecs[0].iov_base = (void *)data; /* loses the 'const' */
+    vecs[0].iov_len = len;
+    *vecs_used = 1;
+
+    return status;
+}
+
+SERF_DECLARE(apr_status_t) serf_default_read_for_sendfile(
+    serf_bucket_t *bucket,
+    apr_size_t requested,
+    apr_hdtr_t *hdtr,
+    apr_file_t **file,
+    apr_off_t *offset,
+    apr_size_t *len)
+{
+    /* Read a bunch of stuff into the headers. */
+    apr_status_t status = serf_bucket_read_iovec(bucket, requested,
+                                                 hdtr->numheaders,
+                                                 hdtr->headers,
+                                                 &hdtr->numheaders);
+
+    /* There isn't a file, and there are no trailers. */
+    *file = NULL;
+    hdtr->numtrailers = 0;
+
+    return status;
 }
 
 SERF_DECLARE(serf_bucket_t *) serf_default_read_bucket(

Modified: commons/serf/branches/gen2/buckets/request_buckets.c
==============================================================================
--- commons/serf/branches/gen2/buckets/request_buckets.c	(original)
+++ commons/serf/branches/gen2/buckets/request_buckets.c	Sat Nov  1 21:27:08 2003
@@ -49,6 +49,7 @@
  */
 
 #include <apr_pools.h>
+#include <apr_strings.h>
 
 #include "serf.h"
 #include "serf_bucket_util.h"
@@ -58,7 +59,6 @@
     const char *method;
     const char *uri;
     serf_bucket_t *body;
-    serf_request_state_t state;
 } request_context_t;
 
 
@@ -74,7 +74,6 @@
     ctx->method = method;
     ctx->uri = uri;
     ctx->body = body;
-    ctx->state = UNREAD;
 
     return serf_bucket_create(&serf_bucket_type_request, allocator, ctx);
 }
@@ -155,8 +154,10 @@
     "REQUEST",
     serf_request_read,
     serf_request_readline,
-    serf_request_peek,
+    serf_default_read_iovec,
+    serf_default_read_for_sendfile,
     serf_default_read_bucket,
+    serf_request_peek,
     serf_default_get_metadata,
     serf_default_set_metadata,
     serf_default_destroy,

Modified: commons/serf/branches/gen2/buckets/simple_buckets.c
==============================================================================
--- commons/serf/branches/gen2/buckets/simple_buckets.c	(original)
+++ commons/serf/branches/gen2/buckets/simple_buckets.c	Sat Nov  1 21:27:08 2003
@@ -135,8 +135,10 @@
     "SIMPLE",
     serf_simple_read,
     serf_simple_readline,
-    serf_simple_peek,
+    serf_default_read_iovec,
+    serf_default_read_for_sendfile,
     serf_default_read_bucket,
+    serf_simple_peek,
     serf_default_get_metadata,
     serf_default_set_metadata,
     serf_simple_destroy,

Modified: commons/serf/branches/gen2/serf.h
==============================================================================
--- commons/serf/branches/gen2/serf.h	(original)
+++ commons/serf/branches/gen2/serf.h	Sat Nov  1 21:27:08 2003
@@ -148,7 +148,7 @@
  * All temporary allocations should be made in @a tmppool.
  */
 typedef serf_bucket_t * (*serf_response_acceptor_t)(serf_connection_t *conn,
-                                                    apr_socket_t *socket,
+                                                    apr_socket_t *skt,
                                                     void *acceptor_baton,
                                                     apr_pool_t *respool,
                                                     apr_pool_t *tmppool);
@@ -271,7 +271,7 @@
  * @{
  */
 
-/** Pass as REQUESTED to the read() bucket function to read, consume,
+/** Pass as REQUESTED to the read function of a bucket to read, consume,
  * and return all available data.
  */
 #define SERF_READ_ALL_AVAIL ((apr_size_t)-1)
@@ -301,7 +301,7 @@
      * The data will exist until one of two conditions occur:
      *
      * 1) this bucket is destroyed
-     * 2) another call to read(), peek(), or read_bucket() is performed.
+     * 2) another call to any read function or to peek()
      *
      * If an application needs the data to exist for a longer duration,
      * then it must make a copy.
@@ -319,6 +319,9 @@
      * A pointer to the data is returned in @a data, and its length is
      * specified by @a len. The data will include the newline, if present.
      *
+     * Note that there is no way to limit the amount of data returned
+     * by this function.
+     *
      * The lifetime of the data is the same as that of the @see read
      * function above.
      */
@@ -327,16 +330,53 @@
                              const char **data, apr_size_t *len);
 
     /**
-     * Peek, but don't consume, the data in @a bucket.
+     * Read a set of pointer/length pairs from the bucket.
      *
-     * The @a data and @a len parameters, and the data they point to, are
-     * handled the same as the @see read function above.
+     * The size of the @a vecs array is specified by @a vecs_size. The
+     * bucket should fill in elements of the array, and return the number
+     * used in @a vecs_used.
      *
-     * Note: if the peek does not return enough data for your particular
-     * use, then you must read/consume some first, then peek again.
+     * Each element of @a vecs should specify a pointer to a block of
+     * data and a length of that data.
+     *
+     * The total length of all data elements should not exceed the
+     * amount specified in @a requested.
+     *
+     * The lifetime of the data is the same as that of the @see read
+     * function above.
      */
-    apr_status_t (*peek)(serf_bucket_t *bucket,
-                         const char **data, apr_size_t *len);
+    apr_status_t (*read_iovec)(serf_bucket_t *bucket, apr_size_t requested,
+                               int vecs_size, struct iovec *vecs,
+                               int *vecs_used);
+
+    /**
+     * Read data from the bucket in a form suitable for apr_socket_sendfile()
+     *
+     * On input, hdtr->numheaders and hdtr->numtrailers specify the size
+     * of the hdtr->headers and hdtr->trailers arrays, respectively. The
+     * bucket should fill in the headers and trailers, up to the specified
+     * limits, and set numheaders and numtrailers to the number of iovecs
+     * filled in for each item.
+     *
+     * @a file should be filled in with a file that can be read. If a file
+     * is not available or appropriate, then NULL should be stored. The
+     * file offset for the data should be stored in @a offset, and the
+     * length of that data should be stored in @a len. If a file is not
+     * returned, then @a offset and @a len should be ignored.
+     *
+     * The file position is not required to correspond to @a offset, and
+     * the caller may manipulate it at will.
+     *
+     * The total length of all data elements, and the portion of the
+     * file should not exceed the amount specified in @a requested.
+     *
+     * The lifetime of the data is the same as that of the @see read
+     * function above.
+     */
+    apr_status_t (*read_for_sendfile)(serf_bucket_t *bucket,
+                                      apr_size_t requested, apr_hdtr_t *hdtr,
+                                      apr_file_t **file, apr_off_t *offset,
+                                      apr_size_t *len);
 
     /**
      * Look within @a bucket for a bucket of the given @a type. The bucket
@@ -354,6 +394,18 @@
                                    const serf_bucket_type_t *type);
 
     /**
+     * Peek, but don't consume, the data in @a bucket.
+     *
+     * The @a data and @a len parameters, and the data they point to, are
+     * handled the same as the @see read function above.
+     *
+     * Note: if the peek does not return enough data for your particular
+     * use, then you must read/consume some first, then peek again.
+     */
+    apr_status_t (*peek)(serf_bucket_t *bucket,
+                         const char **data, apr_size_t *len);
+
+    /**
      * Look up and return a piece of metadata from @a bucket.
      *
      * The metadata is specified by the metadata type @a md_type and the
@@ -391,8 +443,11 @@
 
 #define serf_bucket_read(b,r,d,l) ((b)->type->read(b,r,d,l))
 #define serf_bucket_readline(b,a,f,d,l) ((b)->type->readline(b,a,f,d,l))
-#define serf_bucket_peek(b,d,l) ((b)->type->peek(b,d,l))
+#define serf_bucket_read_iovec(b,r,s,v,u) ((b)->type->read_iovec(b,r,s,v,u))
+#define serf_bucket_read_for_sendfile(b,r,h,f,o,l) \
+    ((b)->type->read_for_sendfile(b,r,h,f,o,l))
 #define serf_bucket_read_bucket(b,t) ((b)->type->read_bucket(b,t))
+#define serf_bucket_peek(b,d,l) ((b)->type->peek(b,d,l))
 #define serf_bucket_get_metadata(b,t,n,v) ((b)->type->get_metadata(b,t,n,v))
 #define serf_bucket_set_metadata(b,t,n,v) ((b)->type->set_metadata(b,t,n,v))
 #define serf_bucket_destroy(b) ((b)->type->destroy(b))

Modified: commons/serf/branches/gen2/serf_bucket_util.h
==============================================================================
--- commons/serf/branches/gen2/serf_bucket_util.h	(original)
+++ commons/serf/branches/gen2/serf_bucket_util.h	Sat Nov  1 21:27:08 2003
@@ -104,6 +104,33 @@
                                                      const void **md_value);
 
 /**
+ * Default implementation of the @see read_iovec functionality.
+ *
+ * This function will use the @see read function to get a block of memory,
+ * then return it in the iovec.
+ */
+SERF_DECLARE(apr_status_t) serf_default_read_iovec(
+    serf_bucket_t *bucket,
+    apr_size_t requested,
+    int vecs_size,
+    struct iovec *vecs,
+    int *vecs_used);
+
+/**
+ * Default implementation of the @see read_for_sendfile functionality.
+ *
+ * This function will use the @see read function to get a block of memory,
+ * then return it as a header. No file will be returned.
+ */
+SERF_DECLARE(apr_status_t) serf_default_read_for_sendfile(
+    serf_bucket_t *bucket,
+    apr_size_t requested,
+    apr_hdtr_t *hdtr,
+    apr_file_t **file,
+    apr_off_t *offset,
+    apr_size_t *len);
+
+/**
  * Default implementation of the @see read_bucket functionality.
  *
  * This function will always return NULL, indicating that the @a type