diff options
Diffstat (limited to 'modules/cache/mod_mem_cache.c')
-rw-r--r-- | modules/cache/mod_mem_cache.c | 159 |
1 files changed, 26 insertions, 133 deletions
diff --git a/modules/cache/mod_mem_cache.c b/modules/cache/mod_mem_cache.c index b9c6915d..ea9c45d3 100644 --- a/modules/cache/mod_mem_cache.c +++ b/modules/cache/mod_mem_cache.c @@ -58,17 +58,11 @@ typedef enum { CACHE_TYPE_MMAP } cache_type_e; -typedef struct { - char* hdr; - char* val; -} cache_header_tbl_t; - typedef struct mem_cache_object { + apr_pool_t *pool; cache_type_e type; - apr_ssize_t num_header_out; - apr_ssize_t num_req_hdrs; - cache_header_tbl_t *header_out; - cache_header_tbl_t *req_hdrs; /* for Vary negotiation */ + apr_table_t *header_out; + apr_table_t *req_hdrs; /* for Vary negotiation */ apr_size_t m_len; void *m; apr_os_file_t fd; @@ -210,22 +204,9 @@ static void cleanup_cache_object(cache_object_t *obj) { mem_cache_object_t *mobj = obj->vobj; - /* TODO: - * We desperately need a more efficient way of allocating objects. We're - * making way too many malloc calls to create a fully populated - * cache object... - */ - - /* Cleanup the cache_object_t */ - if (obj->key) { - free((void*)obj->key); - } - - free(obj); - /* Cleanup the mem_cache_object_t */ if (mobj) { - if (mobj->type == CACHE_TYPE_HEAP && mobj->m) { + if (mobj->m) { free(mobj->m); } if (mobj->type == CACHE_TYPE_FILE && mobj->fd) { @@ -235,18 +216,9 @@ static void cleanup_cache_object(cache_object_t *obj) close(mobj->fd); #endif } - if (mobj->header_out) { - if (mobj->header_out[0].hdr) - free(mobj->header_out[0].hdr); - free(mobj->header_out); - } - if (mobj->req_hdrs) { - if (mobj->req_hdrs[0].hdr) - free(mobj->req_hdrs[0].hdr); - free(mobj->req_hdrs); - } - free(mobj); } + + apr_pool_destroy(mobj->pool); } static apr_status_t decrement_refcount(void *arg) { @@ -334,9 +306,10 @@ static void *create_cache_config(apr_pool_t *p, server_rec *s) static int create_entity(cache_handle_t *h, cache_type_e type_e, request_rec *r, const char *key, apr_off_t len) { + apr_status_t rv; + apr_pool_t *pool; cache_object_t *obj, *tmp_obj; mem_cache_object_t *mobj; - apr_size_t key_len; if (len == -1) { /* Caching a streaming response. Assume the response is @@ -370,25 +343,21 @@ static int create_entity(cache_handle_t *h, cache_type_e type_e, } } - /* Allocate and initialize cache_object_t */ - obj = calloc(1, sizeof(*obj)); - if (!obj) { - return DECLINED; - } - key_len = strlen(key) + 1; - obj->key = malloc(key_len); - if (!obj->key) { - cleanup_cache_object(obj); + rv = apr_pool_create(&pool, NULL); + + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_WARNING, rv, r->server, + "mem_cache: Failed to create memory pool."); return DECLINED; } - memcpy((void*)obj->key, key, key_len); + + /* Allocate and initialize cache_object_t */ + obj = apr_pcalloc(pool, sizeof(*obj)); + obj->key = apr_pstrdup(pool, key); /* Allocate and init mem_cache_object_t */ - mobj = calloc(1, sizeof(*mobj)); - if (!mobj) { - cleanup_cache_object(obj); - return DECLINED; - } + mobj = apr_pcalloc(pool, sizeof(*mobj)); + mobj->pool = pool; /* Finish initing the cache object */ apr_atomic_set32(&obj->refcount, 1); @@ -539,64 +508,7 @@ static int remove_entity(cache_handle_t *h) return OK; } -static apr_status_t serialize_table(cache_header_tbl_t **obj, - apr_ssize_t *nelts, - apr_table_t *table) -{ - const apr_array_header_t *elts_arr = apr_table_elts(table); - apr_table_entry_t *elts = (apr_table_entry_t *) elts_arr->elts; - apr_ssize_t i; - apr_size_t len = 0; - apr_size_t idx = 0; - char *buf; - - *nelts = elts_arr->nelts; - if (*nelts == 0 ) { - *obj=NULL; - return APR_SUCCESS; - } - *obj = malloc(sizeof(cache_header_tbl_t) * elts_arr->nelts); - if (NULL == *obj) { - return APR_ENOMEM; - } - for (i = 0; i < elts_arr->nelts; ++i) { - len += strlen(elts[i].key); - len += strlen(elts[i].val); - len += 2; /* Extra space for NULL string terminator for key and val */ - } - - /* Transfer the headers into a contiguous memory block */ - buf = malloc(len); - if (!buf) { - *obj = NULL; - return APR_ENOMEM; - } - - for (i = 0; i < *nelts; ++i) { - (*obj)[i].hdr = &buf[idx]; - len = strlen(elts[i].key) + 1; /* Include NULL terminator */ - memcpy(&buf[idx], elts[i].key, len); - idx+=len; - - (*obj)[i].val = &buf[idx]; - len = strlen(elts[i].val) + 1; - memcpy(&buf[idx], elts[i].val, len); - idx+=len; - } - return APR_SUCCESS; -} -static int unserialize_table( cache_header_tbl_t *ctbl, - int num_headers, - apr_table_t *t ) -{ - int i; - - for (i = 0; i < num_headers; ++i) { - apr_table_addn(t, ctbl[i].hdr, ctbl[i].val); - } - return APR_SUCCESS; -} /* Define request processing hook handlers */ /* remove_url() * Notes: @@ -629,17 +541,12 @@ static int remove_url(cache_handle_t *h, apr_pool_t *p) static apr_status_t recall_headers(cache_handle_t *h, request_rec *r) { - int rc; mem_cache_object_t *mobj = (mem_cache_object_t*) h->cache_obj->vobj; - h->req_hdrs = apr_table_make(r->pool, mobj->num_req_hdrs); - h->resp_hdrs = apr_table_make(r->pool, mobj->num_header_out); + h->req_hdrs = apr_table_copy(r->pool, mobj->req_hdrs); + h->resp_hdrs = apr_table_copy(r->pool, mobj->header_out); - rc = unserialize_table(mobj->req_hdrs, mobj->num_req_hdrs, h->req_hdrs); - rc = unserialize_table(mobj->header_out, mobj->num_header_out, - h->resp_hdrs); - - return rc; + return OK; } static apr_status_t recall_body(cache_handle_t *h, apr_pool_t *p, apr_bucket_brigade *bb) @@ -669,7 +576,6 @@ static apr_status_t store_headers(cache_handle_t *h, request_rec *r, cache_info { cache_object_t *obj = h->cache_obj; mem_cache_object_t *mobj = (mem_cache_object_t*) obj->vobj; - int rc; apr_table_t *headers_out; /* @@ -679,12 +585,7 @@ static apr_status_t store_headers(cache_handle_t *h, request_rec *r, cache_info * - The original response headers (for returning with a cached response) * - The body of the message */ - rc = serialize_table(&mobj->req_hdrs, - &mobj->num_req_hdrs, - r->headers_in); - if (rc != APR_SUCCESS) { - return rc; - } + mobj->req_hdrs = apr_table_copy(mobj->pool, r->headers_in); /* Precompute how much storage we need to hold the headers */ headers_out = ap_cache_cacheable_hdrs_out(r->pool, r->headers_out, @@ -698,12 +599,7 @@ static apr_status_t store_headers(cache_handle_t *h, request_rec *r, cache_info } headers_out = apr_table_overlay(r->pool, headers_out, r->err_headers_out); - - rc = serialize_table(&mobj->header_out, &mobj->num_header_out, - headers_out); - if (rc != APR_SUCCESS) { - return rc; - } + mobj->header_out = apr_table_copy(mobj->pool, headers_out); /* Init the info struct */ obj->info.status = info->status; @@ -812,13 +708,10 @@ static apr_status_t store_body(cache_handle_t *h, request_rec *r, apr_bucket_bri /* Caching a streamed response. Reallocate a buffer of the * correct size and copy the streamed response into that * buffer */ - char *buf = malloc(obj->count); - if (!buf) { + mobj->m = realloc(mobj->m, obj->count); + if (!mobj->m) { return APR_ENOMEM; } - memcpy(buf, mobj->m, obj->count); - free(mobj->m); - mobj->m = buf; /* Now comes the crufty part... there is no way to tell the * cache that the size of the object has changed. We need |