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/10/30 13:05:22 UTC

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

Author: gstein
Date: Thu Oct 30 04:05:22 2003
New Revision: 61

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/serf.h
   commons/serf/branches/gen2/serf_bucket_types.h
   commons/serf/branches/gen2/serf_bucket_util.h
Log:
Various updates and fixes.

* gen2/serf.h:
  (...): include apr_network_io.h and apr_time.h for proper compilation
  (serf_bucket_t.read_bucket): constify the bucket type
  (serf_bucket_read): fix the parameter list -- add requested amount
  (serf_bucket_readline): new macro for serf_bucket_t.readline
  (serf_bucket_allocator_create): moved in file
  (serf_bucket_allocator_destroy): new declaration

* gen2/serf_bucket_types.h:
  (...): include apr_mmap.h for compilation
  (serf_bucket_aggregate_create): fix typo in the prototype.

* gen2/serf_bucket_util.h:
  (serf_bucket_create, serf_default_read_bucket): constify the type
  (serf_bucket_mem_alloc, serf_bucket_mem_free): new declarations

* gen2/buckets/buckets.c:
  (serf_bucket_create, serf_default_read_bucket): constify the type

* gen2/buckets/aggregate_buckets.c:
  (serf_bucket_aggregate_create): store the new context into the local
    variable. pass the _address_ of the type to serf_bucket_create().
  (serf_bucket_aggregate_become): implement
  (serf_bucket_aggregate_prepend): sizeof should use the variable name
  (serf_bucket_aggregate_append): sizeof should use the variable name
  (serf_aggregate_read): fix variable name (request -> requested)
  (serf_aggregate_read_bucket): if the first bucket is of the right type,
    then return it and remove it. other minor tweaks for compilation.
  (serf_bucket_type_aggreagate): fill in the default functions for the
    metadata entries.

* gen2/buckets/request_buckets.c:
  (serf_request_state_t): removed. we serialize everything in one fell
    swoop now.
  (serf_bucket_request_create): assign new memory properly, and pass a
    pointer to the type to serf_bucket_create().
  (serialize_data): new function to turn "self" into an aggregate bucket
    hold the request.
  (serf_request_read, serf_request_readline, serf_request_peek): serialize
    the data, then ask the aggregate bucket  to response properly.


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	Thu Oct 30 04:05:22 2003
@@ -48,11 +48,10 @@
  *
  */
 
-#include <apr_pools.h>
-
 #include "serf.h"
 #include "serf_bucket_util.h"
 
+
 /* Should be an APR_RING? */
 typedef struct bucket_list {
     serf_bucket_t *bucket;
@@ -63,25 +62,34 @@
     bucket_list *list;
 } serf_aggregate_context_t;
 
+
 SERF_DECLARE(serf_bucket_t *) serf_bucket_aggregate_create(
     serf_bucket_alloc_t *allocator)
 {
     serf_aggregate_context_t *agg_context;
 
-    serf_bucket_mem_alloc(allocator, sizeof(*agg_context));
-
-    /* Theoretically, we *could* store this in the metadata of our bucket,
-     * but that'd be ridiculously slow.
-     */
+    agg_context = serf_bucket_mem_alloc(allocator, sizeof(*agg_context));
     agg_context->list = NULL;
 
-    return serf_bucket_create(serf_bucket_type_aggregate, allocator,
+    return serf_bucket_create(&serf_bucket_type_aggregate, allocator,
                               agg_context);
 }
 
 SERF_DECLARE(void) serf_bucket_aggregate_become(serf_bucket_t *bucket)
 {
-    /* Create a new bucket and swap their internal pointers? */
+    serf_aggregate_context_t *agg_context;
+
+    agg_context = serf_bucket_mem_alloc(bucket->allocator,
+                                        sizeof(*agg_context));
+    agg_context->list = NULL;
+
+    bucket->type = &serf_bucket_type_aggregate;
+    bucket->data = agg_context;
+
+    /* ### leave the metadata? */
+    /* bucket->metadata = NULL; */
+
+    /* The allocator remains the same. */
 }
 
 
@@ -94,7 +102,7 @@
 
     agg_context = (serf_aggregate_context_t*)aggregate_bucket->data;
     new_bucket = serf_bucket_mem_alloc(aggregate_bucket->allocator,
-                                       sizeof(*bucket_list));
+                                       sizeof(*new_bucket));
 
     new_bucket->bucket = prepend_bucket;
     new_bucket->next = agg_context->list;
