rse         98/03/06 04:52:59

  Modified:    src      CHANGES
               src/modules/standard mod_rewrite.c mod_rewrite.h
  Log:
  Avoid the flock()<->fork() problematic by giving each child an
  own file descriptor instead of a shared one.
  
  Revision  Changes    Path
  1.692     +11 -0     apache-1.3/src/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/CHANGES,v
  retrieving revision 1.691
  retrieving revision 1.692
  diff -u -r1.691 -r1.692
  --- CHANGES   1998/03/06 09:37:04     1.691
  +++ CHANGES   1998/03/06 12:52:55     1.692
  @@ -1,5 +1,16 @@
   Changes with Apache 1.3b6
   
  +  *) Fix one more special locking problem for RewriteMap programs in
  +     mod_rewrite: According to the documentation of flock(), "Locks are on
  +     files, not file descriptors.  That is, file descriptors duplicated
  +     through dup(2) or fork(2) do not result in multiple instances of a lock,
  +     but rather multiple references to a single lock. If a process holding a
  +     lock on a file forks and the child explicitly unlocks the file, the
  +     parent will lose its lock.". To overcome this we have to make sure the
  +     RewriteLock file is opened _AFTER_ the childs were spawned which is now
  +     the case by opening it in the child_init instead of the module_init API
  +     hook. [Ralf S. Engelschall, PR#1029]
  +
     *) Change to Location and LocationMatch semantics.  LocationMatch no
        longer lets a single slash match multiple adjacent slashes in the
        URL.  This change is for consistency with RewriteRule and
  
  
  
  1.87      +86 -29    apache-1.3/src/modules/standard/mod_rewrite.c
  
  Index: mod_rewrite.c
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/modules/standard/mod_rewrite.c,v
  retrieving revision 1.86
  retrieving revision 1.87
  diff -u -r1.86 -r1.87
  --- mod_rewrite.c     1998/03/05 12:42:37     1.86
  +++ mod_rewrite.c     1998/03/06 12:52:57     1.87
  @@ -193,7 +193,7 @@
      hook_fixup,                  /* [#7] pre-run fixups                 */
      NULL,                        /* [#9] log a transaction              */
      NULL,                        /* [#3] header parser                  */
  -   NULL,                        /* child_init                          */
  +   init_child,                  /* child_init                          */
      NULL,                        /* child_exit                          */
      NULL                         /* [#0] post read-request              */
   };
  @@ -869,7 +869,7 @@
   
   /*
   **
  -**  module initialisation
  +**  Global Module Initialization
   **  [called from read_config() after all
   **  config commands were already called]
   **
  @@ -877,26 +877,42 @@
   
   static void init_module(server_rec *s, pool *p)
   {
  +    /* check if proxy module is available */
  +    proxy_available = is_proxy_available(s);
  +
  +    /* precompile a static pattern
  +       for the txt mapfile parsing */
  +    lookup_map_txtfile_regexp = pregcomp(p, MAPFILE_PATTERN, REG_EXTENDED);
  +
  +    /* create the rewriting lockfile in the parent */
  +    rewritelock_create(s, p);
  +    register_cleanup(p, (void *)s, rewritelock_remove, null_cleanup);
  +
       /* step through the servers and
        * - open each rewriting logfile
  -     * - open each rewriting lockfile
        * - open the RewriteMap prg:xxx programs
        */
       for (; s; s = s->next) {
           open_rewritelog(s, p);
  -        open_rewritelock(s, p);
           run_rewritemap_programs(s, p);
       }
  +}
   
  -    /* create the lookup cache */
  -    cachep = init_cache(p);
   
  -    /* check if proxy module is available */
  -    proxy_available = is_proxy_available(s);
  +/*
  +**
  +**  Per-Child Module Initialization
  +**  [called after a child process is spawned]
  +**
  +*/
   
  -    /* precompile a static pattern
  -       for the txt mapfile parsing */
  -    lookup_map_txtfile_regexp = pregcomp(p, MAPFILE_PATTERN, REG_EXTENDED);
  +static void init_child(server_rec *s, pool *p)
  +{
  +     /* open the rewriting lockfile */
  +     rewritelock_open(s, p);
  +
  +     /* create the lookup cache */
  +     cachep = init_cache(p);
   }
   
   
  @@ -2984,37 +3000,78 @@
   ** +-------------------------------------------------------+
   */
   
  -static void open_rewritelock(server_rec *s, pool *p)
  -{
  -    rewrite_server_conf *conf;
  -    char *fname;
  -    int    rewritelock_flags = ( O_WRONLY|O_APPEND|O_CREAT );
   #ifdef WIN32
  -    mode_t rewritelock_mode  = ( _S_IREAD|_S_IWRITE );
  +#define REWRITELOCK_MODE ( _S_IREAD|_S_IWRITE )
   #else
  -    mode_t rewritelock_mode  = ( S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH );
  +#define REWRITELOCK_MODE ( S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH )
   #endif
   
  +static void rewritelock_create(server_rec *s, pool *p)
  +{
  +    rewrite_server_conf *conf;
  +
       conf = get_module_config(s->module_config, &rewrite_module);
   
  -    if (conf->rewritelockfile == NULL)
  -        return;
  -    if (*(conf->rewritelockfile) == '\0')
  +    /* only operate if a lockfile is used */
  +    if (conf->rewritelockfile == NULL 
  +        || *(conf->rewritelockfile) == '\0')
           return;
  -    if (conf->rewritelockfp > 0)
  -        return; /* virtual log shared w/ main server */
   
  -    fname = server_root_relative(p, conf->rewritelockfile);
  +    /* fixup the path, especially for rewritelock_remove() */
  +    conf->rewritelockfile = server_root_relative(p, conf->rewritelockfile);
   
  -    if ((conf->rewritelockfp = popenf(p, fname, rewritelock_flags,
  -                                      rewritelock_mode)) < 0) {
  +    /* create the lockfile */
  +    unlink(conf->rewritelockfile);
  +    if ((conf->rewritelockfp = popenf(p, conf->rewritelockfile, 
  +                                      O_WRONLY|O_CREAT,
  +                                      REWRITELOCK_MODE)) < 0) {
           perror("open");
  -        fprintf(stderr,
  -                "mod_rewrite: could not open RewriteLock file %s.\n",
  -                fname);
  +        fprintf(stderr, "mod_rewrite: Parent could not create RewriteLock"
  +                " file %s.\n", conf->rewritelockfile);
           exit(1);
       }
       return;
  +}
  +
  +static void rewritelock_open(server_rec *s, pool *p)
  +{
  +    rewrite_server_conf *conf;
  +
  +    conf = get_module_config(s->module_config, &rewrite_module);
  +
  +    /* only operate if a lockfile is used */
  +    if (conf->rewritelockfile == NULL 
  +        || *(conf->rewritelockfile) == '\0')
  +        return;
  +
  +    /* open the lockfile (once per child) to get a unique fd */
  +    if ((conf->rewritelockfp = popenf(p, conf->rewritelockfile, 
  +                                      O_WRONLY,
  +                                      REWRITELOCK_MODE)) < 0) {
  +        perror("open");
  +        fprintf(stderr, "mod_rewrite: Child could not open RewriteLock"
  +                " file %s.\n", conf->rewritelockfile);
  +        exit(1);
  +    }
  +    return;
  +}
  +
  +static void rewritelock_remove(void *data)
  +{
  +    server_rec *s;
  +    rewrite_server_conf *conf;
  +
  +    /* the data is really the server_rec */
  +    s = (server_rec *)data;
  +    conf = get_module_config(s->module_config, &rewrite_module);
  +
  +    /* only operate if a lockfile is used */
  +    if (conf->rewritelockfile == NULL 
  +        || *(conf->rewritelockfile) == '\0')
  +        return;
  +
  +    /* remove the lockfile */
  +    unlink(conf->rewritelockfile);
   }
   
   static void rewritelock_alloc(request_rec *r)
  
  
  
  1.47      +4 -1      apache-1.3/src/modules/standard/mod_rewrite.h
  
  Index: mod_rewrite.h
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/modules/standard/mod_rewrite.h,v
  retrieving revision 1.46
  retrieving revision 1.47
  diff -u -r1.46 -r1.47
  --- mod_rewrite.h     1998/03/05 10:45:24     1.46
  +++ mod_rewrite.h     1998/03/06 12:52:58     1.47
  @@ -375,6 +375,7 @@
   
       /* initialisation */
   static void init_module(server_rec *s, pool *p);
  +static void init_child(server_rec *s, pool *p);
   
       /* runtime hooks */
   static int hook_uri2file   (request_rec *r);
  @@ -425,7 +426,9 @@
   static char *current_logtime(request_rec *r);
   
       /* rewriting lockfile support */
  -static void open_rewritelock(server_rec *s, pool *p);
  +static void rewritelock_create(server_rec *s, pool *p);
  +static void rewritelock_open(server_rec *s, pool *p);
  +static void rewritelock_remove(void *data);
   static void rewritelock_alloc(request_rec *r);
   static void rewritelock_free(request_rec *r);
   
  
  
  

Reply via email to