dgaudet     99/06/20 14:46:14

  Modified:    mpm/src  CHANGES
               mpm/src/include alloc.h
               mpm/src/main alloc.c mpm_prefork.c
  Log:
  remove 1.3 timeout code; SIGUSR1/SIGHUP/SIGTERM working again
  
  Revision  Changes    Path
  1.7       +3 -0      apache-2.0/mpm/src/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /home/cvs/apache-2.0/mpm/src/CHANGES,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- CHANGES   1999/06/20 21:12:47     1.6
  +++ CHANGES   1999/06/20 21:46:11     1.7
  @@ -1,5 +1,8 @@
   Changes with MPM
   
  +    * mpm_prefork: throw away all the alarm/timeout crud; and clean up the
  +      signal handling for the new world order.  [Dean Gaudet]
  +
       * Crude ap_thread_mutex abstraction so that we get the pthread stuff out
         of alloc.c for now. [Dean Gaudet]
   
  
  
  
  1.2       +0 -22     apache-2.0/mpm/src/include/alloc.h
  
  Index: alloc.h
  ===================================================================
  RCS file: /home/cvs/apache-2.0/mpm/src/include/alloc.h,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- alloc.h   1999/06/18 18:39:27     1.1
  +++ alloc.h   1999/06/20 21:46:12     1.2
  @@ -287,10 +287,6 @@
    *
    * Cleanups are identified for purposes of finding & running them off by the
    * plain_cleanup and data, which should presumably be unique.
  - *
  - * NB any code which invokes register_cleanup or kill_cleanup directly
  - * is a critical section which should be guarded by block_alarms() and
  - * unblock_alarms() below...
    */
   
   API_EXPORT(void) ap_register_cleanup(pool *p, void *data,
  @@ -303,24 +299,6 @@
   /* A "do-nothing" cleanup, for register_cleanup; it's faster to do
    * things this way than to test for NULL. */
   API_EXPORT_NONSTD(void) ap_null_cleanup(void *data);
  -
  -/* The time between when a resource is actually allocated, and when it
  - * its cleanup is registered is a critical section, during which the
  - * resource could leak if we got interrupted or timed out.  So, anything
  - * which registers cleanups should bracket resource allocation and the
  - * cleanup registry with these.  (This is done internally by run_cleanup).
  - *
  - * NB they are actually implemented in http_main.c, since they are bound
  - * up with timeout handling in general...
  - */
  -
  -#ifdef TPF
  -#define ap_block_alarms() (0)
  -#define ap_unblock_alarms() (0)
  -#else
  -API_EXPORT(void) ap_block_alarms(void);
  -API_EXPORT(void) ap_unblock_alarms(void);
  -#endif /* TPF */
   
   /* Common cases which want utility support..
    * the note_cleanups_for_foo routines are for 
  
  
  
  1.3       +4 -4      apache-2.0/mpm/src/main/alloc.c
  
  Index: alloc.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/mpm/src/main/alloc.c,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- alloc.c   1999/06/20 21:12:49     1.2
  +++ alloc.c   1999/06/20 21:46:12     1.3
  @@ -303,7 +303,7 @@
   #define test_is_free(_x)
   #endif
   
  -/* Free a chain of blocks --- must be called with alarms blocked. */
  +/* Free a chain of blocks --- must be called with mutex held. */
   #ifdef POOL_DEBUG
   #define reset_block(b) do { \
           test_is_free(b); \
  @@ -383,7 +383,7 @@
   
   
   /* Get a new block, from our own free list if possible, from the system
  - * if necessary.  Must be called with alarms blocked.
  + * if necessary.  Must be called with mutex held.
    */
   
   static union block_hdr *new_block(int min_size)
  @@ -873,8 +873,8 @@
    * until all the output is done.
    *
    * Note that this is completely safe because nothing else can
  - * allocate in this pool while ap_psprintf is running.  alarms are
  - * blocked, and the only thing outside of alloc.c that's invoked
  + * allocate in this pool while ap_psprintf is running. 
  + * The only thing outside of alloc.c that's invoked
    * is ap_vformatter -- which was purposefully written to be
    * self-contained with no callouts.
    */
  
  
  
  1.5       +21 -348   apache-2.0/mpm/src/main/mpm_prefork.c
  
  Index: mpm_prefork.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/mpm/src/main/mpm_prefork.c,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- mpm_prefork.c     1999/06/20 21:12:50     1.4
  +++ mpm_prefork.c     1999/06/20 21:46:13     1.5
  @@ -82,7 +82,6 @@
    * TODO: behave like apache-1.3... here's a short list of things I think
    * TODO: need cleaning up still:
    * TODO: - use ralf's mm stuff for the shared mem and mutexes
  - * TODO: - eliminate the timeout stuff... 2.0 timeouts are part of the BUFF
    * TODO: - abstract the Listen stuff, it's going to be common with other MPM
    * TODO: - clean up scoreboard stuff when we figure out how to do it in 2.0
    */
  @@ -161,7 +160,6 @@
   /* *Non*-shared http_main globals... */
   
   static server_rec *server_conf;
  -static JMP_BUF jmpbuffer;
   static int sd;
   static fd_set listenfds;
   static int listenmaxfd;
  @@ -180,11 +178,6 @@
   
   static int one_process = 0;
   
  -/* set if timeouts are to be handled by the children and not by the parent.
  - * i.e. child_timeouts = !standalone || one_process.
  - */
  -static int child_timeouts;
  -
   #ifdef HAS_OTHER_CHILD
   /* used to maintain list of children which aren't part of the scoreboard */
   typedef struct other_child_rec other_child_rec;
  @@ -804,220 +797,7 @@
   #define SAFE_ACCEPT(stmt) do {stmt;} while(0)
   #endif
   
  -/*****************************************************************
  - *
  - * Timeout handling.  DISTINCTLY not thread-safe, but all this stuff
  - * has to change for threads anyway.  Note that this code allows only
  - * one timeout in progress at a time...
  - */
  -
  -static conn_rec *volatile current_conn;
  -static request_rec *volatile timeout_req;
  -static const char *volatile timeout_name = NULL;
  -static int volatile alarms_blocked = 0;
  -static int volatile alarm_pending = 0;
  -
  -static void timeout(int sig)
  -{
  -    void *dirconf;
  -
  -    if (alarms_blocked) {
  -     alarm_pending = 1;
  -     return;
  -    }
  -    if (exit_after_unblock) {
  -     clean_child_exit(0);
  -    }
  -
  -    if (!current_conn) {
  -     ap_longjmp(jmpbuffer, 1);
  -    }
  -
  -    if (timeout_req != NULL)
  -     dirconf = timeout_req->per_dir_config;
  -    else
  -     dirconf = current_conn->base_server->lookup_defaults;
  -    if (!current_conn->keptalive) {
  -     ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO,
  -                  current_conn->base_server, "[client %s] %s timed out",
  -                  current_conn->remote_ip,
  -                  timeout_name ? timeout_name : "request");
  -    }
  -
  -    if (timeout_req) {
  -     /* Someone has asked for this transaction to just be aborted
  -      * if it times out...
  -      */
  -
  -     request_rec *log_req = timeout_req;
  -     request_rec *save_req = timeout_req;
  -
  -     /* avoid looping... if ap_log_transaction started another
  -      * timer (say via rfc1413.c) we could loop...
  -      */
  -     timeout_req = NULL;
  -
  -     while (log_req->main || log_req->prev) {
  -         /* Get back to original request... */
  -         if (log_req->main)
  -             log_req = log_req->main;
  -         else
  -             log_req = log_req->prev;
  -     }
  -
  -     if (!current_conn->keptalive) {
  -         /* in some cases we come here before setting the time */
  -         if (log_req->request_time == 0) {
  -           log_req->request_time = time(0);
  -         }
  -         ap_log_transaction(log_req);
  -     }
  -
  -     ap_bsetflag(save_req->connection->client, B_EOUT, 1);
  -     ap_bclose(save_req->connection->client);
  -
  -     ap_longjmp(jmpbuffer, 1);
  -    }
  -    else {                   /* abort the connection */
  -     ap_bsetflag(current_conn->client, B_EOUT, 1);
  -     ap_bclose(current_conn->client);
  -     current_conn->aborted = 1;
  -    }
  -}
  -
  -#ifndef TPF
  -/*
  - * These two called from alloc.c to protect its critical sections...
  - * Note that they can nest (as when destroying the sub_pools of a pool
  - * which is itself being cleared); we have to support that here.
  - */
  -
  -API_EXPORT(void) ap_block_alarms(void)
  -{
  -    ++alarms_blocked;
  -}
  -
  -API_EXPORT(void) ap_unblock_alarms(void)
  -{
  -    --alarms_blocked;
  -    if (alarms_blocked == 0) {
  -     if (exit_after_unblock) {
  -         /* We have a couple race conditions to deal with here, we can't
  -          * allow a timeout that comes in this small interval to allow
  -          * the child to jump back to the main loop.  Instead we block
  -          * alarms again, and then note that exit_after_unblock is
  -          * being dealt with.  We choose this way to solve this so that
  -          * the common path through unblock_alarms() is really short.
  -          */
  -         ++alarms_blocked;
  -         exit_after_unblock = 0;
  -         clean_child_exit(0);
  -     }
  -     if (alarm_pending) {
  -         alarm_pending = 0;
  -         timeout(0);
  -     }
  -    }
  -}
  -#endif /* TPF */
  -
  -static void (*volatile alarm_fn) (int) = NULL;
  -
  -static void alrm_handler(int sig)
  -{
  -    if (alarm_fn) {
  -     (*alarm_fn) (sig);
  -    }
  -}
  -
  -unsigned int ap_set_callback_and_alarm(void (*fn) (int), int x)
  -{
  -    unsigned int old;
  -
  -    if (alarm_fn && x && fn != alarm_fn) {
  -     ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, NULL,
  -         "ap_set_callback_and_alarm: possible nested timer!");
  -    }
  -    alarm_fn = fn;
  -#ifndef OPTIMIZE_TIMEOUTS
  -    old = alarm(x);
  -#else
  -    if (child_timeouts) {
  -     old = alarm(x);
  -    }
  -    else {
  -     /* Just note the timeout in our scoreboard, no need to call the system.
  -      * We also note that the virtual time has gone forward.
  -      */
  -     ap_check_signals();
  -     old = ap_scoreboard_image->servers[my_child_num].timeout_len;
  -     ap_scoreboard_image->servers[my_child_num].timeout_len = x;
  -     ++ap_scoreboard_image->servers[my_child_num].cur_vtime;
  -    }
  -#endif
  -    return (old);
  -}
  -
  -
  -/* reset_timeout (request_rec *) resets the timeout in effect,
  - * as long as it hasn't expired already.
  - */
  -
  -API_EXPORT(void) ap_reset_timeout(request_rec *r)
  -{
  -    int i;
  -
  -    if (timeout_name) {              /* timeout has been set */
  -     i = ap_set_callback_and_alarm(alarm_fn, r->server->timeout);
  -     if (i == 0)             /* timeout already expired, so set it back to 0 
*/
  -         ap_set_callback_and_alarm(alarm_fn, 0);
  -    }
  -}
  -
  -
  -
  -
  -void ap_keepalive_timeout(char *name, request_rec *r)
  -{
  -    unsigned int to;
   
  -    timeout_req = r;
  -    timeout_name = name;
  -
  -    if (r->connection->keptalive)
  -     to = r->server->keep_alive_timeout;
  -    else
  -     to = r->server->timeout;
  -    ap_set_callback_and_alarm(timeout, to);
  -
  -}
  -
  -API_EXPORT(void) ap_hard_timeout(char *name, request_rec *r)
  -{
  -    timeout_req = r;
  -    timeout_name = name;
  -
  -    ap_set_callback_and_alarm(timeout, r->server->timeout);
  -
  -}
  -
  -API_EXPORT(void) ap_soft_timeout(char *name, request_rec *r)
  -{
  -    timeout_name = name;
  -
  -    ap_set_callback_and_alarm(timeout, r->server->timeout);
  -
  -}
  -
  -API_EXPORT(void) ap_kill_timeout(request_rec *dummy)
  -{
  -    ap_check_signals();
  -    ap_set_callback_and_alarm(NULL, 0);
  -    timeout_req = NULL;
  -    timeout_name = NULL;
  -}
  -
  -
   /*****************************************************************
    * dealing with other children
    */
  @@ -1635,14 +1415,8 @@
       ss = &ap_scoreboard_image->servers[child_num];
       old_status = ss->status;
       ss->status = status;
  -#ifdef OPTIMIZE_TIMEOUTS
  -    ++ss->cur_vtime;
  -#endif
   
       if (ap_extended_status) {
  -#ifndef OPTIMIZE_TIMEOUTS
  -     ss->last_used = time(NULL);
  -#endif
        if (status == SERVER_READY || status == SERVER_DEAD) {
            /*
             * Reset individual counters
  @@ -2107,19 +1881,12 @@
    */
   
   static void just_die(int sig)
  -{                            /* SIGHUP to child process??? */
  -    /* if alarms are blocked we have to wait to die otherwise we might
  -     * end up with corruption in alloc.c's internal structures */
  -    if (alarms_blocked) {
  -     exit_after_unblock = 1;
  -    }
  -    else {
  -     clean_child_exit(0);
  -    }
  +{
  +    clean_child_exit(0);
   }
   
  -static int volatile usr1_just_die = 1;
   static int volatile deferred_die;
  +static int volatile usr1_just_die;
   
   static void usr1_handler(int sig)
   {
  @@ -2134,20 +1901,8 @@
   static int volatile restart_pending;
   static int volatile is_graceful;
   ap_generation_t volatile ap_my_generation=0;
  -
   
  -/*
  - * ap_start_shutdown() and ap_start_restart(), below, are a first stab at
  - * functions to initiate shutdown or restart without relying on signals. 
  - * Previously this was initiated in sig_term() and restart() signal 
handlers, 
  - * but we want to be able to start a shutdown/restart from other sources --
  - * e.g. on Win32, from the service manager. Now the service manager can
  - * call ap_start_shutdown() or ap_start_restart() as appropiate.  Note that
  - * these functions can also be called by the child processes, since global
  - * variables are no longer used to pass on the required action to the parent.
  - */
  -
  -void ap_start_shutdown(void)
  +static void sig_term(int sig)
   {
       if (shutdown_pending == 1) {
        /* Um, is this _probably_ not an error, if the user has
  @@ -2159,25 +1914,14 @@
       shutdown_pending = 1;
   }
   
  -/* do a graceful restart if graceful == 1 */
  -void ap_start_restart(int graceful)
  +static void restart(int sig)
   {
       if (restart_pending == 1) {
        /* Probably not an error - don't bother reporting it */
        return;
       }
       restart_pending = 1;
  -    is_graceful = graceful;
  -}
  -
  -static void sig_term(int sig)
  -{
  -    ap_start_shutdown();
  -}
  -
  -static void restart(int sig)
  -{
  -    ap_start_restart(sig == SIGUSR1);
  +    is_graceful = sig == SIGUSR1;
   }
   
   static void set_signals(void)
  @@ -2484,11 +2228,9 @@
        ap_snprintf(addr, sizeof(addr), "port %d", ntohs(server->sin_port));
   
       /* note that because we're about to slack we don't use psocket */
  -    ap_block_alarms();
       if ((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
        ap_log_error(APLOG_MARK, APLOG_CRIT, server_conf,
                    "make_sock: failed to get a socket for %s", addr);
  -     ap_unblock_alarms();
        exit(1);
       }
   
  @@ -2527,7 +2269,6 @@
        ap_log_error(APLOG_MARK, APLOG_CRIT, server_conf,
                    "make_sock: for %s, setsockopt: (SO_REUSEADDR)", addr);
        close(s);
  -     ap_unblock_alarms();
        return -1;
       }
   #endif /*_OSD_POSIX*/
  @@ -2537,7 +2278,6 @@
        ap_log_error(APLOG_MARK, APLOG_CRIT, server_conf,
                    "make_sock: for %s, setsockopt: (SO_KEEPALIVE)", addr);
        close(s);
  -     ap_unblock_alarms();
        return -1;
       }
   #endif
  @@ -2589,7 +2329,6 @@
            GETUSERMODE();
   #endif
        close(s);
  -     ap_unblock_alarms();
        exit(1);
       }
   #ifdef MPE
  @@ -2601,7 +2340,6 @@
        ap_log_error(APLOG_MARK, APLOG_ERR, server_conf,
            "make_sock: unable to listen for connections on %s", addr);
        close(s);
  -     ap_unblock_alarms();
        exit(1);
       }
   
  @@ -2610,7 +2348,6 @@
   
       ap_note_cleanups_for_socket(p, s);       /* arrange to close on exec or 
restart */
   #endif
  -    ap_unblock_alarms();
   
   #ifdef CHECK_FD_SETSIZE
       /* protect various fd_sets */
  @@ -2781,7 +2518,8 @@
   int ap_mpm_graceful_stop(void)
   {
       ap_sync_scoreboard_image();
  -    if (ap_scoreboard_image->global.running_generation != ap_my_generation) {
  +    if (deferred_die ||
  +     ap_scoreboard_image->global.running_generation != ap_my_generation) {
        return 1;
       }
       return 0;
  @@ -2794,18 +2532,7 @@
       struct sockaddr sa_client;
       listen_rec *lr;
       pool *ptrans;
  -
  -    /* All of initialization is a critical section, we don't care if we're
  -     * told to HUP or USR1 before we're done initializing.  For example,
  -     * we could be half way through ap_child_init_hook() when a restart
  -     * signal arrives, and we'd have no real way to recover gracefully
  -     * and exit properly.
  -     *
  -     * I suppose a module could take forever to initialize, but that would
  -     * be either a broken module, or a broken configuration (i.e. network
  -     * problems, file locking problems, whatever). -djg
  -     */
  -    ap_block_alarms();
  +    conn_rec *current_conn;
   
       my_pid = getpid();
       csd = -1;
  @@ -2851,26 +2578,10 @@
   
       ap_child_init_hook(pchild, server_conf);
   
  -    /* done with the initialization critical section */
  -    ap_unblock_alarms();
  -
       (void) ap_update_child_status(my_child_num, SERVER_READY, (request_rec 
*) NULL);
   
  -    /*
  -     * Setup the jump buffers so that we can return here after a timeout 
  -     */
  -    ap_setjmp(jmpbuffer);
  -#ifndef OS2
  -#ifdef SIGURG
  -    signal(SIGURG, timeout);
  -#endif
  -#endif
  -    signal(SIGALRM, alrm_handler);
  -#ifdef TPF
       signal(SIGHUP, just_die);
       signal(SIGTERM, just_die);
  -    signal(SIGUSR1, just_die);
  -#endif /* TPF */
   
   #ifdef OS2
   /* Stop Ctrl-C/Ctrl-Break signals going to child processes */
  @@ -2884,9 +2595,8 @@
        BUFF *conn_io;
   
        /* Prepare to receive a SIGUSR1 due to graceful restart so that
  -      * we can exit cleanly.  Since we're between connections right
  -      * now it's the right time to exit, but we might be blocked in a
  -      * system call when the graceful restart request is made. */
  +      * we can exit cleanly.
  +      */
        usr1_just_die = 1;
        signal(SIGUSR1, usr1_handler);
   
  @@ -2894,16 +2604,10 @@
         * (Re)initialize this child to a pre-connection state.
         */
   
  -     ap_kill_timeout(0);     /* Cancel any outstanding alarms. */
        current_conn = NULL;
   
        ap_clear_pool(ptrans);
   
  -     ap_sync_scoreboard_image();
  -     if (ap_scoreboard_image->global.running_generation != ap_my_generation) 
{
  -         clean_child_exit(0);
  -     }
  -
        if ((ap_max_requests_per_child > 0
             && requests_this_child++ >= ap_max_requests_per_child)) {
            clean_child_exit(0);
  @@ -2951,17 +2655,16 @@
            /* if we accept() something we don't want to die, so we have to
             * defer the exit
             */
  -         deferred_die = 0;
            usr1_just_die = 0;
            for (;;) {
  -             clen = sizeof(sa_client);
  -             csd = ap_accept(sd, &sa_client, &clen);
  -             if (csd >= 0 || errno != EINTR)
  -                 break;
                if (deferred_die) {
                    /* we didn't get a socket, and we were told to die */
                    clean_child_exit(0);
                }
  +             clen = sizeof(sa_client);
  +             csd = ap_accept(sd, &sa_client, &clen);
  +             if (csd >= 0 || errno != EINTR)
  +                 break;
            }
   
            if (csd >= 0)
  @@ -3038,19 +2741,10 @@
                }
            }
   
  -         /* go around again, safe to die */
  -         usr1_just_die = 1;
  -         if (deferred_die) {
  -             /* ok maybe not, see ya later */
  +         if (ap_mpm_graceful_stop()) {
                clean_child_exit(0);
            }
  -         /* or maybe we missed a signal, you never know on systems
  -          * without reliable signals
  -          */
  -         ap_sync_scoreboard_image();
  -         if (ap_scoreboard_image->global.running_generation != 
ap_my_generation) {
  -             clean_child_exit(0);
  -         }
  +         usr1_just_die = 1;
        }
   
        SAFE_ACCEPT(accept_mutex_off());        /* unlock after "accept" */
  @@ -3061,7 +2755,9 @@
   #endif
   
        /* We've got a socket, let's at least process one request off the
  -      * socket before we accept a graceful restart request.
  +      * socket before we accept a graceful restart request.  We set
  +      * the signal to ignore because we don't want to disturb any
  +      * third party code.
         */
        signal(SIGUSR1, SIG_IGN);
   
  @@ -3218,9 +2914,6 @@
        child_main(slot);
       }
   
  -#ifdef OPTIMIZE_TIMEOUTS
  -    ap_scoreboard_image->parent[slot].last_rtime = now;
  -#endif
       ap_scoreboard_image->parent[slot].pid = pid;
   #ifdef SCOREBOARD_FILE
       lseek(scoreboard_fd, XtOffsetOf(scoreboard, parent[slot]), 0);
  @@ -3317,24 +3010,6 @@
   
            ++total_non_dead;
            last_non_dead = i;
  -#ifdef OPTIMIZE_TIMEOUTS
  -         if (ss->timeout_len) {
  -             /* if it's a live server, with a live timeout then
  -              * start checking its timeout */
  -             parent_score *ps = &ap_scoreboard_image->parent[i];
  -             if (ss->cur_vtime != ps->last_vtime) {
  -                 /* it has made progress, so update its last_rtime,
  -                  * last_vtime */
  -                 ps->last_rtime = now;
  -                 ps->last_vtime = ss->cur_vtime;
  -             }
  -             else if (ps->last_rtime + ss->timeout_len < now) {
  -                 /* no progress, and the timeout length has been exceeded */
  -                 ss->timeout_len = 0;
  -                 kill(ps->pid, SIGALRM);
  -             }
  -         }
  -#endif
        }
       }
       max_daemons_limit = last_non_dead + 1;
  @@ -3463,8 +3138,6 @@
   
       server_conf = s;
   
  -    child_timeouts = one_process;
  -
       ap_log_pid(pconf, ap_pid_fname);
       setup_listeners(pconf);
   
  @@ -3687,7 +3360,7 @@
        is_graceful = 0;
   
        if (!one_process) {
  -         /* TODO: detach(); ... it should work fine, this is just easier for 
debugging */
  +         detach();
        }
   
        my_pid = getpid();
  
  
  

Reply via email to