@@ -110,7 +118,7 @@
 
     agg_context = (serf_aggregate_context_t*)aggregate_bucket->data;
     new_bucket = serf_bucket_mem_alloc(aggregate_bucket->allocator,
-                                       sizeof(*bucket_list));
+                                       sizeof(*new_bucket));
 
     /* If we use APR_RING, this is trivial.  So, wait. 
     new_bucket->bucket = prepend_bucket;
@@ -126,7 +134,7 @@
     apr_status_t status;
     serf_aggregate_context_t *agg_context;
 
-    agg_context = (serf_aggregate_context_t*)aggregate_bucket->data;
+    agg_context = (serf_aggregate_context_t*)bucket->data;
     if (!agg_context->list) {
         *len = 0;
         return APR_SUCCESS;
@@ -138,7 +146,7 @@
     if (!status && *len == 0) {
         agg_context->list = agg_context->list->next;
         /* Avoid recursive call here.  Too lazy now.  */
-        return serf_aggregate_read(bucket, request, data, len);
+        return serf_aggregate_read(bucket, requested, data, len);
     }
 
     return status;
@@ -160,28 +168,36 @@
     return APR_ENOTIMPL;
 }
 
-static serf_bucket_t * serf_aggregate_read_bucket(serf_bucket_t *bucket,
-                                                  serf_bucket_type_t *type)
+static serf_bucket_t * serf_aggregate_read_bucket(
+    serf_bucket_t *bucket,
+    const serf_bucket_type_t *type)
 {
-    apr_status_t status;
     serf_aggregate_context_t *agg_context;
+    serf_bucket_t *found_bucket;
 
-    agg_context = (serf_aggregate_context_t*)aggregate_bucket->data;
+    agg_context = (serf_aggregate_context_t*)bucket->data;
     if (!agg_context->list) {
         return NULL;
     }
 
+    if (agg_context->list->bucket->type == type) {
+        /* Got the bucket. Consume it from our list. */
+        found_bucket = agg_context->list->bucket;
+        agg_context->list = agg_context->list->next;
+        return found_bucket;
+    }
+
     /* Call read_bucket on first one in our list. */
     return serf_bucket_read_bucket(agg_context->list->bucket, type);
 }
 
