httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Dean Gaudet <dgau...@hyperreal.org>
Subject cvs commit: apache/src CHANGES http_main.c mod_status.c scoreboard.h
Date Thu, 24 Jul 1997 04:32:33 GMT
dgaudet     97/07/23 21:32:32

  Modified:    src       CHANGES http_main.c mod_status.c scoreboard.h
  Log:
  Exponential spawning, and a child_main optimization for single socket
  servers.
  
  Revision  Changes    Path
  1.362     +10 -0     apache/src/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /export/home/cvs/apache/src/CHANGES,v
  retrieving revision 1.361
  retrieving revision 1.362
  diff -u -r1.361 -r1.362
  --- CHANGES	1997/07/24 04:23:55	1.361
  +++ CHANGES	1997/07/24 04:32:27	1.362
  @@ -1,5 +1,15 @@
   Changes with Apache 1.3a2
   
  +  *) child_main avoids an uneeded call to select() when there is only one
  +     listening socket.  [Dean Gaudet]
  +
  +  *) In the event that the server is starved for idle servers it will
  +     spawn 1, then 2, then 4, ..., then 32 servers each second,
  +     doubling each second.  It'll also give a warning in the errorlog
  +     since the most common reason for this is a poor StartServers
  +     setting.  The define MAX_SPAWN_RATE can be used to raise/lower
  +     the maximum.  [Dean Gaudet]
  +
     *) "nph-" CGIs were not compatible with HTTP/1.1 or SSL support because
        they were passed a socket that connected directly to the client.
        As such they would have to implement the transport level details
  
  
  
  1.186     +82 -34    apache/src/http_main.c
  
  Index: http_main.c
  ===================================================================
  RCS file: /export/home/cvs/apache/src/http_main.c,v
  retrieving revision 1.185
  retrieving revision 1.186
  diff -u -r1.185 -r1.186
  --- http_main.c	1997/07/22 23:51:58	1.185
  +++ http_main.c	1997/07/24 04:32:28	1.186
  @@ -1094,7 +1094,7 @@
       
       sync_scoreboard_image();
       new_score_rec = scoreboard_image->servers[child_num];
  -    new_score_rec.pid = getpid();
  +    new_score_rec.x.pid = getpid();
       old_status = new_score_rec.status;
       new_score_rec.status = status;
   
  @@ -1219,7 +1219,7 @@
       int i;
   
       for (i = 0; i < max_daemons_limit; ++i)
  -	if (scoreboard_image->servers[i].pid == pid)
  +	if (scoreboard_image->servers[i].x.pid == pid)
   	    return i;
   
       return -1;
  @@ -1233,7 +1233,7 @@
   
       sync_scoreboard_image();
       for (i = 0; i < max_daemons_limit; ++i) {
  -	int pid = scoreboard_image->servers[i].pid;
  +	int pid = scoreboard_image->servers[i].x.pid;
   
   	if (pid != my_pid && pid != 0) { 
   	    int waitret = 0,
  @@ -1304,7 +1304,7 @@
   
       for (n = 0; n < max_daemons_limit; ++n) {
   	if (scoreboard_image->servers[n].status != SERVER_DEAD
  -		&& waitpid (scoreboard_image->servers[n].pid, &status, WNOHANG)
  +		&& waitpid (scoreboard_image->servers[n].x.pid, &status, WNOHANG)
   		    == -1
   		&& errno == ECHILD) {
   	    sync_scoreboard_image ();
  @@ -1337,7 +1337,7 @@
               if(scoreboard_image->servers[pi].status != SERVER_DEAD)
               {
                   e[hi] = pi;
  -                h[hi++] = (HANDLE)scoreboard_image->servers[pi].pid;
  +                h[hi++] = (HANDLE)scoreboard_image->servers[pi].x.pid;
               }
   
           }
  @@ -1347,9 +1347,9 @@
               if(rv == -1)
                   err = GetLastError();
               if((WAIT_OBJECT_0 <= (unsigned int)rv) && ((unsigned int)rv <
(WAIT_OBJECT_0 + hi)))
  -                return(scoreboard_image->servers[e[rv - WAIT_OBJECT_0]].pid);
  +                return(scoreboard_image->servers[e[rv - WAIT_OBJECT_0]].x.pid);
               else if((WAIT_ABANDONED_0 <= (unsigned int)rv) && ((unsigned int)rv
< (WAIT_ABANDONED_0 + hi)))
  -                return(scoreboard_image->servers[e[rv - WAIT_ABANDONED_0]].pid);
  +                return(scoreboard_image->servers[e[rv - WAIT_ABANDONED_0]].x.pid);
   
           }
       }
  @@ -2129,7 +2129,6 @@
   #endif    
   
       while (1) {
  -	int errsave;
   	BUFF *conn_io;
   	request_rec *r;
         
  @@ -2169,24 +2168,24 @@
           accept_mutex_on();  /* Lock around "accept", if necessary */
   
           for (;;) {
  -            memcpy(&main_fds, &listenfds, sizeof(fd_set));
  -            srv = ap_select(listenmaxfd+1, &main_fds, NULL, NULL, NULL);
  -            errsave = errno;
  -
  -            sync_scoreboard_image();
  -            if (scoreboard_image->global.exit_generation >= generation)
  -                exit(0);
  -
  -            errno = errsave;
  -            if (srv < 0 && errno != EINTR)
  -                log_unixerr("select", "(listen)", NULL, server_conf);
  -
  -            if (srv <= 0)
  -                continue;
  -
  -	    lr = find_ready_listener(&main_fds);
  -	    if (lr == NULL) continue;
  -	    sd = lr->fd;
  +	    if (listeners->next != listeners) {
  +		/* more than one socket */
  +		memcpy(&main_fds, &listenfds, sizeof(fd_set));
  +		srv = ap_select(listenmaxfd+1, &main_fds, NULL, NULL, NULL);
  +
  +		if (srv < 0 && errno != EINTR)
  +		    log_unixerr("select", "(listen)", NULL, server_conf);
  +
  +		if (srv <= 0)
  +		    continue;
  +
  +		lr = find_ready_listener(&main_fds);
  +		if (lr == NULL) continue;
  +		sd = lr->fd;
  +	    } else {
  +		/* there's only one socket, just pretend we the other stuff */
  +		sd = listeners->fd;
  +	    }
   
   	    /* if we accept() something we don't want to die, so we have to
   	     * defer the exit
  @@ -2223,6 +2222,12 @@
   		/* ok maybe not, see ya later */
   		exit (0);
   	    }
  +	    /* or maybe we missed a signal, you never know on systems
  +	     * without reliable signals
  +	     */
  +	    sync_scoreboard_image();
  +	    if (scoreboard_image->global.exit_generation >= generation)
  +		exit(0);
           }
   
           accept_mutex_off(); /* unlock after "accept" */
  @@ -2404,7 +2409,7 @@
        * to the same word.)
        * XXX: this needs to be sync'd to disk in the non shared memory stuff
        */
  -    scoreboard_image->servers[slot].pid = pid;
  +    scoreboard_image->servers[slot].x.pid = pid;
   
       return 0;
   }
  @@ -2427,16 +2432,34 @@
   }
   
   
  +/*
  + * idle_spawn_rate is the number of children that will be spawned on the
  + * next maintenance cycle if there aren't enough idle servers.  It is
  + * doubled up to MAX_SPAWN_RATE, and reset only when a cycle goes by
  + * without the need to spawn.
  + */
  +static int idle_spawn_rate = 1;
  +#ifndef MAX_SPAWN_RATE
  +#define MAX_SPAWN_RATE	(32)
  +#endif
  +
   static void perform_idle_server_maintenance (void)
   {
       int i;
       int to_kill;
  -    int free_slot;
       int idle_count;
  +    int free_head;
  +    int *free_ptr;
  +    int free_length;
  +
  +    /* initialize the free_list */
  +    free_head = -1;
  +    free_ptr = &free_head;
  +    free_length = 0;
   
  -    free_slot = -1;
       to_kill = -1;
       idle_count = 0;
  +
       sync_scoreboard_image ();
       for (i = 0; i < daemons_limit; ++i) {
   	switch (scoreboard_image->servers[i].status) {
  @@ -2452,8 +2475,10 @@
   	    break;
   	case SERVER_DEAD:
   	    /* try to keep children numbers as low as possible */
  -	    if (free_slot == -1) {
  -		free_slot = i;
  +	    if (free_length < idle_spawn_rate) {
  +		*free_ptr = i;
  +		free_ptr = &scoreboard_image->servers[i].x.free_list;
  +		++free_length;
   	    }
   	    break;
   	}
  @@ -2463,9 +2488,12 @@
   	 * shut down gracefully, in case it happened to pick up a request
   	 * while we were counting
   	 */
  -	kill (scoreboard_image->servers[to_kill].pid, SIGUSR1);
  +	kill (scoreboard_image->servers[to_kill].x.pid, SIGUSR1);
  +	idle_spawn_rate = 1;
       } else if (idle_count < daemons_min_free) {
  -	if (free_slot == -1) {
  +	/* terminate the free list */
  +	*free_ptr = -1;
  +	if (free_head == -1) {
   	    /* only report this condition once */
   	    static int reported = 0;
   
  @@ -2476,8 +2504,28 @@
   		reported = 1;
   	    }
   	} else {
  -	    make_child (server_conf, free_slot);
  +	    if (idle_spawn_rate >= 4) {
  +		log_printf (server_conf,
  +		    "server seems busy, spawning %d children (you may need "
  +		    "to increase StartServers, or Min/MaxSpareServers)",
  +		    idle_spawn_rate);
  +	    }
  +	    i = 0;
  +	    while (i < idle_spawn_rate && free_head != -1) {
  +		int slot = free_head;
  +		free_head = scoreboard_image->servers[free_head].x.free_list;
  +		make_child (server_conf, slot);
  +		++i;
  +	    }
  +	    /* the next time around we want to spawn twice as many if this
  +	     * wasn't good enough
  +	     */
  +	    if (idle_spawn_rate < MAX_SPAWN_RATE) {
  +		idle_spawn_rate *= 2;
  +	    }
   	}
  +    } else {
  +	idle_spawn_rate = 1;
       }
   }
   
  
  
  
  1.54      +2 -2      apache/src/mod_status.c
  
  Index: mod_status.c
  ===================================================================
  RCS file: /export/home/cvs/apache/src/mod_status.c,v
  retrieving revision 1.53
  retrieving revision 1.54
  diff -u -r1.53 -r1.54
  --- mod_status.c	1997/07/17 22:27:41	1.53
  +++ mod_status.c	1997/07/24 04:32:29	1.54
  @@ -472,7 +472,7 @@
   			 i,(int)conn_lres,my_lres,lres);
   		    else
   			rprintf(r,"<b>Server %d</b> (%d): %d|%lu|%lu [",
  -			 i,(int)score_record.pid,(int)conn_lres,my_lres,lres);
  +			 i,(int)score_record.x.pid,(int)conn_lres,my_lres,lres);
   
   		    switch (score_record.status)
   		    {
  @@ -537,7 +537,7 @@
   			 i,(int)conn_lres,my_lres,lres);
   		    else
   			rprintf(r,"<tr><td><b>%d</b><td>%d<td>%d/%lu/%lu",
  -			 i,(int)score_record.pid,(int)conn_lres,my_lres,lres);
  +			 i,(int)score_record.x.pid,(int)conn_lres,my_lres,lres);
   
   		    switch (score_record.status)
   		    {
  
  
  
  1.27      +5 -2      apache/src/scoreboard.h
  
  Index: scoreboard.h
  ===================================================================
  RCS file: /export/home/cvs/apache/src/scoreboard.h,v
  retrieving revision 1.26
  retrieving revision 1.27
  diff -u -r1.26 -r1.27
  --- scoreboard.h	1997/07/21 05:53:51	1.26
  +++ scoreboard.h	1997/07/24 04:32:30	1.27
  @@ -76,8 +76,11 @@
   #define SERVER_GRACEFUL 8	/* server is gracefully finishing request */
   
   typedef struct {
  -    pid_t pid;
  -    char status;
  +    union {
  +	pid_t pid;		/* if it's not DEAD then this is the pid */
  +	int free_list;		/* otherwise this is scratch space */
  +    } x;
  +    int status;
   #if defined(STATUS)
       unsigned long access_count;
       unsigned long bytes_served;
  
  
  

Mime
View raw message