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