]> granicus.if.org Git - apache/blob - server/mpm/mpmt_pthread/mpmt_pthread.c
Port the scoreboard from the mpmt_pthread MPM to use APR's shared memory.
[apache] / server / mpm / mpmt_pthread / mpmt_pthread.c
1 /* ====================================================================
2  * Copyright (c) 1995-1999 The Apache Group.  All rights reserved.
3  * 
4  * Redistribution and use in source and binary forms, with or without 
5  * modification, are permitted provided that the following conditions 
6  * are met: 
7  * 
8  * 1. Redistributions of source code must retain the above copyright 
9  *    notice, this list of conditions and the following disclaimer.  
10  * 
11  * 2. Redistributions in binary form must reproduce the above copyright 
12  *    notice, this list of conditions and the following disclaimer in 
13  *    the documentation and/or other materials provided with the 
14  *    distribution. 
15  * 
16  * 3. All advertising materials mentioning features or use of this 
17  *    software must display the following acknowledgment: 
18  *    "This product includes software developed by the Apache Group 
19  *    for use in the Apache HTTP server project (http://www.apache.org/)." 
20  * 
21  * 4. The names "Apache Server" and "Apache Group" must not be used to 
22  *    endorse or promote products derived from this software without 
23  *    prior written permission. For written permission, please contact 
24  *    apache@apache.org. 
25  * 
26  * 5. Products derived from this software may not be called "Apache" 
27  *    nor may "Apache" appear in their names without prior written 
28  *    permission of the Apache Group. 
29  * 
30  * 6. Redistributions of any form whatsoever must retain the following 
31  *    acknowledgment: 
32  *    "This product includes software developed by the Apache Group 
33  *    for use in the Apache HTTP server project (http://www.apache.org/)." 
34  * 
35  * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY 
36  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
37  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
38  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR 
39  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
40  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
41  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
42  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
43  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
44  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
45  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
46  * OF THE POSSIBILITY OF SUCH DAMAGE. 
47  * ==================================================================== 
48  * 
49  * This software consists of voluntary contributions made by many 
50  * individuals on behalf of the Apache Group and was originally based 
51  * on public domain software written at the National Center for 
52  * Supercomputing Applications, University of Illinois, Urbana-Champaign. 
53  * For more information on the Apache Group and the Apache HTTP server 
54  * project, please see <http://www.apache.org/>. 
55  * 
56  */ 
57  
58 #define CORE_PRIVATE 
59  
60 #include "apr_portable.h"
61 #include "apr_thread_proc.h"
62 #include "ap_config.h"
63 #include "httpd.h" 
64 #include "http_main.h" 
65 #include "http_log.h" 
66 #include "http_config.h"        /* for read_config */ 
67 #include "http_core.h"          /* for get_remote_host */ 
68 #include "http_connection.h"
69 #include "ap_mpm.h"
70 #include "unixd.h"
71 #include "iol_socket.h"
72 #include "ap_listen.h"
73 #include "scoreboard.h" 
74
75 #include <netinet/tcp.h> 
76 #include <sys/wait.h> 
77 #include <pthread.h>
78 #include <signal.h>
79
80 /*
81  * Actual definitions of config globals
82  */
83
84 int ap_threads_per_child=0;         /* Worker threads per child */
85 int ap_max_requests_per_child=0;
86 static char *ap_pid_fname=NULL;
87 API_VAR_EXPORT char *ap_scoreboard_fname=NULL;
88 static int ap_daemons_to_start=0;
89 static int min_spare_threads=0;
90 static int max_spare_threads=0;
91 static int ap_daemons_limit=0;
92 static time_t ap_restart_time=0;
93 API_VAR_EXPORT int ap_extended_status = 0;
94 static int workers_may_exit = 0;
95 static int requests_this_child;
96 static int num_listensocks = 0;
97 static ap_socket_t **listensocks;
98
99 /* The structure used to pass unique initialization info to each thread */
100 typedef struct {
101     int pid;
102     int tid;
103     int sd;
104     ap_context_t *tpool; /* "pthread" would be confusing */
105 } proc_info;
106
107 /*
108  * The max child slot ever assigned, preserved across restarts.  Necessary
109  * to deal with MaxClients changes across SIGWINCH restarts.  We use this
110  * value to optimize routines that have to scan the entire scoreboard.
111  */
112 static int max_daemons_limit = -1;
113
114 static char ap_coredump_dir[MAX_STRING_LEN];
115
116 static int pipe_of_death[2];
117 static pthread_mutex_t pipe_of_death_mutex;
118
119 /* *Non*-shared http_main globals... */
120
121 static server_rec *server_conf;
122
123 /* one_process --- debugging mode variable; can be set from the command line
124  * with the -X flag.  If set, this gets you the child_main loop running
125  * in the process which originally started up (no detach, no make_child),
126  * which is a pretty nice debugging environment.  (You'll get a SIGHUP
127  * early in standalone_main; just continue through.  This is the server
128  * trying to kill off any child processes which it might have lying
129  * around --- Apache doesn't keep track of their pids, it just sends
130  * SIGHUP to the process group, ignoring it in the root process.
131  * Continue through and you'll be fine.).
132  */
133
134 static int one_process = 0;
135
136 #ifdef DEBUG_SIGSTOP
137 int raise_sigstop_flags;
138 #endif
139
140 #ifdef HAS_OTHER_CHILD
141 /* used to maintain list of children which aren't part of the scoreboard */
142 typedef struct other_child_rec other_child_rec;
143 struct other_child_rec {
144     other_child_rec *next;
145     int pid;
146     void (*maintenance) (int, void *, ap_wait_t);
147     void *data;
148     int write_fd;
149 };
150 static other_child_rec *other_children;
151 #endif
152
153 static ap_context_t *pconf;             /* Pool for config stuff */
154 static ap_context_t *pchild;            /* Pool for httpd child stuff */
155
156 static int my_pid; /* Linux getpid() doesn't work except in main thread. Use
157                       this instead */
158 /* Keep track of the number of worker threads currently active */
159 static int worker_thread_count;
160 static pthread_mutex_t worker_thread_count_mutex;
161
162 /* Locks for accept serialization */
163 static pthread_mutex_t thread_accept_mutex = PTHREAD_MUTEX_INITIALIZER;
164 static ap_lock_t *process_accept_mutex;
165 static char *lock_fname;
166
167 #ifdef NO_SERIALIZED_ACCEPT
168 #define SAFE_ACCEPT(stmt) APR_SUCCESS
169 #else
170 #define SAFE_ACCEPT(stmt) (stmt)
171 #endif
172
173
174 /* Global, alas, so http_core can talk to us */
175 enum server_token_type ap_server_tokens = SrvTk_FULL;
176
177 API_EXPORT(const server_rec *) ap_get_server_conf(void)
178 {
179     return (server_conf);
180 }
181
182 API_EXPORT(int) ap_get_max_daemons(void)
183 {
184     return max_daemons_limit;
185 }
186
187 /* a clean exit from a child with proper cleanup */ 
188 static void clean_child_exit(int code) __attribute__ ((noreturn));
189 void clean_child_exit(int code)
190 {
191     if (pchild) {
192         ap_destroy_pool(pchild);
193     }
194     exit(code);
195 }
196
197 /*****************************************************************
198  * dealing with other children
199  */
200
201 #ifdef HAS_OTHER_CHILD
202 API_EXPORT(void) ap_register_other_child(int pid,
203                        void (*maintenance) (int reason, void *, ap_wait_t status),
204                           void *data, int write_fd)
205 {
206     other_child_rec *ocr;
207
208     ocr = ap_palloc(pconf, sizeof(*ocr));
209     ocr->pid = pid;
210     ocr->maintenance = maintenance;
211     ocr->data = data;
212     ocr->write_fd = write_fd;
213     ocr->next = other_children;
214     other_children = ocr;
215 }
216
217 /* note that since this can be called by a maintenance function while we're
218  * scanning the other_children list, all scanners should protect themself
219  * by loading ocr->next before calling any maintenance function.
220  */
221 API_EXPORT(void) ap_unregister_other_child(void *data)
222 {
223     other_child_rec **pocr, *nocr;
224
225     for (pocr = &other_children; *pocr; pocr = &(*pocr)->next) {
226         if ((*pocr)->data == data) {
227             nocr = (*pocr)->next;
228             (*(*pocr)->maintenance) (OC_REASON_UNREGISTER, (*pocr)->data, -1);
229             *pocr = nocr;
230             /* XXX: um, well we've just wasted some space in pconf ? */
231             return;
232         }
233     }
234 }
235
236 /* test to ensure that the write_fds are all still writable, otherwise
237  * invoke the maintenance functions as appropriate */
238 static void probe_writable_fds(void)
239 {
240     return;
241 #if 0
242     fd_set writable_fds;
243     int fd_max;
244     other_child_rec *ocr, *nocr;
245     struct timeval tv;
246     int rc;
247
248     if (other_children == NULL)
249         return;
250
251     fd_max = 0;
252     FD_ZERO(&writable_fds);
253     do {
254         for (ocr = other_children; ocr; ocr = ocr->next) {
255             if (ocr->write_fd == -1)
256                 continue;
257             FD_SET(ocr->write_fd, &writable_fds);
258             if (ocr->write_fd > fd_max) {
259                 fd_max = ocr->write_fd;
260             }
261         }
262         if (fd_max == 0)
263             return;
264
265         tv.tv_sec = 0;
266         tv.tv_usec = 0;
267         rc = ap_select(fd_max + 1, NULL, &writable_fds, NULL, &tv);
268     } while (rc == -1 && errno == EINTR);
269
270     if (rc == -1) {
271         /* XXX: uhh this could be really bad, we could have a bad file
272          * descriptor due to a bug in one of the maintenance routines */
273         ap_log_unixerr("probe_writable_fds", "select",
274                     "could not probe writable fds", server_conf);
275         return;
276     }
277     if (rc == 0)
278         return;
279
280     for (ocr = other_children; ocr; ocr = nocr) {
281         nocr = ocr->next;
282         if (ocr->write_fd == -1)
283             continue;
284         if (FD_ISSET(ocr->write_fd, &writable_fds))
285             continue;
286         (*ocr->maintenance) (OC_REASON_UNWRITABLE, ocr->data, -1);
287     }
288 #endif
289 }
290
291 /* possibly reap an other_child, return 0 if yes, -1 if not */
292 static int reap_other_child(int pid, ap_wait_t status)
293 {
294     other_child_rec *ocr, *nocr;
295
296     for (ocr = other_children; ocr; ocr = nocr) {
297         nocr = ocr->next;
298         if (ocr->pid != pid)
299             continue;
300         ocr->pid = -1;
301         (*ocr->maintenance) (OC_REASON_DEATH, ocr->data, status);
302         return 0;
303     }
304     return -1;
305 }
306 #endif
307
308 static void reclaim_child_processes(int terminate)
309 {
310     int i, status;
311     long int waittime = 1024 * 16;      /* in usecs */
312     struct timeval tv;
313     int waitret, tries;
314     int not_dead_yet;
315 #ifdef HAS_OTHER_CHILD
316     other_child_rec *ocr, *nocr;
317 #endif
318
319     ap_sync_scoreboard_image();
320
321     for (tries = terminate ? 4 : 1; tries <= 9; ++tries) {
322         /* don't want to hold up progress any more than 
323          * necessary, but we need to allow children a few moments to exit.
324          * Set delay with an exponential backoff.
325          */
326         tv.tv_sec = waittime / 1000000;
327         tv.tv_usec = waittime % 1000000;
328         waittime = waittime * 4;
329         ap_select(0, NULL, NULL, NULL, &tv);
330
331         /* now see who is done */
332         not_dead_yet = 0;
333         for (i = 0; i < max_daemons_limit; ++i) {
334             int pid = ap_scoreboard_image->parent[i].pid;
335
336             if (pid == my_pid || pid == 0)
337                 continue;
338
339             waitret = waitpid(pid, &status, WNOHANG);
340             if (waitret == pid || waitret == -1) {
341                 ap_scoreboard_image->parent[i].pid = 0;
342                 continue;
343             }
344             ++not_dead_yet;
345             switch (tries) {
346             case 1:     /*  16ms */
347             case 2:     /*  82ms */
348                 break;
349             case 3:     /* 344ms */
350             case 4:     /*  16ms */
351             case 5:     /*  82ms */
352             case 6:     /* 344ms */
353             case 7:     /* 1.4sec */
354                 /* ok, now it's being annoying */
355                 ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING,
356                             0, server_conf,
357                    "child process %d still did not exit, sending a SIGTERM",
358                             pid);
359                 kill(pid, SIGTERM);
360                 break;
361             case 8:     /*  6 sec */
362                 /* die child scum */
363                 ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, server_conf,
364                    "child process %d still did not exit, sending a SIGKILL",
365                             pid);
366                 kill(pid, SIGKILL);
367                 break;
368             case 9:     /* 14 sec */
369                 /* gave it our best shot, but alas...  If this really 
370                  * is a child we are trying to kill and it really hasn't
371                  * exited, we will likely fail to bind to the port
372                  * after the restart.
373                  */
374                 ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, server_conf,
375                             "could not make child process %d exit, "
376                             "attempting to continue anyway", pid);
377                 break;
378             }
379         }
380 #ifdef HAS_OTHER_CHILD
381         for (ocr = other_children; ocr; ocr = nocr) {
382             nocr = ocr->next;
383             if (ocr->pid == -1)
384                 continue;
385
386             waitret = waitpid(ocr->pid, &status, WNOHANG);
387             if (waitret == ocr->pid) {
388                 ocr->pid = -1;
389                 (*ocr->maintenance) (OC_REASON_DEATH, ocr->data, status);
390             }
391             else if (waitret == 0) {
392                 (*ocr->maintenance) (OC_REASON_RESTART, ocr->data, -1);
393                 ++not_dead_yet;
394             }
395             else if (waitret == -1) {
396                 /* uh what the heck? they didn't call unregister? */
397                 ocr->pid = -1;
398                 (*ocr->maintenance) (OC_REASON_LOST, ocr->data, -1);
399             }
400         }
401 #endif
402         if (!not_dead_yet) {
403             /* nothing left to wait for */
404             break;
405         }
406     }
407 }
408
409 /* Finally, this routine is used by the caretaker process to wait for
410  * a while...
411  */
412
413 /* number of calls to wait_or_timeout between writable probes */
414 #ifndef INTERVAL_OF_WRITABLE_PROBES
415 #define INTERVAL_OF_WRITABLE_PROBES 10
416 #endif
417 static int wait_or_timeout_counter;
418
419 static int wait_or_timeout(ap_wait_t *status)
420 {
421     struct timeval tv;
422     int ret;
423
424     ++wait_or_timeout_counter;
425     if (wait_or_timeout_counter == INTERVAL_OF_WRITABLE_PROBES) {
426         wait_or_timeout_counter = 0;
427 #ifdef HAS_OTHER_CHILD
428         probe_writable_fds();
429 #endif
430     }
431     ret = waitpid(-1, status, WNOHANG);
432     if (ret == -1 && errno == EINTR) {
433         return -1;
434     }
435     if (ret > 0) {
436         return ret;
437     }
438     tv.tv_sec = SCOREBOARD_MAINTENANCE_INTERVAL / 1000000;
439     tv.tv_usec = SCOREBOARD_MAINTENANCE_INTERVAL % 1000000;
440     ap_select(0, NULL, NULL, NULL, &tv);
441     return -1;
442 }
443
444 /* handle all varieties of core dumping signals */
445 static void sig_coredump(int sig)
446 {
447     chdir(ap_coredump_dir);
448     signal(sig, SIG_DFL);
449     kill(my_pid, sig);
450     /* At this point we've got sig blocked, because we're still inside
451      * the signal handler.  When we leave the signal handler it will
452      * be unblocked, and we'll take the signal... and coredump or whatever
453      * is appropriate for this particular Unix.  In addition the parent
454      * will see the real signal we received -- whereas if we called
455      * abort() here, the parent would only see SIGABRT.
456      */
457 }
458
459 static void just_die(int sig)
460 {
461     clean_child_exit(0);
462 }
463
464 /*****************************************************************
465  * Connection structures and accounting...
466  */
467
468 /* volatile just in case */
469 static int volatile shutdown_pending;
470 static int volatile restart_pending;
471 static int volatile is_graceful;
472 ap_generation_t volatile ap_my_generation;
473
474 /*
475  * ap_start_shutdown() and ap_start_restart(), below, are a first stab at
476  * functions to initiate shutdown or restart without relying on signals. 
477  * Previously this was initiated in sig_term() and restart() signal handlers, 
478  * but we want to be able to start a shutdown/restart from other sources --
479  * e.g. on Win32, from the service manager. Now the service manager can
480  * call ap_start_shutdown() or ap_start_restart() as appropiate.  Note that
481  * these functions can also be called by the child processes, since global
482  * variables are no longer used to pass on the required action to the parent.
483  *
484  * These should only be called from the parent process itself, since the
485  * parent process will use the shutdown_pending and restart_pending variables
486  * to determine whether to shutdown or restart. The child process should
487  * call signal_parent() directly to tell the parent to die -- this will
488  * cause neither of those variable to be set, which the parent will
489  * assume means something serious is wrong (which it will be, for the
490  * child to force an exit) and so do an exit anyway.
491  */
492
493 void ap_start_shutdown(void)
494 {
495     if (shutdown_pending == 1) {
496         /* Um, is this _probably_ not an error, if the user has
497          * tried to do a shutdown twice quickly, so we won't
498          * worry about reporting it.
499          */
500         return;
501     }
502     shutdown_pending = 1;
503 }
504
505 /* do a graceful restart if graceful == 1 */
506 void ap_start_restart(int graceful)
507 {
508
509     if (restart_pending == 1) {
510         /* Probably not an error - don't bother reporting it */
511         return;
512     }
513     restart_pending = 1;
514     is_graceful = graceful;
515 }
516
517 static void sig_term(int sig)
518 {
519     ap_start_shutdown();
520 }
521
522 static void restart(int sig)
523 {
524 #ifndef WIN32
525     ap_start_restart(sig == SIGWINCH);
526 #else
527     ap_start_restart(1);
528 #endif
529 }
530
531 static void set_signals(void)
532 {
533 #ifndef NO_USE_SIGACTION
534     struct sigaction sa;
535
536     sigemptyset(&sa.sa_mask);
537     sa.sa_flags = 0;
538
539     if (!one_process) {
540         sa.sa_handler = sig_coredump;
541 #if defined(SA_ONESHOT)
542         sa.sa_flags = SA_ONESHOT;
543 #elif defined(SA_RESETHAND)
544         sa.sa_flags = SA_RESETHAND;
545 #endif
546         if (sigaction(SIGSEGV, &sa, NULL) < 0)
547             ap_log_error(APLOG_MARK, APLOG_WARNING, errno, server_conf, "sigaction(SIGSEGV)");
548 #ifdef SIGBUS
549         if (sigaction(SIGBUS, &sa, NULL) < 0)
550             ap_log_error(APLOG_MARK, APLOG_WARNING, errno, server_conf, "sigaction(SIGBUS)");
551 #endif
552 #ifdef SIGABORT
553         if (sigaction(SIGABORT, &sa, NULL) < 0)
554             ap_log_error(APLOG_MARK, APLOG_WARNING, errno, server_conf, "sigaction(SIGABORT)");
555 #endif
556 #ifdef SIGABRT
557         if (sigaction(SIGABRT, &sa, NULL) < 0)
558             ap_log_error(APLOG_MARK, APLOG_WARNING, errno, server_conf, "sigaction(SIGABRT)");
559 #endif
560 #ifdef SIGILL
561         if (sigaction(SIGILL, &sa, NULL) < 0)
562             ap_log_error(APLOG_MARK, APLOG_WARNING, errno, server_conf, "sigaction(SIGILL)");
563 #endif
564         sa.sa_flags = 0;
565     }
566     sa.sa_handler = sig_term;
567     if (sigaction(SIGTERM, &sa, NULL) < 0)
568         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, server_conf, "sigaction(SIGTERM)");
569 #ifdef SIGINT
570     if (sigaction(SIGINT, &sa, NULL) < 0)
571         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, server_conf, "sigaction(SIGINT)");
572 #endif
573 #ifdef SIGXCPU
574     sa.sa_handler = SIG_DFL;
575     if (sigaction(SIGXCPU, &sa, NULL) < 0)
576         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, server_conf, "sigaction(SIGXCPU)");
577 #endif
578 #ifdef SIGXFSZ
579     sa.sa_handler = SIG_DFL;
580     if (sigaction(SIGXFSZ, &sa, NULL) < 0)
581         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, server_conf, "sigaction(SIGXFSZ)");
582 #endif
583 #ifdef SIGPIPE
584     sa.sa_handler = SIG_IGN;
585     if (sigaction(SIGPIPE, &sa, NULL) < 0)
586         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, server_conf, "sigaction(SIGPIPE)");
587 #endif
588
589     /* we want to ignore HUPs and WINCH while we're busy processing one */
590     sigaddset(&sa.sa_mask, SIGHUP);
591     sigaddset(&sa.sa_mask, SIGWINCH);
592     sa.sa_handler = restart;
593     if (sigaction(SIGHUP, &sa, NULL) < 0)
594         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, server_conf, "sigaction(SIGHUP)");
595     if (sigaction(SIGWINCH, &sa, NULL) < 0)
596         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, server_conf, "sigaction(SIGWINCH)");
597 #else
598     if (!one_process) {
599         signal(SIGSEGV, sig_coredump);
600 #ifdef SIGBUS
601         signal(SIGBUS, sig_coredump);
602 #endif /* SIGBUS */
603 #ifdef SIGABORT
604         signal(SIGABORT, sig_coredump);
605 #endif /* SIGABORT */
606 #ifdef SIGABRT
607         signal(SIGABRT, sig_coredump);
608 #endif /* SIGABRT */
609 #ifdef SIGILL
610         signal(SIGILL, sig_coredump);
611 #endif /* SIGILL */
612 #ifdef SIGXCPU
613         signal(SIGXCPU, SIG_DFL);
614 #endif /* SIGXCPU */
615 #ifdef SIGXFSZ
616         signal(SIGXFSZ, SIG_DFL);
617 #endif /* SIGXFSZ */
618     }
619
620     signal(SIGTERM, sig_term);
621 #ifdef SIGHUP
622     signal(SIGHUP, restart);
623 #endif /* SIGHUP */
624 #ifdef SIGWINCH
625     signal(SIGWINCH, restart);
626 #endif /* SIGWINCH */
627 #ifdef SIGPIPE
628     signal(SIGPIPE, SIG_IGN);
629 #endif /* SIGPIPE */
630
631 #endif
632 }
633
634 static void process_child_status(int pid, ap_wait_t status)
635 {
636     /* Child died... if it died due to a fatal error,
637         * we should simply bail out.
638         */
639     if ((WIFEXITED(status)) &&
640         WEXITSTATUS(status) == APEXIT_CHILDFATAL) {
641         ap_log_error(APLOG_MARK, APLOG_ALERT|APLOG_NOERRNO, 0, server_conf,
642                         "Child %d returned a Fatal error... \n"
643                         "Apache is exiting!",
644                         pid);
645         exit(APEXIT_CHILDFATAL);
646     }
647     if (WIFSIGNALED(status)) {
648         switch (WTERMSIG(status)) {
649         case SIGTERM:
650         case SIGHUP:
651         case SIGUSR1:
652         case SIGKILL:
653             break;
654         default:
655 #ifdef SYS_SIGLIST
656 #ifdef WCOREDUMP
657             if (WCOREDUMP(status)) {
658                 ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE,
659                              0, server_conf,
660                              "child pid %d exit signal %s (%d), "
661                              "possible coredump in %s",
662                              pid, (WTERMSIG(status) >= NumSIG) ? "" : 
663                              SYS_SIGLIST[WTERMSIG(status)], WTERMSIG(status),
664                              ap_coredump_dir);
665             }
666             else {
667 #endif
668                 ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE,
669                              0, server_conf,
670                              "child pid %d exit signal %s (%d)", pid,
671                              SYS_SIGLIST[WTERMSIG(status)], WTERMSIG(status));
672 #ifdef WCOREDUMP
673             }
674 #endif
675 #else
676             ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE,
677                          server_conf,
678                          "child pid %d exit signal %d",
679                          pid, WTERMSIG(status));
680 #endif
681         }
682     }
683 }
684
685 static int setup_listeners(server_rec *s)
686 {
687     ap_listen_rec *lr;
688     int num_listeners = 0;
689     if (ap_listen_open(s->process, s->port)) {
690        return 0;
691     }
692     for (lr = ap_listeners; lr; lr = lr->next) {
693         num_listeners++;
694     }
695     return num_listeners;
696 }
697
698 /*****************************************************************
699  * Here follows a long bunch of generic server bookkeeping stuff...
700  */
701
702 #if defined(TCP_NODELAY) && !defined(MPE) && !defined(TPF)
703 static void sock_disable_nagle(int s) 
704 {
705     /* The Nagle algorithm says that we should delay sending partial
706      * packets in hopes of getting more data.  We don't want to do
707      * this; we are not telnet.  There are bad interactions between
708      * persistent connections and Nagle's algorithm that have very severe
709      * performance penalties.  (Failing to disable Nagle is not much of a
710      * problem with simple HTTP.)
711      *
712      * In spite of these problems, failure here is not a shooting offense.
713      */
714     int just_say_no = 1;
715
716     if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char *) &just_say_no,
717                    sizeof(int)) < 0) {
718         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, server_conf,
719                     "setsockopt: (TCP_NODELAY)");
720     }
721 }
722
723 #else
724 #define sock_disable_nagle(s)   /* NOOP */
725 #endif
726
727 int ap_graceful_stop_signalled(void)
728 {
729     /* XXX - Does this really work? - Manoj */
730     return is_graceful;
731 }
732
733 /*****************************************************************
734  * Child process main loop.
735  */
736
737 static void process_socket(ap_context_t *p, ap_socket_t *sock, int my_child_num, int my_thread_num)
738 {
739     BUFF *conn_io;
740     conn_rec *current_conn;
741     ap_iol *iol;
742     long conn_id = my_child_num * HARD_THREAD_LIMIT + my_thread_num;
743     int csd;
744
745     (void) ap_get_os_sock(&csd, sock);
746
747     sock_disable_nagle(csd);
748
749     iol = unix_attach_socket(sock);
750     if (iol == NULL) {
751         if (errno == EBADF) {
752             ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, NULL,
753                 "filedescriptor (%u) larger than FD_SETSIZE (%u) "
754                 "found, you probably need to rebuild Apache with a "
755                 "larger FD_SETSIZE", csd, FD_SETSIZE);
756         }
757         else {
758             ap_log_error(APLOG_MARK, APLOG_WARNING, errno, NULL,
759                 "error attaching to socket");
760         }
761         ap_close_socket(sock);
762         return;
763     }
764
765     (void) ap_update_child_status(my_child_num, my_thread_num,  
766                                   SERVER_BUSY_READ, (request_rec *) NULL);
767     conn_io = ap_bcreate(p, B_RDWR);
768     ap_bpush_iol(conn_io, iol);
769
770     current_conn = ap_new_apr_connection(p, server_conf, conn_io, sock,
771                                          conn_id);
772
773     ap_process_connection(current_conn);
774 }
775 /* Sets workers_may_exit if we received a character on the pipe_of_death */
776 static void check_pipe_of_death(void)
777 {
778     pthread_mutex_lock(&pipe_of_death_mutex);
779     if (!workers_may_exit) {
780         ap_status_t ret;
781         char pipe_read_char;
782         int n=1;
783
784         ret = ap_recv(listensocks[0], &pipe_read_char, &n);
785         if (ret == APR_EAGAIN) {
786             /* It lost the lottery. It must continue to suffer
787              * through a life of servitude. */
788         }
789         else {
790             /* It won the lottery (or something else is very
791              * wrong). Embrace death with open arms. */
792             workers_may_exit = 1;
793         }
794     }
795     pthread_mutex_unlock(&pipe_of_death_mutex);
796 }
797
798 static void * worker_thread(void * dummy)
799 {
800     proc_info * ti = dummy;
801     int process_slot = ti->pid;
802     int thread_slot = ti->tid;
803     ap_context_t *tpool = ti->tpool;
804     ap_socket_t *csd = NULL;
805     ap_context_t *ptrans;               /* Pool for per-transaction stuff */
806     ap_socket_t *sd = NULL;
807     int n;
808     int curr_pollfd, last_pollfd = 0;
809     ap_pollfd_t *pollset;
810     ap_status_t rv;
811
812     free(ti);
813
814     ap_create_context(&ptrans, tpool);
815
816     pthread_mutex_lock(&worker_thread_count_mutex);
817     worker_thread_count++;
818     pthread_mutex_unlock(&worker_thread_count_mutex);
819
820     ap_setup_poll(&pollset, num_listensocks+1, tpool);
821     for(n=0 ; n <= num_listensocks ; ++n)
822         ap_add_poll_socket(pollset, listensocks[n], APR_POLLIN);
823
824     /* TODO: Switch to a system where threads reuse the results from earlier
825        poll calls - manoj */
826     while (!workers_may_exit) {
827         workers_may_exit |= (ap_max_requests_per_child != 0) && (requests_this_child <= 0);
828         if (workers_may_exit) break;
829
830         (void) ap_update_child_status(process_slot, thread_slot, SERVER_READY, 
831                                       (request_rec *) NULL);
832         pthread_mutex_lock(&thread_accept_mutex);
833         if (workers_may_exit) {
834             pthread_mutex_unlock(&thread_accept_mutex);
835             break;
836         }
837         if ((rv = SAFE_ACCEPT(ap_lock(process_accept_mutex)))
838             != APR_SUCCESS) {
839             ap_log_error(APLOG_MARK, APLOG_EMERG, rv, server_conf,
840                          "ap_lock failed. Attempting to shutdown "
841                          "process gracefully.");
842             workers_may_exit = 1;
843         }
844
845         while (!workers_may_exit) {
846             ap_status_t ret;
847             ap_int16_t event;
848
849             ret = ap_poll(pollset, &n, -1);
850             if (ret != APR_SUCCESS) {
851                 if (ret == APR_EINTR) {
852                     continue;
853                 }
854
855                 /* poll() will only return errors in catastrophic
856                  * circumstances. Let's try exiting gracefully, for now. */
857                 ap_log_error(APLOG_MARK, APLOG_ERR, errno, (const server_rec *)
858                              ap_get_server_conf(), "poll: (listen)");
859                 workers_may_exit = 1;
860             }
861
862             if (workers_may_exit) break;
863
864             ap_get_revents(&event, listensocks[0], pollset);
865             if (event & APR_POLLIN) {
866                 /* A process got a signal on the shutdown pipe. Check if we're
867                  * the lucky process to die. */
868                 check_pipe_of_death();
869                 continue;
870             }
871
872             if (num_listensocks == 1) {
873                 sd = ap_listeners->sd;
874                 goto got_fd;
875             }
876             else {
877                 /* find a listener */
878                 curr_pollfd = last_pollfd;
879                 do {
880                     curr_pollfd++;
881                     if (curr_pollfd > num_listensocks) {
882                         curr_pollfd = 1;
883                     }
884                     /* XXX: Should we check for POLLERR? */
885                     ap_get_revents(&event, listensocks[curr_pollfd], pollset);
886                     if (event & APR_POLLIN) {
887                         last_pollfd = curr_pollfd;
888                         sd=listensocks[curr_pollfd];
889                         goto got_fd;
890                     }
891                 } while (curr_pollfd != last_pollfd);
892             }
893         }
894     got_fd:
895         if (!workers_may_exit) {
896             ap_accept(&csd, sd, ptrans);
897             if ((rv = SAFE_ACCEPT(ap_unlock(process_accept_mutex)))
898                 != APR_SUCCESS) {
899                 ap_log_error(APLOG_MARK, APLOG_EMERG, rv, server_conf,
900                              "ap_unlock failed. Attempting to shutdown "
901                              "process gracefully.");
902                 workers_may_exit = 1;
903             }
904             pthread_mutex_unlock(&thread_accept_mutex);
905             process_socket(ptrans, csd, process_slot, thread_slot);
906             requests_this_child--;
907         }
908         else {
909             if ((rv = SAFE_ACCEPT(ap_unlock(process_accept_mutex)))
910                 != APR_SUCCESS) {
911                 ap_log_error(APLOG_MARK, APLOG_EMERG, rv, server_conf,
912                              "ap_unlock failed. Attempting to shutdown "
913                              "process gracefully.");
914                 workers_may_exit = 1;
915             }
916             pthread_mutex_unlock(&thread_accept_mutex);
917             break;
918         }
919         ap_clear_pool(ptrans);
920     }
921
922     ap_destroy_pool(tpool);
923     ap_update_child_status(process_slot, thread_slot, SERVER_DEAD,
924         (request_rec *) NULL);
925     pthread_mutex_lock(&worker_thread_count_mutex);
926     worker_thread_count--;
927     if (worker_thread_count == 0) {
928         /* All the threads have exited, now finish the shutdown process
929          * by signalling the sigwait thread */
930         kill(my_pid, SIGTERM);
931     }
932     pthread_mutex_unlock(&worker_thread_count_mutex);
933
934     return NULL;
935 }
936
937
938 static void child_main(int child_num_arg)
939 {
940     sigset_t sig_mask;
941     int signal_received;
942     pthread_t thread;
943     pthread_attr_t thread_attr;
944     int i;
945     int my_child_num = child_num_arg;
946     proc_info *my_info = NULL;
947     ap_listen_rec *lr;
948     ap_status_t rv;
949
950
951     my_pid = getpid();
952     ap_create_context(&pchild, pconf);
953
954     /*stuff to do before we switch id's, so we have permissions.*/
955     reopen_scoreboard(pchild);
956
957     rv = SAFE_ACCEPT(ap_child_init_lock(&process_accept_mutex, lock_fname,
958                      pchild));
959     if (rv != APR_SUCCESS) {
960         ap_log_error(APLOG_MARK, APLOG_EMERG, rv, server_conf,
961                      "Couldn't initialize cross-process lock in child");
962         clean_child_exit(APEXIT_CHILDFATAL);
963     }
964
965     if (unixd_setup_child()) {
966         clean_child_exit(APEXIT_CHILDFATAL);
967     }
968
969     ap_child_init_hook(pchild, server_conf);
970
971     /*done with init critical section */
972
973     /* All threads should mask signals out, accoring to sigwait(2) man page */
974     sigfillset(&sig_mask);
975
976     if (pthread_sigmask(SIG_SETMASK, &sig_mask, NULL) != 0) {
977         ap_log_error(APLOG_MARK, APLOG_ALERT, errno, server_conf, "pthread_sigmask");
978     }
979
980     requests_this_child = ap_max_requests_per_child;
981     
982     /* Set up the pollfd array */
983     listensocks = ap_palloc(pchild,
984                             sizeof(*listensocks) * (num_listensocks + 1));
985     ap_create_tcp_socket(&listensocks[0], pchild);
986     ap_put_os_sock(&listensocks[0], &pipe_of_death[0], pchild);
987     for (lr = ap_listeners, i = 1; i <= num_listensocks; lr = lr->next, ++i)
988         listensocks[i]=lr->sd;
989
990     /* Setup worker threads */
991
992     worker_thread_count = 0;
993     pthread_mutex_init(&worker_thread_count_mutex, NULL);
994     pthread_mutex_init(&pipe_of_death_mutex, NULL);
995     pthread_attr_init(&thread_attr);
996     pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
997     for (i=0; i < ap_threads_per_child; i++) {
998
999         my_info = (proc_info *)malloc(sizeof(proc_info));
1000         if (my_info == NULL) {
1001             ap_log_error(APLOG_MARK, APLOG_ALERT, errno, server_conf,
1002                          "malloc: out of memory");
1003             clean_child_exit(APEXIT_CHILDFATAL);
1004         }
1005         my_info->pid = my_child_num;
1006         my_info->tid = i;
1007         my_info->sd = 0;
1008         ap_create_context(&my_info->tpool, pchild);
1009         
1010         /* We are creating threads right now */
1011         (void) ap_update_child_status(my_child_num, i, SERVER_STARTING, 
1012                                       (request_rec *) NULL);
1013 #ifndef NO_THREADS
1014         if (pthread_create(&thread, &thread_attr, worker_thread, my_info)) {
1015             ap_log_error(APLOG_MARK, APLOG_ALERT, errno, server_conf,
1016                          "pthread_create: unable to create worker thread");
1017             /* In case system resources are maxxed out, we don't want
1018                Apache running away with the CPU trying to fork over and
1019                over and over again if we exit. */
1020             sleep(10);
1021             clean_child_exit(APEXIT_CHILDFATAL);
1022         }
1023 #else
1024         worker_thread(my_info);
1025         /* The SIGTERM shouldn't let us reach this point, but just in case... */
1026         clean_child_exit(APEXIT_OK);
1027 #endif
1028
1029         /* We let each thread update it's own scoreboard entry.  This is done
1030          * because it let's us deal with tid better.
1031          */
1032     }
1033
1034     pthread_attr_destroy(&thread_attr);
1035
1036     /* This thread will be the one responsible for handling signals */
1037     sigemptyset(&sig_mask);
1038     sigaddset(&sig_mask, SIGTERM);
1039     sigaddset(&sig_mask, SIGINT);
1040     sigwait(&sig_mask, &signal_received);
1041     switch (signal_received) {
1042         case SIGTERM:
1043         case SIGINT:
1044             just_die(signal_received);
1045             break;
1046         default:
1047             ap_log_error(APLOG_MARK, APLOG_ALERT, errno, server_conf,
1048             "received impossible signal: %d", signal_received);
1049             just_die(SIGTERM);
1050     }
1051 }
1052
1053 static int make_child(server_rec *s, int slot, time_t now) 
1054 {
1055     int pid;
1056
1057     if (slot + 1 > max_daemons_limit) {
1058         max_daemons_limit = slot + 1;
1059     }
1060
1061     if (one_process) {
1062         set_signals();
1063         ap_scoreboard_image->parent[slot].pid = getpid();
1064         child_main(slot);
1065     }
1066
1067     /* Tag this slot as occupied so that perform_idle_server_maintenance
1068      * doesn't try to steal it */
1069     (void) ap_update_child_status(slot, 0, SERVER_STARTING, (request_rec *) NULL);
1070
1071     if ((pid = fork()) == -1) {
1072         ap_log_error(APLOG_MARK, APLOG_ERR, errno, s, "fork: Unable to fork new process");
1073
1074         /* fork didn't succeed. Fix the scoreboard or else
1075          * it will say SERVER_STARTING forever and ever
1076          */
1077         (void) ap_update_child_status(slot, 0, SERVER_DEAD, (request_rec *) NULL);
1078
1079         /* In case system resources are maxxed out, we don't want
1080            Apache running away with the CPU trying to fork over and
1081            over and over again. */
1082         sleep(10);
1083
1084         return -1;
1085     }
1086
1087     if (!pid) {
1088 #ifdef AIX_BIND_PROCESSOR
1089       /* By default, AIX binds to a single processor.  This bit unbinds
1090          children which will then bind to another CPU.
1091       */
1092 #include <sys/processor.h>
1093         int status = bindprocessor(BINDPROCESS, (int)getpid(),
1094                                PROCESSOR_CLASS_ANY);
1095         if (status != OK)
1096             ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, server_conf,
1097                          "processor unbind failed %d", status);
1098 #endif
1099
1100         RAISE_SIGSTOP(MAKE_CHILD);
1101
1102         signal(SIGTERM, just_die);
1103         child_main(slot);
1104
1105         return 0;
1106     }
1107     /* else */
1108     ap_scoreboard_image->parent[slot].pid = pid;
1109     return 0;
1110 }
1111
1112 /* start up a bunch of children */
1113 static void startup_children(int number_to_start)
1114 {
1115     int i;
1116
1117     for (i = 0; number_to_start && i < ap_daemons_limit; ++i) {
1118         if (ap_scoreboard_image->parent[i].pid != 0) {
1119             continue;
1120         }
1121         if (make_child(server_conf, i, 0) < 0) {
1122             break;
1123         }
1124         --number_to_start;
1125     }
1126 }
1127
1128
1129 /*
1130  * idle_spawn_rate is the number of children that will be spawned on the
1131  * next maintenance cycle if there aren't enough idle servers.  It is
1132  * doubled up to MAX_SPAWN_RATE, and reset only when a cycle goes by
1133  * without the need to spawn.
1134  */
1135 static int idle_spawn_rate = 1;
1136 #ifndef MAX_SPAWN_RATE
1137 #define MAX_SPAWN_RATE  (32)
1138 #endif
1139 static int hold_off_on_exponential_spawning;
1140
1141 static void perform_idle_server_maintenance(void)
1142 {
1143     int i, j;
1144     int idle_thread_count;
1145     thread_score *ss;
1146     time_t now = 0;
1147     int free_length;
1148     int free_slots[MAX_SPAWN_RATE];
1149     int last_non_dead;
1150     int total_non_dead;
1151
1152     /* initialize the free_list */
1153     free_length = 0;
1154
1155     idle_thread_count = 0;
1156     last_non_dead = -1;
1157     total_non_dead = 0;
1158
1159     ap_sync_scoreboard_image();
1160     for (i = 0; i < ap_daemons_limit; ++i) {
1161         /* Initialization to satisfy the compiler. It doesn't know
1162          * that ap_threads_per_child is always > 0 */
1163         int status = SERVER_DEAD;
1164         int any_dying_threads = 0;
1165         int all_dead_threads = 1;
1166         int idle_thread_addition = 0;
1167
1168         if (i >= max_daemons_limit && free_length == idle_spawn_rate)
1169             break;
1170         for (j = 0; j < ap_threads_per_child; j++) {
1171             ss = &ap_scoreboard_image->servers[i][j];
1172             status = ss->status;
1173
1174             any_dying_threads = any_dying_threads || (status == SERVER_DEAD)
1175                                     || (status == SERVER_GRACEFUL);
1176             all_dead_threads = all_dead_threads && (status == SERVER_DEAD);
1177
1178             /* We consider a starting server as idle because we started it
1179              * at least a cycle ago, and if it still hasn't finished starting
1180              * then we're just going to swamp things worse by forking more.
1181              * So we hopefully won't need to fork more if we count it.
1182              * This depends on the ordering of SERVER_READY and SERVER_STARTING.
1183              */
1184             if (status <= SERVER_READY) {
1185                 ++idle_thread_addition;
1186             }
1187         }
1188         if (all_dead_threads && free_length < idle_spawn_rate) {
1189             free_slots[free_length] = i;
1190             ++free_length;
1191         }
1192         if (!all_dead_threads) {
1193             last_non_dead = i;
1194         }
1195         if (!any_dying_threads) {
1196             ++total_non_dead;
1197             idle_thread_count += idle_thread_addition;
1198         }
1199     }
1200     max_daemons_limit = last_non_dead + 1;
1201
1202     if (idle_thread_count > max_spare_threads) {
1203         /* Kill off one child */
1204         char char_of_death = '!';
1205         if (write(pipe_of_death[1], &char_of_death, 1) == -1) {
1206             ap_log_error(APLOG_MARK, APLOG_WARNING, errno, server_conf, "write pipe_of_death");
1207         }
1208         idle_spawn_rate = 1;
1209     }
1210     else if (idle_thread_count < min_spare_threads) {
1211         /* terminate the free list */
1212         if (free_length == 0) {
1213             /* only report this condition once */
1214             static int reported = 0;
1215             
1216             if (!reported) {
1217                 ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, server_conf,
1218                              "server reached MaxClients setting, consider"
1219                              " raising the MaxClients setting");
1220                 reported = 1;
1221             }
1222             idle_spawn_rate = 1;
1223         }
1224         else {
1225             
1226             if (idle_spawn_rate >= 8) {
1227                 ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, 0, server_conf,
1228                              "server seems busy, (you may need "
1229                              "to increase StartServers, ThreadsPerChild "
1230                              "or Min/MaxSparetThreads), "
1231                              "spawning %d children, there are around %d idle "
1232                              "threads, and %d total children", idle_spawn_rate,
1233                              idle_thread_count, total_non_dead);
1234             }
1235             for (i = 0; i < free_length; ++i) {
1236                 make_child(server_conf, free_slots[i], now);
1237             }
1238             /* the next time around we want to spawn twice as many if this
1239              * wasn't good enough, but not if we've just done a graceful
1240              */
1241             if (hold_off_on_exponential_spawning) {
1242                 --hold_off_on_exponential_spawning;
1243             }
1244             else if (idle_spawn_rate < MAX_SPAWN_RATE) {
1245                 idle_spawn_rate *= 2;
1246             }
1247         }
1248     }
1249     else {
1250       idle_spawn_rate = 1;
1251     }
1252 }
1253
1254 static void server_main_loop(int remaining_children_to_start)
1255 {
1256     int child_slot;
1257     ap_wait_t status;
1258     int pid;
1259     int i;
1260
1261     while (!restart_pending && !shutdown_pending) {
1262         pid = wait_or_timeout(&status);
1263         
1264         if (pid >= 0) {
1265             process_child_status(pid, status);
1266             /* non-fatal death... note that it's gone in the scoreboard. */
1267             child_slot = find_child_by_pid(pid);
1268             if (child_slot >= 0) {
1269                 for (i = 0; i < ap_threads_per_child; i++)
1270                     ap_update_child_status(child_slot, i, SERVER_DEAD, (request_rec *) NULL);
1271                 
1272                 if (remaining_children_to_start
1273                     && child_slot < ap_daemons_limit) {
1274                     /* we're still doing a 1-for-1 replacement of dead
1275                      * children with new children
1276                      */
1277                     make_child(server_conf, child_slot, time(NULL));
1278                     --remaining_children_to_start;
1279                 }
1280 #ifdef HAS_OTHER_CHILD
1281             }
1282             else if (reap_other_child(pid, status) == 0) {
1283                 /* handled */
1284 #endif
1285             }
1286             else if (is_graceful) {
1287                 /* Great, we've probably just lost a slot in the
1288                     * scoreboard.  Somehow we don't know about this
1289                     * child.
1290                     */
1291                 ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, server_conf,
1292                             "long lost child came home! (pid %d)", pid);
1293             }
1294             /* Don't perform idle maintenance when a child dies,
1295              * only do it when there's a timeout.  Remember only a
1296              * finite number of children can die, and it's pretty
1297              * pathological for a lot to die suddenly.
1298              */
1299             continue;
1300         }
1301         else if (remaining_children_to_start) {
1302             /* we hit a 1 second timeout in which none of the previous
1303              * generation of children needed to be reaped... so assume
1304              * they're all done, and pick up the slack if any is left.
1305              */
1306             startup_children(remaining_children_to_start);
1307             remaining_children_to_start = 0;
1308             /* In any event we really shouldn't do the code below because
1309              * few of the servers we just started are in the IDLE state
1310              * yet, so we'd mistakenly create an extra server.
1311              */
1312             continue;
1313         }
1314
1315         perform_idle_server_maintenance();
1316     }
1317 }
1318
1319 int ap_mpm_run(ap_context_t *_pconf, ap_context_t *plog, server_rec *s)
1320 {
1321     int remaining_children_to_start;
1322     ap_status_t rv;
1323
1324     pconf = _pconf;
1325     server_conf = s;
1326     if (pipe(pipe_of_death) == -1) {
1327         ap_log_error(APLOG_MARK, APLOG_ERR, errno,
1328                      (const server_rec*) server_conf,
1329                      "pipe: (pipe_of_death)");
1330         exit(1);
1331     }
1332 /*  XXXXXX  Removed because these functions don't exist anymore.  When
1333     These pipes are changed to apr_types, these functions won't be needed
1334     anyway.
1335     ap_note_cleanups_for_fd(pconf, pipe_of_death[0]);
1336     ap_note_cleanups_for_fd(pconf, pipe_of_death[1]);
1337 */
1338
1339     if (fcntl(pipe_of_death[0], F_SETFD, O_NONBLOCK) == -1) {
1340         ap_log_error(APLOG_MARK, APLOG_ERR, errno,
1341                      (const server_rec*) server_conf,
1342                      "fcntl: O_NONBLOCKing (pipe_of_death)");
1343         exit(1);
1344     }
1345     server_conf = s;
1346     if ((num_listensocks = setup_listeners(server_conf)) < 1) {
1347         /* XXX: hey, what's the right way for the mpm to indicate a fatal error? */
1348         ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ALERT, 0, s,
1349             "no listening sockets available, shutting down");
1350         return 1;
1351     }
1352     ap_log_pid(pconf, ap_pid_fname);
1353
1354     /* Initialize cross-process accept lock */
1355     lock_fname = ap_psprintf(_pconf, "%s.%lu",
1356                              ap_server_root_relative(_pconf, lock_fname),
1357                              my_pid);
1358     rv = ap_create_lock(&process_accept_mutex, APR_MUTEX, APR_CROSS_PROCESS,
1359                    lock_fname, _pconf);
1360     if (rv != APR_SUCCESS) {
1361         ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s,
1362                      "Couldn't create cross-process lock");
1363         return 1;
1364     }
1365
1366
1367     if (!is_graceful) {
1368         reinit_scoreboard(pconf);
1369     }
1370
1371     set_signals();
1372     /* Don't thrash... */
1373     if (max_spare_threads < min_spare_threads + ap_threads_per_child)
1374         max_spare_threads = min_spare_threads + ap_threads_per_child;
1375
1376     /* If we're doing a graceful_restart then we're going to see a lot
1377      * of children exiting immediately when we get into the main loop
1378      * below (because we just sent them SIGWINCH).  This happens pretty
1379      * rapidly... and for each one that exits we'll start a new one until
1380      * we reach at least daemons_min_free.  But we may be permitted to
1381      * start more than that, so we'll just keep track of how many we're
1382      * supposed to start up without the 1 second penalty between each fork.
1383      */
1384     remaining_children_to_start = ap_daemons_to_start;
1385     if (remaining_children_to_start > ap_daemons_limit) {
1386         remaining_children_to_start = ap_daemons_limit;
1387     }
1388     if (!is_graceful) {
1389         startup_children(remaining_children_to_start);
1390         remaining_children_to_start = 0;
1391     }
1392     else {
1393         /* give the system some time to recover before kicking into
1394             * exponential mode */
1395         hold_off_on_exponential_spawning = 10;
1396     }
1397
1398     ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, 0, server_conf,
1399                 "%s configured -- resuming normal operations",
1400                 ap_get_server_version());
1401     ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, 0, server_conf,
1402                 "Server built: %s", ap_get_server_built());
1403     restart_pending = shutdown_pending = 0;
1404
1405     server_main_loop(remaining_children_to_start);
1406
1407     if (shutdown_pending) {
1408         /* Time to gracefully shut down:
1409          * Kill child processes, tell them to call child_exit, etc...
1410          */
1411         if (unixd_killpg(getpgrp(), SIGTERM) < 0) {
1412             ap_log_error(APLOG_MARK, APLOG_WARNING, errno, server_conf, "killpg SIGTERM");
1413         }
1414         reclaim_child_processes(1);             /* Start with SIGTERM */
1415     
1416         /* cleanup pid file on normal shutdown */
1417         {
1418             const char *pidfile = NULL;
1419             pidfile = ap_server_root_relative (pconf, ap_pid_fname);
1420             if ( pidfile != NULL && unlink(pidfile) == 0)
1421                 ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, 0,
1422                          server_conf,
1423                          "removed PID file %s (pid=%ld)",
1424                          pidfile, (long)getpid());
1425         }
1426     
1427         ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, 0, server_conf,
1428             "caught SIGTERM, shutting down");
1429     
1430         return 1;
1431     }
1432
1433     /* we've been told to restart */
1434     signal(SIGHUP, SIG_IGN);
1435
1436     if (one_process) {
1437         /* not worth thinking about */
1438         return 1;
1439     }
1440
1441     /* advance to the next generation */
1442     /* XXX: we really need to make sure this new generation number isn't in
1443      * use by any of the children.
1444      */
1445     ++ap_my_generation;
1446     ap_scoreboard_image->global.running_generation = ap_my_generation;
1447     update_scoreboard_global();
1448
1449     if (is_graceful) {
1450         int i, j;
1451         char char_of_death = '!';
1452
1453         ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, 0, server_conf,
1454                     "SIGWINCH received.  Doing graceful restart");
1455
1456         /* give the children the signal to die */
1457         for (i = 0; i < ap_daemons_limit;) {
1458             if (write(pipe_of_death[1], &char_of_death, 1) == -1) {
1459                 if (errno == EINTR) continue;
1460                 ap_log_error(APLOG_MARK, APLOG_WARNING, errno, server_conf, "write pipe_of_death");
1461             }
1462             i++;
1463         }
1464
1465         /* This is mostly for debugging... so that we know what is still
1466          * gracefully dealing with existing request.
1467          */
1468         
1469         for (i = 0; i < ap_daemons_limit; ++i) {
1470             for (j = 0; j < ap_threads_per_child; j++) { 
1471                 if (ap_scoreboard_image->servers[i][j].status != SERVER_DEAD) {
1472                     ap_scoreboard_image->servers[i][j].status = SERVER_GRACEFUL;
1473                 }
1474             } 
1475         }
1476     }
1477     else {
1478       /* Kill 'em all.  Since the child acts the same on the parents SIGTERM 
1479        * and a SIGHUP, we may as well use the same signal, because some user
1480        * pthreads are stealing signals from us left and right.
1481        */
1482         if (unixd_killpg(getpgrp(), SIGTERM) < 0) {
1483             ap_log_error(APLOG_MARK, APLOG_WARNING, errno, server_conf, "killpg SIGTERM");
1484         }
1485         reclaim_child_processes(1);             /* Start with SIGTERM */
1486         ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, 0, server_conf,
1487                     "SIGHUP received.  Attempting to restart");
1488     }
1489     if (!is_graceful) {
1490         ap_restart_time = time(NULL); 
1491     }
1492     return 0;
1493 }
1494
1495 static void mpmt_pthread_pre_config(ap_context_t *pconf, ap_context_t *plog, ap_context_t *ptemp)
1496 {
1497     static int restart_num = 0;
1498
1499     one_process = !!getenv("ONE_PROCESS");
1500
1501     /* sigh, want this only the second time around */
1502     if (restart_num++ == 1) {
1503         is_graceful = 0;
1504
1505         if (!one_process) {
1506             unixd_detach();
1507         }
1508         my_pid = getpid();
1509     }
1510
1511     unixd_pre_config();
1512     ap_listen_pre_config();
1513     ap_daemons_to_start = DEFAULT_START_DAEMON;
1514     min_spare_threads = DEFAULT_MIN_FREE_DAEMON * DEFAULT_THREADS_PER_CHILD;
1515     max_spare_threads = DEFAULT_MAX_FREE_DAEMON * DEFAULT_THREADS_PER_CHILD;
1516     ap_daemons_limit = HARD_SERVER_LIMIT;
1517     ap_threads_per_child = DEFAULT_THREADS_PER_CHILD;
1518     ap_pid_fname = DEFAULT_PIDLOG;
1519     ap_scoreboard_fname = DEFAULT_SCOREBOARD;
1520     lock_fname = DEFAULT_LOCKFILE;
1521     ap_max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD;
1522     ap_extended_status = 0;
1523
1524     ap_cpystrn(ap_coredump_dir, ap_server_root, sizeof(ap_coredump_dir));
1525 }
1526
1527 static void mpmt_pthread_hooks(void)
1528 {
1529     ap_hook_pre_config(mpmt_pthread_pre_config,NULL,NULL,HOOK_MIDDLE);
1530     INIT_SIGLIST()
1531     one_process = 0;
1532 }
1533
1534
1535 static const char *set_pidfile(cmd_parms *cmd, void *dummy, char *arg) 
1536 {
1537     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
1538     if (err != NULL) {
1539         return err;
1540     }
1541
1542     if (cmd->server->is_virtual) {
1543         return "PidFile directive not allowed in <VirtualHost>";
1544     }
1545     ap_pid_fname = arg;
1546     return NULL;
1547 }
1548
1549 static const char *set_scoreboard(cmd_parms *cmd, void *dummy, char *arg) 
1550 {
1551     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
1552     if (err != NULL) {
1553         return err;
1554     }
1555
1556     ap_scoreboard_fname = arg;
1557     return NULL;
1558 }
1559
1560 static const char *set_lockfile(cmd_parms *cmd, void *dummy, char *arg) 
1561 {
1562     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
1563     if (err != NULL) {
1564         return err;
1565     }
1566
1567     lock_fname = arg;
1568     return NULL;
1569 }
1570
1571 static const char *set_daemons_to_start(cmd_parms *cmd, void *dummy, char *arg) 
1572 {
1573     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
1574     if (err != NULL) {
1575         return err;
1576     }
1577
1578     ap_daemons_to_start = atoi(arg);
1579     return NULL;
1580 }
1581
1582 static const char *set_min_spare_threads(cmd_parms *cmd, void *dummy, char *arg)
1583 {
1584     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
1585     if (err != NULL) {
1586         return err;
1587     }
1588
1589     min_spare_threads = atoi(arg);
1590     if (min_spare_threads <= 0) {
1591        ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
1592                     "WARNING: detected MinSpareThreads set to non-positive.");
1593        ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
1594                     "Resetting to 1 to avoid almost certain Apache failure.");
1595        ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
1596                     "Please read the documentation.");
1597        min_spare_threads = 1;
1598     }
1599        
1600     return NULL;
1601 }
1602
1603 static const char *set_max_spare_threads(cmd_parms *cmd, void *dummy, char *arg)
1604 {
1605     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
1606     if (err != NULL) {
1607         return err;
1608     }
1609
1610     max_spare_threads = atoi(arg);
1611     return NULL;
1612 }
1613
1614 static const char *set_server_limit (cmd_parms *cmd, void *dummy, char *arg) 
1615 {
1616     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
1617     if (err != NULL) {
1618         return err;
1619     }
1620
1621     ap_daemons_limit = atoi(arg);
1622     if (ap_daemons_limit > HARD_SERVER_LIMIT) {
1623        ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
1624                     "WARNING: MaxClients of %d exceeds compile time limit "
1625                     "of %d servers,", ap_daemons_limit, HARD_SERVER_LIMIT);
1626        ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
1627                     " lowering MaxClients to %d.  To increase, please "
1628                     "see the", HARD_SERVER_LIMIT);
1629        ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
1630                     " HARD_SERVER_LIMIT define in src/include/httpd.h.");
1631        ap_daemons_limit = HARD_SERVER_LIMIT;
1632     } 
1633     else if (ap_daemons_limit < 1) {
1634         ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, "WARNING: Require MaxClients > 0, setting to 1\n");
1635         ap_daemons_limit = 1;
1636     }
1637     return NULL;
1638 }
1639
1640 static const char *set_threads_per_child (cmd_parms *cmd, void *dummy, char *arg) 
1641 {
1642     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
1643     if (err != NULL) {
1644         return err;
1645     }
1646
1647     ap_threads_per_child = atoi(arg);
1648     if (ap_threads_per_child > HARD_THREAD_LIMIT) {
1649         ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
1650                      "WARNING: ThreadsPerChild of %d exceeds compile time"
1651                      "limit of %d threads,", ap_threads_per_child,
1652                      HARD_THREAD_LIMIT);
1653         ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
1654                      " lowering ThreadsPerChild to %d. To increase, please"
1655                      "see the", HARD_THREAD_LIMIT);
1656         ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
1657                      " HARD_THREAD_LIMIT define in src/include/httpd.h.");
1658     }
1659     else if (ap_threads_per_child < 1) {
1660         ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
1661                      "WARNING: Require ThreadsPerChild > 0, setting to 1");
1662         ap_threads_per_child = 1;
1663     }
1664     return NULL;
1665 }
1666
1667 static const char *set_max_requests(cmd_parms *cmd, void *dummy, char *arg) 
1668 {
1669     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
1670     if (err != NULL) {
1671         return err;
1672     }
1673
1674     ap_max_requests_per_child = atoi(arg);
1675
1676     return NULL;
1677 }
1678
1679 static const char *set_coredumpdir (cmd_parms *cmd, void *dummy, char *arg) 
1680 {
1681     struct stat finfo;
1682     const char *fname;
1683     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
1684     if (err != NULL) {
1685         return err;
1686     }
1687
1688     fname = ap_server_root_relative(cmd->pool, arg);
1689     if ((stat(fname, &finfo) == -1) || !S_ISDIR(finfo.st_mode)) {
1690         return ap_pstrcat(cmd->pool, "CoreDumpDirectory ", fname, 
1691                           " does not exist or is not a directory", NULL);
1692     }
1693     ap_cpystrn(ap_coredump_dir, fname, sizeof(ap_coredump_dir));
1694     return NULL;
1695 }
1696
1697 static const command_rec mpmt_pthread_cmds[] = {
1698 UNIX_DAEMON_COMMANDS
1699 LISTEN_COMMANDS
1700 { "PidFile", set_pidfile, NULL, RSRC_CONF, TAKE1,
1701     "A file for logging the server process ID"},
1702 { "ScoreBoardFile", set_scoreboard, NULL, RSRC_CONF, TAKE1,
1703     "A file for Apache to maintain runtime process management information"},
1704 { "LockFile", set_lockfile, NULL, RSRC_CONF, TAKE1,
1705     "The lockfile used when Apache needs to lock the accept() call"},
1706 { "StartServers", set_daemons_to_start, NULL, RSRC_CONF, TAKE1,
1707   "Number of child processes launched at server startup" },
1708 { "MinSpareThreads", set_min_spare_threads, NULL, RSRC_CONF, TAKE1,
1709   "Minimum number of idle children, to handle request spikes" },
1710 { "MaxSpareThreads", set_max_spare_threads, NULL, RSRC_CONF, TAKE1,
1711   "Maximum number of idle children" },
1712 { "MaxClients", set_server_limit, NULL, RSRC_CONF, TAKE1,
1713   "Maximum number of children alive at the same time" },
1714 { "ThreadsPerChild", set_threads_per_child, NULL, RSRC_CONF, TAKE1,
1715   "Number of threads each child creates" },
1716 { "MaxRequestsPerChild", set_max_requests, NULL, RSRC_CONF, TAKE1,
1717   "Maximum number of requests a particular child serves before dying." },
1718 { "CoreDumpDirectory", set_coredumpdir, NULL, RSRC_CONF, TAKE1,
1719   "The location of the directory Apache changes to before dumping core" },
1720 { NULL }
1721 };
1722
1723 module MODULE_VAR_EXPORT mpm_mpmt_pthread_module = {
1724     STANDARD20_MODULE_STUFF,
1725     NULL,                       /* create per-directory config structure */
1726     NULL,                       /* merge per-directory config structures */
1727     NULL,                       /* create per-server config structure */
1728     NULL,                       /* merge per-server config structures */
1729     mpmt_pthread_cmds,          /* command ap_table_t */
1730     NULL,                       /* handlers */
1731     mpmt_pthread_hooks          /* register_hooks */
1732 };
1733