-SERF_DECLARE_DATA serf_bucket_type_t serf_bucket_type_aggregate {
+SERF_DECLARE_DATA const serf_bucket_type_t serf_bucket_type_aggregate = {
     "AGGREGATE",
     serf_aggregate_read,
     serf_aggregate_readline,
     serf_aggregate_peek,
     serf_aggregate_read_bucket,
-    NULL, /* set_metadata */
-    NULL, /* get_metadata */
+    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	Thu Oct 30 04:05:22 2003
@@ -1,7 +1,7 @@
 /* ====================================================================
  * The Apache Software License, Version 1.1
  *
- * Copyright (c) 2002 The Apache Software Foundation.  All rights
+ * Copyright (c) 2003 The Apache Software Foundation.  All rights
  * reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -63,7 +63,7 @@
 };
 
 SERF_DECLARE(serf_bucket_t *) serf_bucket_create(
-    serf_bucket_type_t *type,
+    const serf_bucket_type_t *type,
     serf_bucket_alloc_t *allocator,
     void *data)
 {
@@ -131,7 +131,7 @@
 
 SERF_DECLARE(serf_bucket_t *) serf_default_read_bucket(
     serf_bucket_t *bucket,
-    serf_bucket_type_t *type)
+    const serf_bucket_type_t *type)
 {
     return NULL;
 }

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	Thu Oct 30 04:05:22 2003
@@ -53,13 +53,6 @@
 #include "serf.h"
 #include "serf_bucket_util.h"
 
-typedef enum serf_request_state_t {
-    UNREAD,
-    READING_STATUS,
-    READING_HEADERS,
-    READING_BODY,
-    EXHAUSTED
-} serf_request_state_t;
 
 typedef struct serf_request_context_t {
     const char *method;
@@ -68,6 +61,7 @@
     serf_request_state_t state;
 } serf_request_context_t;
 
+
 SERF_DECLARE(serf_bucket_t *) serf_bucket_request_create(
     const char *method,
     const char *uri,
@@ -76,94 +70,95 @@
 {
     serf_request_context_t *req_context;
 
-    serf_bucket_mem_alloc(allocator, sizeof(*req_context));
-
-    /* Theoretically, we *could* store this in the metadata of our bucket,
-     * but that'd be ridiculously slow.
-     */
+    req_context = serf_bucket_mem_alloc(allocator, sizeof(*req_context));
     req_context->method = method;
     req_context->uri = uri;
     req_context->body = body;
     req_context->state = UNREAD;
 
-    return serf_bucket_create(serf_bucket_type_request, allocator, data);
+    return serf_bucket_create(&serf_bucket_type_request, allocator,
+                              req_context);
 }
 
-static apr_status_t serf_request_read(serf_bucket_t *bucket,
-                                      apr_size_t requested,
-                                      const char **data, apr_size_t *len)
+static void serialize_data(serf_bucket_t *bucket)
 {
     serf_request_context_t *req_context;
     serf_bucket_t *new_bucket;
     const char *new_data;
 
     req_context = (serf_request_context_t*)bucket->data;
-    new_bucket = NULL;
 
-    /* We'll store whatever we generate into a new bucket and update our
-     * state accordingly.
+    /* Serialize the request-line and headers into one mother string,
+     * and wrap a bucket around it.
+     */
+    /* ### ARGH.  Allocator's pool needs to be public? */
+    new_data = apr_pstrcat(bucket->allocator->pool,
+                           req_context->method, " ",
+                           req_context->uri, " HTTP/1.1\r\n",
+                           "User-Agent: serf\r\n",
+                           "\r\n",
+                           NULL);
+
+    /* heap, pool, whatever. */
+    new_bucket = serf_bucket_pool_create(bucket->allocator, new_data);
+
+    /* Build up the new bucket structure.
+     *
+     * Note that self needs to become an aggregate bucket so that a
+     * pointer to self still represents the "right" data.
      */
-    switch (req_context->state) {
-    case UNREAD:
-        /* Store method line. */
-        /* ARGH.  Allocator needs to be public? */
-        new_data = apr_pstrcat(bucket->allocator->pool,
-                               req_context->method, " ",
-                               req_context->uri, " HTTP/1.1", NULL);
-        /* heap, pool, whatever. */
-        new_bucket = serf_bucket_pool_create(bucket->allocator, new_data);
-        req_context->state = READ_STATUS;
-        break;
-    case READ_STATUS:
-        /* Store method line. */
-        req_context->state = READ_HEADERS;
-        break;
-    case READ_HEADERS:
-        /* Return all headers. */
-        req_context->state = READ_BODY;
-        break;
-    case READ_BODY:
-        /* Just read from the body at this point! */
-        req_context->state = READ_EXHAUSTED;
-        break;
-    case EXHAUSTED:
-        /* Hmm.  How did we get here? */
-        break;
-    }
-
-    if (!new_bucket) {
-        *len = 0;
-        return APR_SUCCESS;
-    }
-
-    /* Okay, so we created a bucket.  Pass the 'hard' stuff to that bucket. */
-    /* This better have the semantics we want in that bucket is pushed down. */
     serf_bucket_aggregate_become(bucket);
-    serf_bucket_aggregate_prepend(bucket, new_bucket);
-    return serf_bucket_read(bucket, data, len);
+
+    /* Insert the two buckets. */
+    serf_bucket_aggregate_append(bucket, new_bucket);
+    serf_bucket_aggregate_append(bucket, req_context->body);
+
+    /* Our private context is no longer needed, and is not referred to
+     * any existing bucket. Toss it.
+     */
+    serf_bucket_mem_free(bucket->allocator, req_context);
+}
+
+static apr_status_t serf_request_read(serf_bucket_t *bucket,
+                                      apr_size_t requested,
+                                      const char **data, apr_size_t *len)
+{
+    /* Seralize our private data into a new aggregate bucket. */
+    serialize_data(bucket);
+
+    /* Delegate to the "new" aggregate bucket to do the read. */
+    return serf_bucket_read(bucket, requested, data, len);
 }
 
 static apr_status_t serf_request_readline(serf_bucket_t *bucket,
                                           int acceptable, int *found,
                                           const char **data, apr_size_t *len)
 {
-    return APR_ENOTIMPL;
+    /* Seralize our private data into a new aggregate bucket. */
+    serialize_data(bucket);
+
+    /* Delegate to the "new" aggregate bucket to do the readline. */
+    return serf_bucket_readline(bucket, acceptable, found, data, len);
 }
 
 static apr_status_t serf_request_peek(serf_bucket_t *bucket,
                                       const char **data,
                                       apr_size_t *len)
 {
-    return APR_ENOTIMPL;
+    /* Seralize our private data into a new aggregate bucket. */
+    serialize_data(bucket);
+
+    /* Delegate to the "new" aggregate bucket to do the peek. */
+    return serf_bucket_peek(bucket, data, len);
 }
 
-SERF_DECLARE_DATA serf_bucket_type_t serf_bucket_type_request {
+SERF_DECLARE_DATA const serf_bucket_type_t serf_bucket_type_request = {
     "REQUEST",
     serf_request_read,
     serf_request_readline,
     serf_request_peek,
     serf_default_read_bucket,
-    serf_default_set_metadata,
     serf_default_get_metadata,
+    serf_default_set_metadata,
     serf_default_destroy,
 };

Modified: commons/serf/branches/gen2/serf.h
==============================================================================
--- commons/serf/branches/gen2/serf.h	(original)
+++ commons/serf/branches/gen2/serf.h	Thu Oct 30 04:05:22 2003
@@ -60,6 +60,8 @@
 #include <apr_errno.h>
 #include <apr_allocator.h>
 #include <apr_pools.h>
+#include <apr_network_io.h>
+#include <apr_time.h>
 
 #include "serf_declare.h"
 
@@ -94,14 +96,6 @@
  */
 SERF_DECLARE(serf_context_t *) serf_context_create(apr_pool_t *pool);
 
-/**
- * Create a new allocator for buckets from an APR allocator.
- *
- * All buckets are associated with a serf bucket allocator.
- */
-SERF_DECLARE(serf_bucket_alloc_t *) serf_bucket_allocator_create(
-    apr_allocator_t *allocator, apr_pool_t *pool);
-
 /** @see serf_context_run should not block at all. */
 #define SERF_DURATION_NOBLOCK 0
 /** @see serf_context_run should run for (nearly) "forever". */
@@ -357,7 +351,7 @@
      * If a bucket of the given type is not found, then NULL is returned.
      */
     serf_bucket_t * (*read_bucket)(serf_bucket_t *bucket,
-                                   serf_bucket_type_t *type);
+                                   const serf_bucket_type_t *type);
 
     /**
      * Look up and return a piece of metadata from @a bucket.
@@ -395,7 +389,8 @@
     */
 };
 
