ben 96/07/16 12:39:19
Modified: src CHANGES http_config.c http_config.h http_main.c httpd.h scoreboard.h Log: Graceful restart patches. Revision Changes Path 1.42 +5 -0 apache/src/CHANGES Index: CHANGES =================================================================== RCS file: /export/home/cvs/apache/src/CHANGES,v retrieving revision 1.41 retrieving revision 1.42 diff -C3 -r1.41 -r1.42 *** CHANGES 1996/07/10 14:38:04 1.41 --- CHANGES 1996/07/16 19:39:10 1.42 *************** *** 1,3 **** --- 1,8 ---- + Changes with Apache 1.2b1: + + *) Graceful restart code added. This allows the server to restart without + losing current connections on receipt of signal 2 (SIGINT). [Ben Laurie] + Changes with Apache 1.1.1: *) Fixed bug where Cookie module would make two entries in the 1.14 +42 -1 apache/src/http_config.c Index: http_config.c =================================================================== RCS file: /export/home/cvs/apache/src/http_config.c,v retrieving revision 1.13 retrieving revision 1.14 diff -C3 -r1.13 -r1.14 *** http_config.c 1996/06/29 19:52:11 1.13 --- http_config.c 1996/07/16 19:39:12 1.14 *************** *** 75,80 **** --- 75,83 ---- #include "http_log.h" /* for errors in parse_htaccess */ #include "http_request.h" /* for default_handler (see invoke_handler) */ #include "http_conf_globals.h" /* Sigh... */ + #include "explain.h" + + DEF_Explain /**************************************************************** * *************** *** 206,211 **** --- 209,248 ---- return create_empty_config (p); } + #ifdef EXPLAIN + + struct + { + int offset; + char *method; + } aMethods[]= + { + #define m(meth) { XtOffsetOf(module,meth),#meth } + m(translate_handler), + m(check_user_id), + m(auth_checker), + m(type_checker), + m(fixer_upper), + m(logger), + { -1,"?" }, + #undef m + }; + + char *ShowMethod(module *modp,int offset) + { + int n; + static char buf[200]; + + for(n=0 ; aMethods[n].offset >= 0 ; ++n) + if(aMethods[n].offset == offset) + break; + sprintf(buf,"%s:%s",modp->name,aMethods[n].method); + return buf; + } + #else + #define ShowMethod(modp,offset) + #endif + /**************************************************************** * * Dispatch through the modules to find handlers for various phases *************** *** 221,228 **** handler mod_handler = *(handler *)(offset + (char *)(modp)); if (mod_handler) { ! int result = (*mod_handler)(r); if (result != DECLINED && (!run_all || result != OK)) return result; } --- 258,269 ---- handler mod_handler = *(handler *)(offset + (char *)(modp)); if (mod_handler) { ! int result; ! ! Explain1("Run %s",ShowMethod(modp,offset)); ! result = (*mod_handler)(r); + Explain2("%s returned %d",ShowMethod(modp,offset),result); if (result != DECLINED && (!run_all || result != OK)) return result; } 1.7 +4 -1 apache/src/http_config.h Index: http_config.h =================================================================== RCS file: /export/home/cvs/apache/src/http_config.h,v retrieving revision 1.6 retrieving revision 1.7 diff -C3 -r1.6 -r1.7 *** http_config.h 1996/05/27 19:48:38 1.6 --- http_config.h 1996/07/16 19:39:12 1.7 *************** *** 146,151 **** --- 146,154 ---- int module_index; /* Index to this modules structures in * config vectors. */ + + const char *name; + struct module_struct *next; #ifdef ULTRIX_BRAIN_DEATH *************** *** 198,204 **** */ #define MODULE_MAGIC_NUMBER 19960526 ! #define STANDARD_MODULE_STUFF MODULE_MAGIC_NUMBER, 0, NULL /* Generic accessors for other modules to get at their own module-specific * data --- 201,207 ---- */ #define MODULE_MAGIC_NUMBER 19960526 ! #define STANDARD_MODULE_STUFF MODULE_MAGIC_NUMBER, 0, __FILE__, NULL /* Generic accessors for other modules to get at their own module-specific * data 1.48 +193 -40 apache/src/http_main.c Index: http_main.c =================================================================== RCS file: /export/home/cvs/apache/src/http_main.c,v retrieving revision 1.47 retrieving revision 1.48 diff -C3 -r1.47 -r1.48 *** http_main.c 1996/07/13 01:47:36 1.47 --- http_main.c 1996/07/16 19:39:13 1.48 *************** *** 88,93 **** --- 88,94 ---- #include "http_core.h" /* for get_remote_host */ #include "scoreboard.h" #include <setjmp.h> + #include <assert.h> #ifdef HAVE_SHMGET #include <sys/types.h> #include <sys/ipc.h> *************** *** 165,171 **** */ void accept_mutex_init(pool *p) ! { char lock_fname[30]; strcpy(lock_fname, "/usr/tmp/htlock.XXXXXX"); --- 166,172 ---- */ void accept_mutex_init(pool *p) ! { char lock_fname[30]; strcpy(lock_fname, "/usr/tmp/htlock.XXXXXX"); *************** *** 481,494 **** */ #if defined(HAVE_MMAP) ! static short_score *scoreboard_image=NULL; static void setup_shared_mem(void) { caddr_t m; #if defined(MAP_ANON) || defined(MAP_FILE) /* BSD style */ ! m = mmap((caddr_t)0, HARD_SERVER_LIMIT*sizeof(short_score), PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0); if (m == (caddr_t)-1) { --- 482,495 ---- */ #if defined(HAVE_MMAP) ! static scoreboard *scoreboard_image=NULL; static void setup_shared_mem(void) { caddr_t m; #if defined(MAP_ANON) || defined(MAP_FILE) /* BSD style */ ! m = mmap((caddr_t)0, SCOREBOARD_SIZE, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0); if (m == (caddr_t)-1) { *************** *** 507,513 **** fprintf(stderr, "httpd: Could not open /dev/zero\n"); exit(1); } ! m = mmap((caddr_t)0, HARD_SERVER_LIMIT*sizeof(short_score), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (m == (caddr_t)-1) { --- 508,514 ---- fprintf(stderr, "httpd: Could not open /dev/zero\n"); exit(1); } ! m = mmap((caddr_t)0, SCOREBOARD_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (m == (caddr_t)-1) { *************** *** 517,540 **** } close(fd); #endif ! scoreboard_image = (short_score *)m; } #elif defined(HAVE_SHMGET) ! static short_score *scoreboard_image=NULL; static key_t shmkey = IPC_PRIVATE; static int shmid = -1; static void setup_shared_mem(void) { - int score_size = HARD_SERVER_LIMIT*sizeof(short_score); char errstr[MAX_STRING_LEN]; struct shmid_ds shmbuf; #ifdef MOVEBREAK char *obrk; #endif ! if ((shmid = shmget(shmkey, score_size, IPC_CREAT|SHM_R|SHM_W)) == -1) { perror("shmget"); fprintf(stderr, "httpd: Could not call shmget\n"); --- 518,541 ---- } close(fd); #endif ! scoreboard_image = (scoreboard *)m; ! scoreboard_image->global.exit_generation=0; } #elif defined(HAVE_SHMGET) ! static scoreboard *scoreboard_image=NULL; static key_t shmkey = IPC_PRIVATE; static int shmid = -1; static void setup_shared_mem(void) { char errstr[MAX_STRING_LEN]; struct shmid_ds shmbuf; #ifdef MOVEBREAK char *obrk; #endif ! if ((shmid = shmget(shmkey, SCOREBOARD_SIZE, IPC_CREAT|SHM_R|SHM_W)) == -1) { perror("shmget"); fprintf(stderr, "httpd: Could not call shmget\n"); *************** *** 561,568 **** } #endif ! #define BADSHMAT ((short_score*)(-1)) ! if ((scoreboard_image = (short_score*)shmat(shmid, 0, 0)) == BADSHMAT) { perror("shmat"); fprintf(stderr, "httpd: Could not call shmat\n"); --- 562,569 ---- } #endif ! #define BADSHMAT ((scoreboard *)(-1)) ! if ((scoreboard_image = (scoreboard *)shmat(shmid, 0, 0)) == BADSHMAT) { perror("shmat"); fprintf(stderr, "httpd: Could not call shmat\n"); *************** *** 608,617 **** fprintf(stderr, "httpd: Could not move break back\n"); } #endif } #else ! static short_score scoreboard_image[HARD_SERVER_LIMIT]; static int have_scoreboard_fname = 0; static int scoreboard_fd; --- 609,620 ---- fprintf(stderr, "httpd: Could not move break back\n"); } #endif + scoreboard_image->global.exit_generation=0; } #else ! static scoreboard _scoreboard_image; ! static scoreboard *scoreboard_image=&_scoreboard_image; static int have_scoreboard_fname = 0; static int scoreboard_fd; *************** *** 649,660 **** /* Called by parent process */ void reinit_scoreboard (pool *p) { #if defined(HAVE_SHMGET) || defined(HAVE_MMAP) if (scoreboard_image == NULL) { setup_shared_mem(); } ! memset(scoreboard_image, 0, HARD_SERVER_LIMIT*sizeof(short_score)); #else scoreboard_fname = server_root_relative (p, scoreboard_fname); --- 652,668 ---- /* Called by parent process */ void reinit_scoreboard (pool *p) { + int exit_gen=0; + if(scoreboard_image) + exit_gen=scoreboard_image->global.exit_generation; + #if defined(HAVE_SHMGET) || defined(HAVE_MMAP) if (scoreboard_image == NULL) { setup_shared_mem(); } ! memset(scoreboard_image, 0, SCOREBOARD_SIZE); ! scoreboard_image->global.exit_generation=exit_gen; #else scoreboard_fname = server_root_relative (p, scoreboard_fname); *************** *** 673,681 **** exit (1); } ! memset ((char*)scoreboard_image, 0, sizeof(scoreboard_image)); force_write (scoreboard_fd, (char*)scoreboard_image, ! sizeof(scoreboard_image)); #endif } --- 681,690 ---- exit (1); } ! memset ((char*)scoreboard_image, 0, sizeof(*scoreboard_image)); ! scoreboard_image->global.exit_generation=exit_gen; force_write (scoreboard_fd, (char*)scoreboard_image, ! sizeof(*scoreboard_image)); #endif } *************** *** 723,729 **** #if !defined(HAVE_MMAP) && !defined(HAVE_SHMGET) lseek (scoreboard_fd, 0L, 0); force_read (scoreboard_fd, (char*)scoreboard_image, ! sizeof(scoreboard_image)); #endif } --- 732,738 ---- #if !defined(HAVE_MMAP) && !defined(HAVE_SHMGET) lseek (scoreboard_fd, 0L, 0); force_read (scoreboard_fd, (char*)scoreboard_image, ! sizeof(*scoreboard_image)); #endif } *************** *** 735,741 **** if (child_num < 0) return -1; ! memcpy(&new_score_rec,&scoreboard_image[child_num],sizeof new_score_rec); new_score_rec.pid = getpid(); old_status = new_score_rec.status; new_score_rec.status = status; --- 744,750 ---- if (child_num < 0) return -1; ! memcpy(&new_score_rec,&scoreboard_image->servers[child_num],sizeof new_score_rec); new_score_rec.pid = getpid(); old_status = new_score_rec.status; new_score_rec.status = status; *************** *** 767,773 **** #endif #if defined(HAVE_MMAP) || defined(HAVE_SHMGET) ! memcpy(&scoreboard_image[child_num], &new_score_rec, sizeof(short_score)); #else lseek (scoreboard_fd, (long)child_num * sizeof(short_score), 0); force_write (scoreboard_fd, (char*)&new_score_rec, sizeof(short_score)); --- 776,782 ---- #endif #if defined(HAVE_MMAP) || defined(HAVE_SHMGET) ! memcpy(&scoreboard_image->servers[child_num], &new_score_rec, sizeof new_score_rec); #else lseek (scoreboard_fd, (long)child_num * sizeof(short_score), 0); force_write (scoreboard_fd, (char*)&new_score_rec, sizeof(short_score)); *************** *** 776,787 **** return old_status; } int get_child_status (int child_num) { if (child_num<0 || child_num>=HARD_SERVER_LIMIT) return -1; else ! return scoreboard_image[child_num].status; } int count_busy_servers () --- 785,806 ---- return old_status; } + void update_scoreboard_global() + { + #if !defined(HAVE_MMAP) && !defined(HAVE_SHMGET) + lseek(scoreboard_fd, + (char *)&scoreboard_image->global-(char *)scoreboard_image,0); + force_write(scoreboard_fd,(char *)&scoreboard_image->global, + sizeof scoreboard_image->global); + #endif + } + int get_child_status (int child_num) { if (child_num<0 || child_num>=HARD_SERVER_LIMIT) return -1; else ! return scoreboard_image->servers[child_num].status; } int count_busy_servers () *************** *** 790,807 **** int res = 0; for (i = 0; i < HARD_SERVER_LIMIT; ++i) ! if (scoreboard_image[i].status == SERVER_BUSY_READ || ! scoreboard_image[i].status == SERVER_BUSY_WRITE || ! scoreboard_image[i].status == SERVER_BUSY_KEEPALIVE || ! scoreboard_image[i].status == SERVER_BUSY_LOG || ! scoreboard_image[i].status == SERVER_BUSY_DNS) ++res; return res; } short_score get_scoreboard_info(int i) { ! return (scoreboard_image[i]); } #if defined(STATUS) --- 809,837 ---- int res = 0; for (i = 0; i < HARD_SERVER_LIMIT; ++i) ! if (scoreboard_image->servers[i].status == SERVER_BUSY_READ || ! scoreboard_image->servers[i].status == SERVER_BUSY_WRITE || ! scoreboard_image->servers[i].status == SERVER_BUSY_KEEPALIVE || ! scoreboard_image->servers[i].status == SERVER_BUSY_LOG || ! scoreboard_image->servers[i].status == SERVER_BUSY_DNS) ++res; return res; } + int count_live_servers() + { + int i; + int res = 0; + + for (i = 0; i < HARD_SERVER_LIMIT; ++i) + if (scoreboard_image->servers[i].status != SERVER_DEAD) + ++res; + return res; + } + short_score get_scoreboard_info(int i) { ! return (scoreboard_image->servers[i]); } #if defined(STATUS) *************** *** 845,852 **** int res = 0; for (i = 0; i < HARD_SERVER_LIMIT; ++i) ! if (scoreboard_image[i].status == SERVER_READY ! || scoreboard_image[i].status == SERVER_STARTING) ++res; return res; --- 875,882 ---- int res = 0; for (i = 0; i < HARD_SERVER_LIMIT; ++i) ! if (scoreboard_image->servers[i].status == SERVER_READY ! || scoreboard_image->servers[i].status == SERVER_STARTING) ++res; return res; *************** *** 857,863 **** int i; for (i = 0; i < HARD_SERVER_LIMIT; ++i) ! if (scoreboard_image[i].status == SERVER_DEAD) return i; return -1; --- 887,893 ---- int i; for (i = 0; i < HARD_SERVER_LIMIT; ++i) ! if (scoreboard_image->servers[i].status == SERVER_DEAD) return i; return -1; *************** *** 868,874 **** int i; for (i = 0; i < HARD_SERVER_LIMIT; ++i) ! if (scoreboard_image[i].pid == pid) return i; return -1; --- 898,904 ---- int i; for (i = 0; i < HARD_SERVER_LIMIT; ++i) ! if (scoreboard_image->servers[i].pid == pid) return i; return -1; *************** *** 881,890 **** sync_scoreboard_image(); for (i = 0; i < HARD_SERVER_LIMIT; ++i) { ! int pid = scoreboard_image[i].pid; if (pid != my_pid && pid != 0) ! waitpid (scoreboard_image[i].pid, &status, 0); } } --- 911,920 ---- sync_scoreboard_image(); for (i = 0; i < HARD_SERVER_LIMIT; ++i) { ! int pid = scoreboard_image->servers[i].pid; if (pid != my_pid && pid != 0) ! waitpid (scoreboard_image->servers[i].pid, &status, 0); } } *************** *** 1053,1068 **** } } void restart() { signal (SIGALRM, SIG_IGN); alarm (0); ! #if defined(NEXT) || defined(USE_LONGJMP) longjmp(restart_buffer,1); #else siglongjmp(restart_buffer,1); #endif } void set_signals() { #ifndef NO_USE_SIGACTION struct sigaction sa; --- 1083,1114 ---- } } + static int is_graceful; + static int generation; + void restart() { signal (SIGALRM, SIG_IGN); alarm (0); ! is_graceful=0; ! #ifdef NEXT longjmp(restart_buffer,1); #else siglongjmp(restart_buffer,1); #endif } + void graceful_restart() + { + scoreboard_image->global.exit_generation=generation; + is_graceful=1; + update_scoreboard_global(); + #if defined(NEXT) || defined(USE_LONGJMP) + longjmp(restart_buffer,1); + #else + siglongjmp(restart_buffer,1); + #endif + } + void set_signals() { #ifndef NO_USE_SIGACTION struct sigaction sa; *************** *** 1075,1080 **** --- 1121,1127 ---- #ifdef NO_USE_SIGACTION signal(SIGTERM,(void (*)())sig_term); signal(SIGHUP,(void (*)())restart); + signal(SIGINT,(void (*)())graceful_restart); #else memset(&sa,0,sizeof sa); sa.sa_handler=(void (*)())sig_term; *************** *** 1083,1088 **** --- 1130,1138 ---- sa.sa_handler=(void (*)())restart; if(sigaction(SIGHUP,&sa,NULL) < 0) log_unixerr("sigaction(SIGHUP)", NULL, NULL, server_conf); + sa.sa_handler=(void (*)())graceful_restart; + if(sigaction(SIGINT,&sa,NULL) < 0) + log_unixerr("sigaction(SIGINT)", NULL, NULL, server_conf); #endif } *************** *** 1235,1240 **** --- 1285,1294 ---- clear_pool (ptrans); sync_scoreboard_image(); + + /*fprintf(stderr,"%d check %d %d\n",getpid(),scoreboard_image->global.exit_generation,generation);*/ + if(scoreboard_image->global.exit_generation >= generation) + exit(0); if ((count_idle_servers() >= daemons_max_free) || (max_requests_per_child > 0 *************** *** 1261,1266 **** --- 1315,1325 ---- #endif if (csd == -1 && errno != EINTR) log_unixerr("select",NULL,"select error", server_conf); + + /*fprintf(stderr,"%d check(2a) %d %d\n",getpid(),scoreboard_image->global.exit_generation,generation);*/ + if(scoreboard_image->global.exit_generation >= generation) + exit(0); + if (csd <= 0) continue; for (sd=listenmaxfd; sd >= 0; sd--) if (FD_ISSET(sd, &fds)) break; *************** *** 1273,1281 **** --- 1332,1360 ---- log_unixerr("accept", "(client socket)", NULL, server_conf); } } else + { + fd_set fds; + + memset(&fds,0,sizeof fds); + FD_SET(sd,&fds); + + do + csd = select(sd+1, &fds, NULL, NULL, NULL); + while(csd < 0 && errno == EINTR); + + if(csd < 0) + { + log_unixerr("select","(listen)",NULL,server_conf); + exit(0); + } + /*fprintf(stderr,"%d check(2a) %d %d\n",getpid(),scoreboard_image->global.exit_generation,generation);*/ + if(scoreboard_image->global.exit_generation >= generation) + exit(0); + while ((csd=accept(sd, &sa_client, &clen)) == -1) if (errno != EINTR) log_unixerr("accept",NULL,"socket error: accept failed", server_conf); + } accept_mutex_off(); /* unlock after "accept" */ *************** *** 1318,1323 **** --- 1397,1407 ---- #if defined(STATUS) if (r) increment_counts(child_num,r,0); #endif + sync_scoreboard_image(); + if(scoreboard_image->global.exit_generation >= generation) + exit(0); + /*fprintf(stderr,"%d check(3) %d %d\n",getpid(),scoreboard_image->global.exit_generation,generation);*/ + } #if 0 if (bytes_in_pool (ptrans) > 80000) *************** *** 1373,1379 **** exit(1); } ! note_cleanups_for_fd (pconf, s); /* arrange to close on exec or restart */ if((setsockopt(s, SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one))) == -1) { --- 1457,1463 ---- exit(1); } ! /* note_cleanups_for_fd (pconf, s); /* arrange to close on exec or restart */ if((setsockopt(s, SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one))) == -1) { *************** *** 1423,1428 **** --- 1507,1555 ---- return s; } + static listen_rec *old_listeners; + + static void copy_listeners() + { + listen_rec *lr; + + assert(old_listeners == NULL); + for(lr=listeners ; lr ; lr=lr->next) + { + listen_rec *nr=malloc(sizeof *nr); + *nr=*lr; + nr->next=old_listeners; + assert(!nr->used); + old_listeners=nr; + } + } + + static int find_listener(listen_rec *lr) + { + listen_rec *or; + + for(or=old_listeners ; or ; or=or->next) + if(!memcmp(&or->local_addr,&lr->local_addr,sizeof or->local_addr)) + { + or->used=1; + return or->fd; + } + return -1; + } + + static void close_unused_listeners() + { + listen_rec *or,*next; + + for(or=old_listeners ; or ; or=next) + { + next=or->next; + if(!or->used) + close(or->fd); + free(or); + } + old_listeners=NULL; + } /***************************************************************** * Executive routines. *************** *** 1433,1438 **** --- 1560,1566 ---- void standalone_main(int argc, char **argv) { struct sockaddr_in sa_server; + int saved_sd; standalone = 1; sd = listenmaxfd = -1; *************** *** 1445,1453 **** sigsetjmp(restart_buffer,1); #endif signal (SIGHUP, SIG_IGN); /* Until we're done (re)reading config */ ! if(!one_process) { #ifndef NO_KILLPG if (killpg(pgrp,SIGHUP) < 0) /* Kill 'em off */ --- 1573,1583 ---- sigsetjmp(restart_buffer,1); #endif + ++generation; + signal (SIGHUP, SIG_IGN); /* Until we're done (re)reading config */ ! if(!one_process && !is_graceful) { #ifndef NO_KILLPG if (killpg(pgrp,SIGHUP) < 0) /* Kill 'em off */ *************** *** 1457,1467 **** log_unixerr ("killpg SIGHUP", NULL, NULL, server_conf); } ! if (sd != -1 || listenmaxfd != -1) { reclaim_child_processes(); /* Not when just starting up */ log_error ("SIGHUP received. Attempting to restart", server_conf); } restart_time = time(NULL); clear_pool (pconf); ptrans = make_sub_pool (pconf); --- 1587,1601 ---- log_unixerr ("killpg SIGHUP", NULL, NULL, server_conf); } ! if(is_graceful) ! log_error("SIGINT received. Doing graceful restart",server_conf); ! else if (sd != -1 || listenmaxfd != -1) { reclaim_child_processes(); /* Not when just starting up */ log_error ("SIGHUP received. Attempting to restart", server_conf); } + copy_listeners(); + saved_sd=sd; restart_time = time(NULL); clear_pool (pconf); ptrans = make_sub_pool (pconf); *************** *** 1476,1487 **** if (listeners == NULL) { ! memset((char *) &sa_server, 0, sizeof(sa_server)); ! sa_server.sin_family=AF_INET; ! sa_server.sin_addr=bind_address; ! sa_server.sin_port=htons(server_conf->port); ! sd = make_sock(pconf, &sa_server); } else { listen_rec *lr; --- 1610,1626 ---- if (listeners == NULL) { ! if(!is_graceful) ! { ! memset((char *) &sa_server, 0, sizeof(sa_server)); ! sa_server.sin_family=AF_INET; ! sa_server.sin_addr=bind_address; ! sa_server.sin_port=htons(server_conf->port); ! sd = make_sock(pconf, &sa_server); ! } ! else ! sd=saved_sd; } else { listen_rec *lr; *************** *** 1491,1500 **** FD_ZERO(&listenfds); for (lr=listeners; lr != NULL; lr=lr->next) { ! fd = make_sock(pconf, &lr->local_addr); FD_SET(fd, &listenfds); if (fd > listenmaxfd) listenmaxfd = fd; } sd = -1; } --- 1630,1643 ---- FD_ZERO(&listenfds); for (lr=listeners; lr != NULL; lr=lr->next) { ! fd=find_listener(lr); ! if(fd < 0) ! fd = make_sock(pconf, &lr->local_addr); FD_SET(fd, &listenfds); if (fd > listenmaxfd) listenmaxfd = fd; + lr->fd=fd; } + close_unused_listeners(); sd = -1; } *************** *** 1532,1538 **** --- 1675,1691 ---- (void)update_child_status(child_slot,SERVER_STARTING, (request_rec*)NULL); make_child(server_conf, child_slot); + } + + /* + if(scoreboard_image->global.please_exit && !count_live_servers()) + #ifdef NEXT + longjmp(restart_buffer,1); + #else + siglongjmp(restart_buffer,1); + #endif + */ } } /* standalone_main */ 1.38 +2 -0 apache/src/httpd.h Index: httpd.h =================================================================== RCS file: /export/home/cvs/apache/src/httpd.h,v retrieving revision 1.37 retrieving revision 1.38 diff -C3 -r1.37 -r1.38 *** httpd.h 1996/07/03 22:58:45 1.37 --- httpd.h 1996/07/16 19:39:14 1.38 *************** *** 498,503 **** --- 498,505 ---- struct listen_rec { listen_rec *next; struct sockaddr_in local_addr; /* local IP address and port */ + int fd; + int used; /* Only used during restart */ /* more stuff here, like which protocol is bound to the port */ }; 1.14 +15 -0 apache/src/scoreboard.h Index: scoreboard.h =================================================================== RCS file: /export/home/cvs/apache/src/scoreboard.h,v retrieving revision 1.13 retrieving revision 1.14 diff -C3 -r1.13 -r1.14 *** scoreboard.h 1996/07/13 01:47:38 1.13 --- scoreboard.h 1996/07/16 19:39:14 1.14 *************** *** 91,95 **** --- 91,110 ---- #endif } short_score; + typedef struct + { + int exit_generation; /* Set by the main process if a graceful + restart is required */ + } global_score; + + typedef struct + { + short_score servers[HARD_SERVER_LIMIT]; + global_score global; + } scoreboard; + + #define SCOREBOARD_SIZE sizeof(scoreboard) + extern void sync_scoreboard_image(void); short_score get_scoreboard_info(int x); +