dirkx       99/04/08 13:27:46

  Modified:    src/modules/proxy proxy_cache.c
  Log:
  Modified cache garbage control to first check if it
  actually should run, based on the time of last run,
  and to try to get a lock; prior to actually forking
  and doing the real cleanup. This effectively avoids
  a fork after each and every request; and limites
  the spawning to just once every few hours.
  
  Revision  Changes    Path
  1.57      +77 -46    apache-1.3/src/modules/proxy/proxy_cache.c
  
  Index: proxy_cache.c
  ===================================================================
  RCS file: /x3/home/cvs/apache-1.3/src/modules/proxy/proxy_cache.c,v
  retrieving revision 1.56
  retrieving revision 1.57
  diff -u -r1.56 -r1.57
  --- proxy_cache.c     1999/03/23 14:48:09     1.56
  +++ proxy_cache.c     1999/04/08 20:27:44     1.57
  @@ -102,7 +102,7 @@
   #define ROUNDUP2BLOCKS(_bytes) (((_bytes)+block_size-1) & ~(block_size-1))
   static long block_size = 512;        /* this must be a power of 2 */
   static long61_t curbytes, cachesize;
  -static time_t every, garbage_now, garbage_expire;
  +static time_t garbage_now, garbage_expire;
   static char *filename;
   static mutex *garbage_mutex = NULL;
   
  @@ -119,6 +119,7 @@
   static int sub_garbage_coll(request_rec *r, array_header *files,
                            const char *cachedir, const char *cachesubdir);
   static void help_proxy_garbage_coll(request_rec *r);
  +static int should_proxy_garbage_coll(request_rec *r);
   #if !defined(WIN32) && !defined(MPE) && !defined(OS2)
   static void detached_proxy_garbage_coll(request_rec *r);
   #endif
  @@ -138,10 +139,11 @@
       (void) ap_release_mutex(garbage_mutex);
   
       ap_block_alarms();               /* avoid SIGALRM on big cache cleanup */
  +    if (should_proxy_garbage_coll(r))
   #if !defined(WIN32) && !defined(MPE) && !defined(OS2)
  -    detached_proxy_garbage_coll(r);
  +        detached_proxy_garbage_coll(r);
   #else
  -    help_proxy_garbage_coll(r);
  +        help_proxy_garbage_coll(r);
   #endif
       ap_unblock_alarms();
   
  @@ -205,6 +207,10 @@
       int status;
       pid_t pgrp;
   
  +#if 0
  +    ap_log_error(APLOG_MARK, APLOG_DEBUG, r->server,
  +                      "proxy: Guess what; we fork() again...");
  +#endif
       switch (pid = fork()) {
        case -1:
            ap_log_error(APLOG_MARK, APLOG_ERR, r->server,
  @@ -264,27 +270,25 @@
   }
   #endif /* ndef WIN32 */
   
  -static void help_proxy_garbage_coll(request_rec *r)
  +#define DOT_TIME "/.time"    /* marker */
  +
  +static int should_proxy_garbage_coll(request_rec *r)
   {
  -    const char *cachedir;
       void *sconf = r->server->module_config;
       proxy_server_conf *pconf =
       (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
       const struct cache_conf *conf = &pconf->cache;
  -    array_header *files;
  -    struct stat buf;
  -    struct gc_ent *fent;
  -    int i, timefd;
  -    static time_t lastcheck = BAD_DATE;              /* static (per-process) 
data!!! */
   
  -    cachedir = conf->root;
  -    /* configured size is given in kB. Make it bytes, convert to long61_t: */
  -    cachesize.lower = cachesize.upper = 0;
  -    add_long61(&cachesize, conf->space << 10);
  -    every = conf->gcinterval;
  +    const char *cachedir = conf->root;
  +    char filename[ strlen(cachedir) + strlen( DOT_TIME ) +1];
  +    struct stat buf;
  +    int timefd;
  +    time_t every = conf->gcinterval;
  +    static time_t lastcheck = BAD_DATE;         /* static (per-process) 
data!!! */
   
       if (cachedir == NULL || every == -1)
  -     return;
  +        return 0;
  +
       garbage_now = time(NULL);
       /* Usually, the modification time of <cachedir>/.time can only increase.
        * Thus, even with several child processes having their own copy of
  @@ -292,41 +296,68 @@
        * for GC yet.
        */
       if (garbage_now != -1 && lastcheck != BAD_DATE && garbage_now < 
lastcheck + every)
  -     return;
  +        return 0;
   
  -    ap_block_alarms();               /* avoid SIGALRM on big cache cleanup */
  +    strcpy(filename,cachedir);
  +    strcat(filename,DOT_TIME);
   
  -    filename = ap_palloc(r->pool, strlen(cachedir) + HASH_LEN + 2);
  -    strcpy(filename, cachedir);
  -    strcat(filename, "/.time");
  -    if (stat(filename, &buf) == -1) {        /* does not exist */
  -     if (errno != ENOENT) {
  -         ap_log_error(APLOG_MARK, APLOG_ERR, r->server,
  -                      "proxy: stat(%s)", filename);
  -         ap_unblock_alarms();
  -         return;
  -     }
  -     if ((timefd = creat(filename, 0666)) == -1) {
  -         if (errno != EEXIST)
  -             ap_log_error(APLOG_MARK, APLOG_ERR, r->server,
  -                          "proxy: creat(%s)", filename);
  -         else
  -             lastcheck = garbage_now;        /* someone else got in there */
  -         ap_unblock_alarms();
  -         return;
  -     }
  -     close(timefd);
  +    /* At this point we have a bit of an engineering compromise. We could 
either
  +     * create and/or mark the .time file  (prior to the fork which might
  +     * fail on a resource issue) or wait until we are safely forked. The
  +     * advantage of doing it now in this process is that we get some
  +     * usefull live out of the global last check variable. (XXX which
  +     * should go scoreboard IMHO.) Note that the actual counting is 
  +     * at a later moment.
  +     */
  +   if (stat(filename, &buf) == -1) {   /* does not exist */
  +        if (errno != ENOENT) {
  +            ap_log_error(APLOG_MARK, APLOG_ERR, r->server,
  +                         "proxy: stat(%s)", filename);
  +            return 0;
  +        }
  +        if ((timefd = creat(filename, 0666)) == -1) {
  +            if (errno != EEXIST)
  +                ap_log_error(APLOG_MARK, APLOG_ERR, r->server,
  +                             "proxy: creat(%s)", filename);
  +            else
  +                lastcheck = garbage_now;        /* someone else got in there 
*/
  +            return 0;
  +        }
  +        close(timefd);
       }
       else {
  -     lastcheck = buf.st_mtime;       /* save the time */
  -     if (garbage_now < lastcheck + every) {
  -         ap_unblock_alarms();
  -         return;
  -     }
  -     if (utime(filename, NULL) == -1)
  -         ap_log_error(APLOG_MARK, APLOG_ERR, r->server,
  -                      "proxy: utimes(%s)", filename);
  +     lastcheck = buf.st_mtime;       /* save the time */
  +        if (garbage_now < lastcheck + every) {
  +            ap_unblock_alarms();
  +            return 0;
  +        }
  +        if (utime(filename, NULL) == -1)
  +            ap_log_error(APLOG_MARK, APLOG_ERR, r->server,
  +                         "proxy: utimes(%s)", filename);
       }
  +
  +    return 1;
  +}
  +
  +static void help_proxy_garbage_coll(request_rec *r)
  +{
  +    const char *cachedir;
  +    void *sconf = r->server->module_config;
  +    proxy_server_conf *pconf =
  +    (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
  +    const struct cache_conf *conf = &pconf->cache;
  +    array_header *files;
  +    struct gc_ent *fent;
  +    int i;
  +    char filename[ strlen(cachedir) + HASH_LEN + 2];
  +
  +    cachedir = conf->root;
  +    /* configured size is given in kB. Make it bytes, convert to long61_t: */
  +    cachesize.lower = cachesize.upper = 0;
  +    add_long61(&cachesize, conf->space << 10);
  +
  +    ap_block_alarms();               /* avoid SIGALRM on big cache cleanup */
  +
       files = ap_make_array(r->pool, 100, sizeof(struct gc_ent));
       curbytes.upper = curbytes.lower = 0L;
   
  
  
  

Reply via email to