-#define serf_bucket_read(b,d,l) ((b)->type->read(b,d,l))
+#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->read(b,a,f,d,l))
 #define serf_bucket_peek(b,d,l) ((b)->type->peek(b,d,l))
 #define serf_bucket_read_bucket(b,t) ((b)->type->read_bucket(b,t))
 #define serf_bucket_get_metadata(b,t,n,v) ((b)->type->get_metadata(b,t,n,v))
@@ -424,6 +419,23 @@
  */
 #define SERF_BUCKET_CHECK(b, btype) ((b)->type == &serf_bucket_type_ ## btype)
 
+
+/**
+ * Create a new allocator for buckets from an APR allocator.
+ *
+ * All buckets are associated with a serf bucket allocator.
+ */
+SERF_DECLARE(serf_bucket_alloc_t *) serf_bucket_allocator_create(
+    apr_allocator_t *allocator, apr_pool_t *pool);
+
+/**
+ * Destroy a bucket allocator.
+ *
+ * Buckets that have not been destroyed (and returned to the allocator)
+ * will be unaffected.
+ */
+SERF_DECLARE(void) serf_bucket_allocator_destroy(
+    serf_bucket_alloc_t *allocator);
 
 
 /** @} */

Modified: commons/serf/branches/gen2/serf_bucket_types.h
==============================================================================
--- commons/serf/branches/gen2/serf_bucket_types.h	(original)
+++ commons/serf/branches/gen2/serf_bucket_types.h	Thu Oct 30 04:05:22 2003
@@ -51,6 +51,7 @@
 #ifndef SERF_BUCKET_TYPES_H
 #define SERF_BUCKET_TYPES_H
 
