mod_mem_cache.c revision d7d551e53cdfb3288eb651447d7209599c40d17e
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000-2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
*
* Portions of this software are based upon public domain software
* originally written at the National Center for Supercomputing Applications,
* University of Illinois, Urbana-Champaign.
*/
#define CORE_PRIVATE
#include "mod_cache.h"
#include "ap_mpm.h"
#include "apr_thread_mutex.h"
#if !APR_HAS_THREADS
#endif
/*
* XXX
* This cache uses apr_hash functions which leak storage when something is removed
* from the cache. This can be fixed in the apr_hash functions by making them use
*/
/*
* XXX Introduce a type field that identifies whether the cache obj
* references malloc'ed or mmap storage or a file descriptor
*/
typedef enum {
CACHE_TYPE_FILE = 1,
} cache_type_e;
typedef struct {
char* hdr;
char* val;
typedef struct mem_cache_object {
void *m;
typedef struct {
int space;
static mem_cache_conf *sconf;
#define CACHEFILE_LEN 20
/* Forward declarations */
static int remove_entity(cache_handle_t *h);
{
/* Cleanup the cache_object_t */
}
/* Cleanup the mem_cache_object_t */
if (!mobj) {
return;
}
if (mobj->m) {
}
/* XXX should freeing of the info be done here or in cache_storage ?
if (obj->info.content_type ) {
free((char*)obj->info.content_type );
obj->info.content_type =NULL;
}
if (obj->info.filename ) {
free( (char*)obj->info.filename );
obj->info.filename= NULL;
}
*/
/* XXX Cleanup the headers */
if (mobj->num_header_out) {
}
}
{
}
/* If the object is marked for cleanup and the refcount
* has dropped to zero, cleanup the object
*/
}
}
return APR_SUCCESS;
}
{
if (!co) {
return APR_SUCCESS;
}
/* Iterate over the frag hash table and clean up each entry */
}
if (obj) {
}
else {
}
}
}
}
return APR_SUCCESS;
}
{
int threaded_mpm;
if (threaded_mpm) {
}
return sconf;
}
const char *type,
const char *key,
{
return DECLINED;
}
/* XXX Check len to see if it is withing acceptable bounds
* max cache check should be configurable variable.
*/
return DECLINED;
}
/* XXX Check total cache size and number of entries. Are they within the
* configured limits? If not, kick off garbage collection thread.
*/
/* Allocate and initialize cache_object_t */
if (!obj) {
return DECLINED;
}
return DECLINED;
}
/* Allocate and init mem_cache_object_t */
if (!mobj) {
/* XXX: Cleanup */
}
* cache_object_t
*/
/* Place the cache_object_t into the hash table
* XXX Need a way to insert into the cache w/o such coarse grained locking
* XXX Need to enable caching multiple cache objects (representing different
* views of the same content) under a single search key
*/
}
key,
if (!tmp_obj) {
}
}
if (tmp_obj) {
/* This thread collided with another thread loading the same object
* into the cache at the same time. Defer to the other thread which
* is further along.
*/
return DECLINED;
}
/* Populate the cache handle */
h->read_headers = &read_headers;
h->write_body = &write_body;
h->write_headers = &write_headers;
h->remove_entity = &remove_entity;
return OK;
}
{
/* Look up entity keyed to 'url' */
return DECLINED;
}
}
if (obj) {
}
}
return DECLINED;
}
/* Initialize the cache_handle */
h->read_headers = &read_headers;
h->write_body = &write_body;
h->write_headers = &write_headers;
h->remove_entity = &remove_entity;
return OK;
}
static int remove_entity(cache_handle_t *h)
{
}
if (obj) {
}
else {
}
}
}
return OK;
}
{
apr_ssize_t i;
apr_size_t len = 0;
apr_size_t idx = 0;
char *buf;
if (*nelts ==0 ) {
return OK;
}
/* cleanup_cache_obj(h->cache_obj); */
return DECLINED;
}
}
/* Transfer the headers into a contiguous memory block */
if (!buf) {
/* cleanup_cache_obj(h->cache_obj); */
return DECLINED;
}
for (i = 0; i < *nelts; ++i) {
}
return OK;
}
int num_headers,
apr_table_t *t )
{
int i;
for (i = 0; i < num_headers; ++i) {
}
return OK;
}
/* Define request processing hook handlers */
{
return DECLINED;
}
/* WIBNIF
* apr_hash_set(..,..,..,NULL) returned pointer to the object just removed.
* That way, we could free the object w/o doing another call to an
* apr_hash function.
*/
/* First, find the object in the cache */
}
if (obj) {
}
else {
}
}
}
if (!obj) {
return DECLINED;
}
return OK;
}
{
int rc;
r->headers_out);
r->subprocess_env);
r->notes);
return rc;
}
{
apr_bucket *b;
b = apr_bucket_eos_create();
return OK;
}
{
int rc;
/* Precompute how much storage we need to hold the headers */
r->headers_out);
return rc;
}
r->subprocess_env );
return rc;
}
return rc;
}
/* Init the info struct */
}
}
}
if (info->content_type) {
/* cleanup the object? */
return DECLINED;
}
}
return DECLINED;
}
}
return OK;
}
{
apr_bucket *e;
char *cur;
/* XXX mmap, malloc or file?
* Enable this decision to be configured....
* XXX cache buckets...
*/
/* Cleanup cache entry and return */
}
}
/* Iterate accross the brigade and populate the cache storage */
APR_BRIGADE_FOREACH(e, b) {
const char *s;
if (APR_BUCKET_IS_EOS(e)) {
break;
}
if (rv != APR_SUCCESS) {
/* Big problem! Cleanup cache entry and return */
}
/* XXX Check for overflow */
if (len ) {
}
/* This should not happen, but if it does, we are in BIG trouble
* cause we just stomped all over the heap.
*/
}
return OK;
}
static const char
{
int val;
return "CacheSize value must be an integer (kBytes)";
}
return NULL;
}
static const char
{
int val;
return "CacheSize value must be an integer (bytes)";
}
return NULL;
}
static const command_rec cache_cmds[] =
{
/* XXX
* What config directives does this module need?
* Should this module manage expire policy for its entries?
* Certainly cache limits like max number of entries,
* max entry size, and max size of the cache should
* be managed by this module.
*/
"The maximum space used by the cache in Kb"),
"The maximum size (in bytes) that a entry can take"),
{NULL}
};
static void register_hooks(apr_pool_t *p)
{
/* cache initializer */
/* cache_hook_cache_init(cache_init, NULL, NULL, AP_HOOK_FIRST); */
}
{
NULL, /* create per-directory config structure */
NULL, /* merge per-directory config structures */
create_cache_config, /* create per-server config structure */
NULL, /* merge per-server config structures */
cache_cmds, /* command apr_table_t */
};