httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From stodd...@apache.org
Subject cvs commit: httpd-2.0/modules/experimental mod_mem_cache.c
Date Thu, 30 Aug 2001 02:49:40 GMT
stoddard    01/08/29 19:49:40

  Modified:    modules/experimental mod_mem_cache.c
  Log:
  Three small changes...
  1. Change CACHE_TYPE_MALLOC to CACHE_TYPE_HEAP
  2. Enable cacheing content contained in multiple brigades
  3. Don't cache an entry more than once.
  
  Revision  Changes    Path
  1.5       +49 -20    httpd-2.0/modules/experimental/mod_mem_cache.c
  
  Index: mod_mem_cache.c
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/modules/experimental/mod_mem_cache.c,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- mod_mem_cache.c	2001/08/24 17:01:21	1.4
  +++ mod_mem_cache.c	2001/08/30 02:49:40	1.5
  @@ -76,7 +76,7 @@
    */
   typedef enum {
       CACHE_TYPE_FILE = 1,
  -    CACHE_TYPE_MALLOC,
  +    CACHE_TYPE_HEAP,
       CACHE_TYPE_MMAP
   } cache_type_e;
   
  @@ -141,7 +141,7 @@
       */
   
       if (obj->info.content_type)
  -        free(obj->info.content_type);
  +        free((char*) obj->info.content_type);
       if (obj->key)
           free(obj->key);
       if (obj->m)
  @@ -192,7 +192,7 @@
   
   static int create_entity(cache_handle **hp, const char *type, char *key, apr_size_t len)

   {
  -    cache_object_t *obj;
  +    cache_object_t *obj, *eobj = NULL;
       cache_handle *h;
   
       /* Create the cache handle and begin populating it.
  @@ -234,8 +234,9 @@
           free(h);
           return DECLINED;
       }
  +    memset(obj,'\0', sizeof(*obj));
   
  -    obj->key = malloc(strlen(key));
  +    obj->key = malloc(strlen(key) + 1);
       if (!obj->key) {
           /* XXX Uuugh, there has got to be a better way to manage memory.
            */
  @@ -245,7 +246,7 @@
       }
       obj->m_len = len;     /* One of these len fields can go */
       obj->info.len = len;
  -    strcpy(obj->key, key);
  +    strncpy(obj->key, key, strlen(key) + 1);
       h->cache_obj = (void *) obj;
       
       /* Mark the cache object as incomplete and put it into the cache */
  @@ -254,12 +255,31 @@
       /* XXX Need a way to insert into the cache w/o such coarse grained locking */
       if (sconf->lock) {
           apr_lock_acquire(sconf->lock);
  +    }
  +    /* Do not allow the new cache object to replace an existing cache object.
  +     * We should find eobj only when another thread is in the process of
  +     * caching the same object as this thread. If we hit this case, decline
  +     * the request.
  +     */
  +    eobj = (cache_object_t *) apr_hash_get(sconf->cacheht, key, APR_HASH_KEY_STRING);
  +    if (!eobj) {
  +        apr_hash_set(sconf->cacheht, obj->key, strlen(obj->key), obj);
       }
  -    apr_hash_set(sconf->cacheht, obj->key, strlen(obj->key), obj);
       if (sconf->lock) {
           apr_lock_release(sconf->lock);
       }
   
  +    if (eobj) {
  +        /* 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.
  +         */
  +        cleanup_cache_object(obj);
  +        free(h);
  +        *hp = NULL;
  +        return DECLINED;
  +    }
  +
       return OK;
   }
   
  @@ -394,7 +414,7 @@
       if (info->content_type) {
           obj->info.content_type = (char*) malloc(strlen(info->content_type));
           if (obj->info.content_type)
  -            strcpy(obj->info.content_type, info->content_type);
  +            strcpy((char*) obj->info.content_type, info->content_type);
       }
   
       return OK;
  @@ -406,38 +426,47 @@
       cache_object_t *obj = (cache_object_t *) h->cache_obj;
       apr_read_type_e eblock = APR_BLOCK_READ;
       apr_bucket *e;
  -
  +    char *cur;
  +    
       /* XXX mmap, malloc or file? 
        * Enable this decision to be configured....
  +     * XXX cache buckets...
        */
  -    char *m = malloc(obj->m_len);
  -    obj->m = m;
  -    if (!m) {
  -        /* Cleanup cache entry and return */
  +    if (obj->m == NULL) {
  +        obj->m = malloc(obj->m_len);
  +        if (obj->m == NULL) {
  +            /* Cleanup cache entry and return */
  +        }
  +        obj->type = CACHE_TYPE_HEAP;
  +        h->count = 0;
       }
  -    obj->type = CACHE_TYPE_MALLOC;
  +    cur = (char*) obj->m + h->count;
   
       /* Iterate accross the brigade and populate the cache storage */
  -    /* XXX doesn't handle multiple brigades */
       APR_BRIGADE_FOREACH(e, b) {
           const char *s;
           apr_size_t len;
   
  +        if (APR_BUCKET_IS_EOS(e)) {
  +            obj->complete = 1;
  +            break;
  +        }
           rv = apr_bucket_read(e, &s, &len, eblock);
           if (rv != APR_SUCCESS) {
               /* Big problem!  Cleanup cache entry and return */
           }
           /* XXX Check for overflow */
           if (len ) {
  -            memcpy(m, s, len);
  -            m+=len;
  +            memcpy(cur, s, len);
  +            cur+=len;
  +            h->count+=len;
           }
  +        /* This should not happen, but if it does, we are in BIG trouble
  +         * cause we just stomped all over the heap.
  +         */
  +        AP_DEBUG_ASSERT(h->count > obj->m_len);
       }
   
  -    /* XXX - Check for EOS before setting obj->complete
  -     * Open for business. This entry can be served from the cache 
  -     */
  -    obj->complete = 1;
       return OK;
   }
   
  
  
  

Mime
View raw message