+#include <apr_mmap.h>
 
 /* this header and serf.h refer to each other, so take a little extra care */
 #ifndef SERF_H
@@ -112,7 +113,7 @@
 SERF_DECLARE_DATA extern const serf_bucket_type_t serf_bucket_type_aggregate;
 #define SERF_BUCKET_IS_AGGREGATE(b) SERF_BUCKET_CHECK((b), aggregate)
 
-SERF_DECALRE(serf_bucket_t *) serf_bucket_aggregate_create(
+SERF_DECLARE(serf_bucket_t *) serf_bucket_aggregate_create(
     serf_bucket_alloc_t *allocator);
 
 SERF_DECLARE(void) serf_bucket_aggregate_become(serf_bucket_t *bucket);
@@ -171,7 +172,7 @@
 /* ==================================================================== */
 
 
-/* Note: this is always defined, but if APR doesn't have mmaps, then
+/* Note: apr_mmap_t is always defined, but if APR doesn't have mmaps, then
    the caller can never create an apr_mmap_t to pass to this function. */
 
 SERF_DECLARE_DATA extern const serf_bucket_type_t serf_bucket_type_mmap;

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	Thu Oct 30 04:05:22 2003
@@ -76,7 +76,7 @@
  * The metadata for the bucket will be empty.
  */
 SERF_DECLARE(serf_bucket_t *) serf_bucket_create(
-    serf_bucket_type_t *type,
+    const serf_bucket_type_t *type,
     serf_bucket_alloc_t *allocator,
     void *data);
 
@@ -111,7 +111,7 @@
  */
 SERF_DECLARE(serf_bucket_t *) serf_default_read_bucket(
     serf_bucket_t *bucket,
-    serf_bucket_type_t *type);
+    const serf_bucket_type_t *type);
 
 /**
  * Default implementation of the @see destroy functionality.
@@ -119,6 +119,16 @@
  * This function will return the @a bucket to its allcoator.
  */
 SERF_DECLARE(void) serf_default_destroy(serf_bucket_t *bucket);
+
+
+
+SERF_DECLARE(void *) serf_bucket_mem_alloc(
+    serf_bucket_alloc_t *allocator,
+    apr_size_t size);
+
+SERF_DECLARE(void) serf_bucket_mem_free(
+    serf_bucket_alloc_t *allocator,
+    void *block);
 
 
 #ifdef __cplusplus