/[Apache-SVN]/httpd/httpd/branches/2.2.x/server/mpm/worker/worker.c
ViewVC logotype

Contents of /httpd/httpd/branches/2.2.x/server/mpm/worker/worker.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 396056 - (hide annotations)
Sat Apr 22 01:53:06 2006 UTC (3 years, 7 months ago) by pquerna
File MIME type: text/plain
File size: 80313 byte(s)
Revert r395231 from the 2.2.x branch.  This gets us back to the old place with regard to the copyright statements.
1 pquerna 396056 /* Copyright 2001-2005 The Apache Software Foundation or its licensors, as
2 jerenkrantz 151408 * applicable.
3 rbb 89781 *
4 nd 102525 * Licensed under the Apache License, Version 2.0 (the "License");
5     * you may not use this file except in compliance with the License.
6     * You may obtain a copy of the License at
7 rbb 89781 *
8 nd 102525 * http://www.apache.org/licenses/LICENSE-2.0
9 rbb 89781 *
10 nd 102525 * Unless required by applicable law or agreed to in writing, software
11     * distributed under the License is distributed on an "AS IS" BASIS,
12     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13     * See the License for the specific language governing permissions and
14     * limitations under the License.
15 rbb 89781 */
16    
17 rbb 89938 /* The purpose of this MPM is to fix the design flaws in the threaded
18     * model. Because of the way that pthreads and mutex locks interact,
19     * it is basically impossible to cleanly gracefully shutdown a child
20     * process if multiple threads are all blocked in accept. This model
21     * fixes those problems.
22     */
23    
24 rbb 89781 #include "apr.h"
25     #include "apr_portable.h"
26     #include "apr_strings.h"
27     #include "apr_file_io.h"
28     #include "apr_thread_proc.h"
29     #include "apr_signal.h"
30 aaron 91518 #include "apr_thread_mutex.h"
31 aaron 91582 #include "apr_proc_mutex.h"
32 rbb 96005 #include "apr_poll.h"
33 rbb 89781 #define APR_WANT_STRFUNC
34     #include "apr_want.h"
35    
36     #if APR_HAVE_UNISTD_H
37     #include <unistd.h>
38     #endif
39     #if APR_HAVE_SYS_SOCKET_H
40     #include <sys/socket.h>
41     #endif
42     #if APR_HAVE_SYS_WAIT_H
43 jim 332309 #include <sys/wait.h>
44 rbb 89781 #endif
45     #ifdef HAVE_SYS_PROCESSOR_H
46     #include <sys/processor.h> /* for bindprocessor() */
47     #endif
48    
49     #if !APR_HAS_THREADS
50     #error The Worker MPM requires APR threads, but they are unavailable.
51     #endif
52    
53 jim 332309 #define CORE_PRIVATE
54    
55 rbb 89781 #include "ap_config.h"
56 jim 332309 #include "httpd.h"
57     #include "http_main.h"
58     #include "http_log.h"
59     #include "http_config.h" /* for read_config */
60     #include "http_core.h" /* for get_remote_host */
61 rbb 89781 #include "http_connection.h"
62     #include "ap_mpm.h"
63 rbb 93358 #include "pod.h"
64 rbb 89781 #include "mpm_common.h"
65     #include "ap_listen.h"
66 jim 332309 #include "scoreboard.h"
67 rbb 89781 #include "fdqueue.h"
68 trawick 92512 #include "mpm_default.h"
69 rbb 89781
70     #include <signal.h>
71     #include <limits.h> /* for INT_MAX */
72    
73 trawick 92512 /* Limit on the total --- clients will be locked out if more servers than
74     * this are needed. It is intended solely to keep the server from crashing
75     * when things get out of hand.
76     *
77     * We keep a hard maximum number of servers, for two reasons --- first off,
78     * in case something goes seriously wrong, we want to stop the fork bomb
79     * short of actually crashing the machine we're running on by filling some
80     * kernel table. Secondly, it keeps the size of the scoreboard file small
81     * enough that we can read the whole thing without worrying too much about
82     * the overhead.
83     */
84 trawick 92530 #ifndef DEFAULT_SERVER_LIMIT
85     #define DEFAULT_SERVER_LIMIT 16
86 trawick 92512 #endif
87    
88 trawick 92530 /* Admin can't tune ServerLimit beyond MAX_SERVER_LIMIT. We want
89     * some sort of compile-time limit to help catch typos.
90     */
91     #ifndef MAX_SERVER_LIMIT
92     #define MAX_SERVER_LIMIT 20000
93     #endif
94    
95 trawick 92512 /* Limit on the threads per process. Clients will be locked out if more than
96 trawick 92530 * this * server_limit are needed.
97 trawick 92512 *
98     * We keep this for one reason it keeps the size of the scoreboard file small
99     * enough that we can read the whole thing without worrying too much about
100     * the overhead.
101     */
102 trawick 92530 #ifndef DEFAULT_THREAD_LIMIT
103 jim 332309 #define DEFAULT_THREAD_LIMIT 64
104 trawick 92512 #endif
105    
106 trawick 92530 /* Admin can't tune ThreadLimit beyond MAX_THREAD_LIMIT. We want
107     * some sort of compile-time limit to help catch typos.
108     */
109     #ifndef MAX_THREAD_LIMIT
110     #define MAX_THREAD_LIMIT 20000
111     #endif
112    
113 rbb 89781 /*
114     * Actual definitions of config globals
115     */
116    
117 jerenkrantz 92473 int ap_threads_per_child = 0; /* Worker threads per child */
118     static int ap_daemons_to_start = 0;
119     static int min_spare_threads = 0;
120     static int max_spare_threads = 0;
121 trawick 93528 static int ap_daemons_limit = 0;
122 trawick 92530 static int server_limit = DEFAULT_SERVER_LIMIT;
123 colm 293164 static int first_server_limit = 0;
124 trawick 92530 static int thread_limit = DEFAULT_THREAD_LIMIT;
125 colm 293164 static int first_thread_limit = 0;
126 trawick 92530 static int changed_limit_at_restart;
127 rbb 89781 static int dying = 0;
128     static int workers_may_exit = 0;
129 trawick 94095 static int start_thread_may_exit = 0;
130     static int listener_may_exit = 0;
131 rbb 89781 static int requests_this_child;
132     static int num_listensocks = 0;
133 gregames 93366 static int resource_shortage = 0;
134 rbb 90635 static fd_queue_t *worker_queue;
135 aaron 94824 static fd_queue_info_t *worker_queue_info;
136 trawick 102045 static int mpm_state = AP_MPMQ_STARTING;
137 gregames 168182 static int sick_child_detected;
138 rbb 89781
139     /* The structure used to pass unique initialization info to each thread */
140     typedef struct {
141     int pid;
142     int tid;
143     int sd;
144     } proc_info;
145    
146 jim 332309 /* Structure used to pass information to the thread responsible for
147 rbb 89781 * creating the rest of the threads.
148     */
149     typedef struct {
150     apr_thread_t **threads;
151 trawick 94031 apr_thread_t *listener;
152 rbb 89781 int child_num_arg;
153     apr_threadattr_t *threadattr;
154     } thread_starter;
155    
156 trawick 92530 #define ID_FROM_CHILD_THREAD(c, t) ((c * thread_limit) + t)
157 trawick 92512
158 rbb 89781 /*
159     * The max child slot ever assigned, preserved across restarts. Necessary
160 jim 332309 * to deal with MaxClients changes across AP_SIG_GRACEFUL restarts. We
161     * use this value to optimize routines that have to scan the entire
162 jerenkrantz 91076 * scoreboard.
163 rbb 89781 */
164     int ap_max_daemons_limit = -1;
165    
166 brianp 93096 static ap_pod_t *pod;
167 rbb 89781
168     /* *Non*-shared http_main globals... */
169    
170     server_rec *ap_server_conf;
171    
172 jwoolley 90790 /* The worker MPM respects a couple of runtime flags that can aid
173     * in debugging. Setting the -DNO_DETACH flag will prevent the root process
174     * from detaching from its controlling terminal. Additionally, setting
175     * the -DONE_PROCESS flag (which implies -DNO_DETACH) will get you the
176     * child_main loop running in the process which originally started up.
177     * This gives you a pretty nice debugging environment. (You'll get a SIGHUP
178 rbb 89781 * early in standalone_main; just continue through. This is the server
179     * trying to kill off any child processes which it might have lying
180     * around --- Apache doesn't keep track of their pids, it just sends
181     * SIGHUP to the process group, ignoring it in the root process.
182     * Continue through and you'll be fine.).
183     */
184    
185     static int one_process = 0;
186    
187     #ifdef DEBUG_SIGSTOP
188     int raise_sigstop_flags;
189     #endif
190    
191 jerenkrantz 92473 static apr_pool_t *pconf; /* Pool for config stuff */
192     static apr_pool_t *pchild; /* Pool for httpd child stuff */
193 rbb 89781
194 jim 332309 static pid_t ap_my_pid; /* Linux getpid() doesn't work except in main
195 rbb 89781 thread. Use this instead */
196 gregames 90064 static pid_t parent_pid;
197 trawick 94031 static apr_os_thread_t *listener_os_thread;
198 rbb 89781
199     /* Locks for accept serialization */
200 aaron 91580 static apr_proc_mutex_t *accept_mutex;
201 rbb 89781
202 brianp 93096 #ifdef SINGLE_LISTEN_UNSERIALIZED_ACCEPT
203     #define SAFE_ACCEPT(stmt) (ap_listeners->next ? (stmt) : APR_SUCCESS)
204 rbb 89781 #else
205     #define SAFE_ACCEPT(stmt) (stmt)
206     #endif
207    
208 jim 332309 /* The LISTENER_SIGNAL signal will be sent from the main thread to the
209     * listener thread to wake it up for graceful termination (what a child
210     * process from an old generation does when the admin does "apachectl
211 trawick 94031 * graceful"). This signal will be blocked in all threads of a child
212     * process except for the listener thread.
213     */
214     #define LISTENER_SIGNAL SIGHUP
215    
216 jerenkrantz 94886 /* An array of socket descriptors in use by each thread used to
217     * perform a non-graceful (forced) shutdown of the server. */
218     static apr_socket_t **worker_sockets;
219    
220     static void close_worker_sockets(void)
221     {
222     int i;
223     for (i = 0; i < ap_threads_per_child; i++) {
224     if (worker_sockets[i]) {
225     apr_socket_close(worker_sockets[i]);
226     worker_sockets[i] = NULL;
227     }
228     }
229     }
230 jim 332309
231 trawick 94031 static void wakeup_listener(void)
232     {
233 trawick 94095 listener_may_exit = 1;
234 trawick 94420 if (!listener_os_thread) {
235     /* XXX there is an obscure path that this doesn't handle perfectly:
236 jim 332309 * right after listener thread is created but before
237 trawick 94420 * listener_os_thread is set, the first worker thread hits an
238     * error and starts graceful termination
239     */
240     return;
241     }
242 trawick 94031 /*
243 trawick 94417 * we should just be able to "kill(ap_my_pid, LISTENER_SIGNAL)" on all
244 jim 332309 * platforms and wake up the listener thread since it is the only thread
245 trawick 94417 * with SIGHUP unblocked, but that doesn't work on Linux
246 trawick 94031 */
247 trawick 94417 #ifdef HAVE_PTHREAD_KILL
248 trawick 94031 pthread_kill(*listener_os_thread, LISTENER_SIGNAL);
249 trawick 94417 #else
250     kill(ap_my_pid, LISTENER_SIGNAL);
251     #endif
252 trawick 94031 }
253    
254 trawick 94232 #define ST_INIT 0
255 trawick 94095 #define ST_GRACEFUL 1
256     #define ST_UNGRACEFUL 2
257    
258 trawick 94232 static int terminate_mode = ST_INIT;
259    
260 trawick 94095 static void signal_threads(int mode)
261 rbb 89827 {
262 trawick 94232 if (terminate_mode == mode) {
263 trawick 94106 return;
264     }
265 trawick 94232 terminate_mode = mode;
266 trawick 102045 mpm_state = AP_MPMQ_STOPPING;
267 trawick 94106
268 trawick 94031 /* in case we weren't called from the listener thread, wake up the
269     * listener thread
270     */
271     wakeup_listener();
272    
273 trawick 94106 /* for ungraceful termination, let the workers exit now;
274     * for graceful termination, the listener thread will notify the
275     * workers to exit once it has stopped accepting new connections
276     */
277     if (mode == ST_UNGRACEFUL) {
278     workers_may_exit = 1;
279     ap_queue_interrupt_all(worker_queue);
280 aaron 94824 ap_queue_info_term(worker_queue_info);
281 jerenkrantz 94886 close_worker_sockets(); /* forcefully kill all current connections */
282 trawick 94106 }
283 rbb 89827 }
284    
285 rbb 89781 AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result)
286     {
287     switch(query_code){
288     case AP_MPMQ_MAX_DAEMON_USED:
289     *result = ap_max_daemons_limit;
290     return APR_SUCCESS;
291     case AP_MPMQ_IS_THREADED:
292     *result = AP_MPMQ_STATIC;
293     return APR_SUCCESS;
294     case AP_MPMQ_IS_FORKED:
295     *result = AP_MPMQ_DYNAMIC;
296     return APR_SUCCESS;
297     case AP_MPMQ_HARD_LIMIT_DAEMONS:
298 trawick 92530 *result = server_limit;
299 rbb 89781 return APR_SUCCESS;
300     case AP_MPMQ_HARD_LIMIT_THREADS:
301 trawick 92530 *result = thread_limit;
302 rbb 89781 return APR_SUCCESS;
303     case AP_MPMQ_MAX_THREADS:
304     *result = ap_threads_per_child;
305     return APR_SUCCESS;
306 jwoolley 91777 case AP_MPMQ_MIN_SPARE_DAEMONS:
307 rbb 89781 *result = 0;
308     return APR_SUCCESS;
309 jim 332309 case AP_MPMQ_MIN_SPARE_THREADS:
310 rbb 89781 *result = min_spare_threads;
311     return APR_SUCCESS;
312     case AP_MPMQ_MAX_SPARE_DAEMONS:
313     *result = 0;
314     return APR_SUCCESS;
315     case AP_MPMQ_MAX_SPARE_THREADS:
316     *result = max_spare_threads;
317     return APR_SUCCESS;
318 jwoolley 91777 case AP_MPMQ_MAX_REQUESTS_DAEMON:
319 rbb 89781 *result = ap_max_requests_per_child;
320     return APR_SUCCESS;
321     case AP_MPMQ_MAX_DAEMONS:
322     *result = ap_daemons_limit;
323     return APR_SUCCESS;
324 trawick 102045 case AP_MPMQ_MPM_STATE:
325     *result = mpm_state;
326     return APR_SUCCESS;
327 rbb 89781 }
328     return APR_ENOTIMPL;
329     }
330    
331 jim 332309 /* a clean exit from a child with proper cleanup */
332 rbb 89781 static void clean_child_exit(int code) __attribute__ ((noreturn));
333     static void clean_child_exit(int code)
334     {
335 trawick 102045 mpm_state = AP_MPMQ_STOPPING;
336 rbb 89781 if (pchild) {
337 jerenkrantz 92473 apr_pool_destroy(pchild);
338 rbb 89781 }
339     exit(code);
340     }
341    
342     static void just_die(int sig)
343     {
344     clean_child_exit(0);
345     }
346    
347     /*****************************************************************
348     * Connection structures and accounting...
349     */
350    
351     /* volatile just in case */
352     static int volatile shutdown_pending;
353     static int volatile restart_pending;
354     static int volatile is_graceful;
355 trawick 92019 static volatile int child_fatal;
356 rbb 89781 ap_generation_t volatile ap_my_generation;
357    
358     /*
359     * ap_start_shutdown() and ap_start_restart(), below, are a first stab at
360 jim 332309 * functions to initiate shutdown or restart without relying on signals.
361     * Previously this was initiated in sig_term() and restart() signal handlers,
362 rbb 89781 * but we want to be able to start a shutdown/restart from other sources --
363     * e.g. on Win32, from the service manager. Now the service manager can
364     * call ap_start_shutdown() or ap_start_restart() as appropiate. Note that
365     * these functions can also be called by the child processes, since global
366     * variables are no longer used to pass on the required action to the parent.
367     *
368     * These should only be called from the parent process itself, since the
369     * parent process will use the shutdown_pending and restart_pending variables
370     * to determine whether to shutdown or restart. The child process should
371     * call signal_parent() directly to tell the parent to die -- this will
372     * cause neither of those variable to be set, which the parent will
373     * assume means something serious is wrong (which it will be, for the
374     * child to force an exit) and so do an exit anyway.
375     */
376    
377 colm 290189 static void ap_start_shutdown(int graceful)
378 rbb 89781 {
379 trawick 102045 mpm_state = AP_MPMQ_STOPPING;
380 rbb 89781 if (shutdown_pending == 1) {
381 jerenkrantz 92473 /* Um, is this _probably_ not an error, if the user has
382     * tried to do a shutdown twice quickly, so we won't
383     * worry about reporting it.
384     */
385     return;
386 rbb 89781 }
387     shutdown_pending = 1;
388 colm 290189 is_graceful = graceful;
389 rbb 89781 }
390    
391     /* do a graceful restart if graceful == 1 */
392     static void ap_start_restart(int graceful)
393     {
394 trawick 102045 mpm_state = AP_MPMQ_STOPPING;
395 rbb 89781 if (restart_pending == 1) {
396 jerenkrantz 92473 /* Probably not an error - don't bother reporting it */
397     return;
398 rbb 89781 }
399     restart_pending = 1;
400     is_graceful = graceful;
401     }
402    
403     static void sig_term(int sig)
404     {
405 colm 290189 ap_start_shutdown(sig == AP_SIG_GRACEFUL_STOP);
406 rbb 89781 }
407    
408     static void restart(int sig)
409     {
410 jerenkrantz 91076 ap_start_restart(sig == AP_SIG_GRACEFUL);
411 rbb 89781 }
412    
413     static void set_signals(void)
414     {
415     #ifndef NO_USE_SIGACTION
416     struct sigaction sa;
417 trawick 99312 #endif
418 rbb 89781
419 trawick 99312 if (!one_process) {
420     ap_fatal_signal_setup(ap_server_conf, pconf);
421     }
422    
423     #ifndef NO_USE_SIGACTION
424 rbb 89781 sigemptyset(&sa.sa_mask);
425     sa.sa_flags = 0;
426    
427     sa.sa_handler = sig_term;
428     if (sigaction(SIGTERM, &sa, NULL) < 0)
429 jim 332309 ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
430 jerenkrantz 92473 "sigaction(SIGTERM)");
431 colm 290189 #ifdef AP_SIG_GRACEFUL_STOP
432     if (sigaction(AP_SIG_GRACEFUL_STOP, &sa, NULL) < 0)
433 jim 332309 ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
434 colm 290189 "sigaction(" AP_SIG_GRACEFUL_STOP_STRING ")");
435     #endif
436 rbb 89781 #ifdef SIGINT
437     if (sigaction(SIGINT, &sa, NULL) < 0)
438 jim 332309 ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
439 jerenkrantz 92473 "sigaction(SIGINT)");
440 rbb 89781 #endif
441     #ifdef SIGXCPU
442     sa.sa_handler = SIG_DFL;
443     if (sigaction(SIGXCPU, &sa, NULL) < 0)
444 jim 332309 ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
445 jerenkrantz 92473 "sigaction(SIGXCPU)");
446 rbb 89781 #endif
447     #ifdef SIGXFSZ
448     sa.sa_handler = SIG_DFL;
449     if (sigaction(SIGXFSZ, &sa, NULL) < 0)
450 jim 332309 ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
451 jerenkrantz 92473 "sigaction(SIGXFSZ)");
452 rbb 89781 #endif
453     #ifdef SIGPIPE
454     sa.sa_handler = SIG_IGN;
455     if (sigaction(SIGPIPE, &sa, NULL) < 0)
456 jim 332309 ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
457 jerenkrantz 92473 "sigaction(SIGPIPE)");
458 rbb 89781 #endif
459    
460 jim 332309 /* we want to ignore HUPs and AP_SIG_GRACEFUL while we're busy
461 jerenkrantz 91076 * processing one */
462 rbb 89781 sigaddset(&sa.sa_mask, SIGHUP);
463 jerenkrantz 91076 sigaddset(&sa.sa_mask, AP_SIG_GRACEFUL);
464 rbb 89781 sa.sa_handler = restart;
465     if (sigaction(SIGHUP, &sa, NULL) < 0)
466 jim 332309 ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
467 jerenkrantz 92473 "sigaction(SIGHUP)");
468 jerenkrantz 91076 if (sigaction(AP_SIG_GRACEFUL, &sa, NULL) < 0)
469 jim 332309 ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
470 jerenkrantz 92473 "sigaction(" AP_SIG_GRACEFUL_STRING ")");
471 rbb 89781 #else
472     if (!one_process) {
473     #ifdef SIGXCPU
474 jerenkrantz 92473 apr_signal(SIGXCPU, SIG_DFL);
475 rbb 89781 #endif /* SIGXCPU */
476     #ifdef SIGXFSZ
477 jerenkrantz 92473 apr_signal(SIGXFSZ, SIG_DFL);
478 rbb 89781 #endif /* SIGXFSZ */
479     }
480    
481     apr_signal(SIGTERM, sig_term);
482     #ifdef SIGHUP
483     apr_signal(SIGHUP, restart);
484     #endif /* SIGHUP */
485 jerenkrantz 91076 #ifdef AP_SIG_GRACEFUL
486     apr_signal(AP_SIG_GRACEFUL, restart);
487     #endif /* AP_SIG_GRACEFUL */
488 colm 290189 #ifdef AP_SIG_GRACEFUL_STOP
489     apr_signal(AP_SIG_GRACEFUL_STOP, sig_term);
490     #endif /* AP_SIG_GRACEFUL_STOP */
491 rbb 89781 #ifdef SIGPIPE
492     apr_signal(SIGPIPE, SIG_IGN);
493     #endif /* SIGPIPE */
494    
495     #endif
496     }
497    
498     /*****************************************************************
499     * Here follows a long bunch of generic server bookkeeping stuff...
500     */
501    
502     int ap_graceful_stop_signalled(void)
503 gregames 89881 /* XXX this is really a bad confusing obsolete name
504     * maybe it should be ap_mpm_process_exiting?
505     */
506 rbb 89781 {
507 trawick 94095 /* note: for a graceful termination, listener_may_exit will be set before
508     * workers_may_exit, so check listener_may_exit
509     */
510     return listener_may_exit;
511 rbb 89781 }
512    
513     /*****************************************************************
514     * Child process main loop.
515     */
516    
517 jerenkrantz 92473 static void process_socket(apr_pool_t *p, apr_socket_t *sock, int my_child_num,
518 jwoolley 94304 int my_thread_num, apr_bucket_alloc_t *bucket_alloc)
519 rbb 89781 {
520     conn_rec *current_conn;
521 trawick 92512 long conn_id = ID_FROM_CHILD_THREAD(my_child_num, my_thread_num);
522 rbb 89781 int csd;
523 wrowe 92791 ap_sb_handle_t *sbh;
524 rbb 89781
525 trawick 92512 ap_create_sb_handle(&sbh, p, my_child_num, my_thread_num);
526 jwoolley 91082 apr_os_sock_get(&csd, sock);
527 rbb 89781
528 jwoolley 94304 current_conn = ap_run_create_connection(p, ap_server_conf, sock,
529     conn_id, sbh, bucket_alloc);
530 rbb 89781 if (current_conn) {
531 stoddard 93087 ap_process_connection(current_conn, sock);
532 rbb 91968 ap_lingering_close(current_conn);
533 rbb 89781 }
534     }
535    
536     /* requests_this_child has gone to zero or below. See if the admin coded
537     "MaxRequestsPerChild 0", and keep going in that case. Doing it this way
538     simplifies the hot path in worker_thread */
539     static void check_infinite_requests(void)
540     {
541     if (ap_max_requests_per_child) {
542 trawick 94095 signal_threads(ST_GRACEFUL);
543 rbb 89781 }
544     else {
545     /* wow! if you're executing this code, you may have set a record.
546     * either this child process has served over 2 billion requests, or
547 jim 332309 * you're running a threaded 2.0 on a 16 bit machine.
548 rbb 89781 *
549     * I'll buy pizza and beers at Apachecon for the first person to do
550     * the former without cheating (dorking with INT_MAX, or running with
551 jim 332309 * uncommitted performance patches, for example).
552 rbb 89781 *
553     * for the latter case, you probably deserve a beer too. Greg Ames
554     */
555 jim 332309
556     requests_this_child = INT_MAX; /* keep going */
557 rbb 89781 }
558     }
559    
560 trawick 94232 static void unblock_signal(int sig)
561 trawick 94031 {
562 trawick 94232 sigset_t sig_mask;
563    
564     sigemptyset(&sig_mask);
565     sigaddset(&sig_mask, sig);
566     #if defined(SIGPROCMASK_SETS_THREAD_MASK)
567     sigprocmask(SIG_UNBLOCK, &sig_mask, NULL);
568     #else
569     pthread_sigmask(SIG_UNBLOCK, &sig_mask, NULL);
570     #endif
571     }
572    
573     static void dummy_signal_handler(int sig)
574     {
575 trawick 94031 /* XXX If specifying SIG_IGN is guaranteed to unblock a syscall,
576     * then we don't need this goofy function.
577     */
578     }
579    
580 rbb 89781 static void *listener_thread(apr_thread_t *thd, void * dummy)
581     {
582     proc_info * ti = dummy;
583     int process_slot = ti->pid;
584 rbb 90635 apr_pool_t *tpool = apr_thread_pool_get(thd);
585 rbb 91955 void *csd = NULL;
586 trawick 307222 apr_pool_t *ptrans = NULL; /* Pool for per-transaction stuff */
587 gstein 101801 apr_pollset_t *pollset;
588 rbb 89781 apr_status_t rv;
589 gstein 101801 ap_listen_rec *lr;
590 brianp 95270 int have_idle_worker = 0;
591 gstein 101801 int last_poll_idx = 0;
592 rbb 89781
593     free(ti);
594    
595 gstein 101801 /* ### check the status */
596     (void) apr_pollset_create(&pollset, num_listensocks, tpool, 0);
597 rbb 89781
598 gstein 101801 for (lr = ap_listeners; lr != NULL; lr = lr->next) {
599     apr_pollfd_t pfd = { 0 };
600    
601     pfd.desc_type = APR_POLL_SOCKET;
602     pfd.desc.s = lr->sd;
603     pfd.reqevents = APR_POLLIN;
604     pfd.client_data = lr;
605    
606     /* ### check the status */
607     (void) apr_pollset_add(pollset, &pfd);
608     }
609    
610 trawick 94031 /* Unblock the signal used to wake this thread up, and set a handler for
611     * it.
612     */
613 trawick 94232 unblock_signal(LISTENER_SIGNAL);
614     apr_signal(LISTENER_SIGNAL, dummy_signal_handler);
615 trawick 94031
616 rbb 89781 /* TODO: Switch to a system where threads reuse the results from earlier
617     poll calls - manoj */
618     while (1) {
619 rbb 90635 /* TODO: requests_this_child should be synchronized - aaron */
620 rbb 89781 if (requests_this_child <= 0) {
621     check_infinite_requests();
622     }
623 trawick 94095 if (listener_may_exit) break;
624 rbb 89781
625 brianp 95270 if (!have_idle_worker) {
626 trawick 307222 /* the following pops a recycled ptrans pool off a stack
627     * if there is one, in addition to reserving a worker thread
628     */
629 brianp 95270 rv = ap_queue_info_wait_for_idler(worker_queue_info,
630 trawick 307222 &ptrans);
631 brianp 95270 if (APR_STATUS_IS_EOF(rv)) {
632     break; /* we've been signaled to die now */
633     }
634     else if (rv != APR_SUCCESS) {
635     ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf,
636     "apr_queue_info_wait failed. Attempting to "
637     " shutdown process gracefully.");
638     signal_threads(ST_GRACEFUL);
639     break;
640     }
641     have_idle_worker = 1;
642 aaron 94824 }
643 jim 332309
644 aaron 94824 /* We've already decremented the idle worker count inside
645     * ap_queue_info_wait_for_idler. */
646    
647 aaron 91580 if ((rv = SAFE_ACCEPT(apr_proc_mutex_lock(accept_mutex)))
648 rbb 89781 != APR_SUCCESS) {
649 trawick 93720 int level = APLOG_EMERG;
650    
651 trawick 94095 if (listener_may_exit) {
652 trawick 94031 break;
653     }
654 jim 332309 if (ap_scoreboard_image->parent[process_slot].generation !=
655 trawick 93720 ap_scoreboard_image->global->running_generation) {
656     level = APLOG_DEBUG; /* common to get these at restart time */
657     }
658     ap_log_error(APLOG_MARK, level, rv, ap_server_conf,
659 aaron 91582 "apr_proc_mutex_lock failed. Attempting to shutdown "
660 rbb 89781 "process gracefully.");
661 trawick 94095 signal_threads(ST_GRACEFUL);
662 trawick 93718 break; /* skip the lock release */
663 rbb 89781 }
664    
665 brianp 93096 if (!ap_listeners->next) {
666     /* Only one listener, so skip the poll */
667     lr = ap_listeners;
668     }
669     else {
670 trawick 94095 while (!listener_may_exit) {
671 gstein 101801 apr_int32_t numdesc;
672     const apr_pollfd_t *pdesc;
673 rbb 89781
674 gstein 101801 rv = apr_pollset_poll(pollset, -1, &numdesc, &pdesc);
675     if (rv != APR_SUCCESS) {
676     if (APR_STATUS_IS_EINTR(rv)) {
677 brianp 93096 continue;
678     }
679    
680 trawick 102045 /* apr_pollset_poll() will only return errors in catastrophic
681 brianp 93096 * circumstances. Let's try exiting gracefully, for now. */
682 gstein 101801 ap_log_error(APLOG_MARK, APLOG_ERR, rv,
683     (const server_rec *) ap_server_conf,
684     "apr_pollset_poll: (listen)");
685 trawick 94095 signal_threads(ST_GRACEFUL);
686 rbb 89781 }
687    
688 trawick 94095 if (listener_may_exit) break;
689 rbb 89781
690 gstein 101801 /* We can always use pdesc[0], but sockets at position N
691     * could end up completely starved of attention in a very
692     * busy server. Therefore, we round-robin across the
693     * returned set of descriptors. While it is possible that
694     * the returned set of descriptors might flip around and
695     * continue to starve some sockets, we happen to know the
696     * internal pollset implementation retains ordering
697     * stability of the sockets. Thus, the round-robin should
698     * ensure that a socket will eventually be serviced.
699     */
700     if (last_poll_idx >= numdesc)
701     last_poll_idx = 0;
702    
703     /* Grab a listener record from the client_data of the poll
704     * descriptor, and advance our saved index to round-robin
705     * the next fetch.
706     *
707     * ### hmm... this descriptor might have POLLERR rather
708     * ### than POLLIN
709     */
710     lr = pdesc[last_poll_idx++].client_data;
711     break;
712    
713     } /* while */
714    
715     } /* if/else */
716    
717 trawick 94095 if (!listener_may_exit) {
718 trawick 307222 if (ptrans == NULL) {
719     /* we can't use a recycled transaction pool this time.
720     * create a new transaction pool */
721 striker 93943 apr_allocator_t *allocator;
722    
723     apr_allocator_create(&allocator);
724 striker 95954 apr_allocator_max_free_set(allocator, ap_max_mem_free);
725 jorton 170896 apr_pool_create_ex(&ptrans, pconf, NULL, allocator);
726 striker 95373 apr_allocator_owner_set(allocator, ptrans);
727 brianp 93386 }
728 brianp 92482 apr_pool_tag(ptrans, "transaction");
729 rbb 91960 rv = lr->accept_func(&csd, lr, ptrans);
730 trawick 94625 /* later we trash rv and rely on csd to indicate success/failure */
731     AP_DEBUG_ASSERT(rv == APR_SUCCESS || !csd);
732 rbb 91955
733     if (rv == APR_EGENERAL) {
734 gregames 93366 /* E[NM]FILE, ENOMEM, etc */
735     resource_shortage = 1;
736 trawick 94095 signal_threads(ST_GRACEFUL);
737 rbb 89781 }
738 aaron 91580 if ((rv = SAFE_ACCEPT(apr_proc_mutex_unlock(accept_mutex)))
739 rbb 89781 != APR_SUCCESS) {
740 trawick 93720 int level = APLOG_EMERG;
741    
742 trawick 94095 if (listener_may_exit) {
743 trawick 94031 break;
744     }
745 jim 332309 if (ap_scoreboard_image->parent[process_slot].generation !=
746 trawick 93720 ap_scoreboard_image->global->running_generation) {
747     level = APLOG_DEBUG; /* common to get these at restart time */
748     }
749     ap_log_error(APLOG_MARK, level, rv, ap_server_conf,
750 trawick 93719 "apr_proc_mutex_unlock failed. Attempting to "
751 aaron 91582 "shutdown process gracefully.");
752 trawick 94095 signal_threads(ST_GRACEFUL);
753 rbb 89781 }
754     if (csd != NULL) {
755 brianp 94830 rv = ap_queue_push(worker_queue, csd, ptrans);
756 trawick 91089 if (rv) {
757     /* trash the connection; we couldn't queue the connected
758 jim 332309 * socket to a worker
759 trawick 91089 */
760     apr_socket_close(csd);
761 trawick 93530 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,
762     "ap_queue_push failed");
763 trawick 91089 }
764 brianp 95270 else {
765     have_idle_worker = 0;
766     }
767 rbb 89781 }
768     }
769     else {
770 aaron 91580 if ((rv = SAFE_ACCEPT(apr_proc_mutex_unlock(accept_mutex)))
771 rbb 89781 != APR_SUCCESS) {
772 trawick 179317 int level = APLOG_EMERG;
773    
774 jim 332309 if (ap_scoreboard_image->parent[process_slot].generation !=
775 trawick 179317 ap_scoreboard_image->global->running_generation) {
776     level = APLOG_DEBUG; /* common to get these at restart time */
777     }
778     ap_log_error(APLOG_MARK, level, rv, ap_server_conf,
779 aaron 91582 "apr_proc_mutex_unlock failed. Attempting to "
780     "shutdown process gracefully.");
781 trawick 94095 signal_threads(ST_GRACEFUL);
782 rbb 89781 }
783     break;
784     }
785     }
786    
787 colm 290179 ap_close_listeners();
788 trawick 94106 ap_queue_term(worker_queue);
789 rbb 89781 dying = 1;
790 rbb 90065 ap_scoreboard_image->parent[process_slot].quiescing = 1;
791 trawick 94112
792 trawick 94232 /* wake up the main thread */
793 rbb 90065 kill(ap_my_pid, SIGTERM);
794 rbb 89781
795 rbb 90635 apr_thread_exit(thd, APR_SUCCESS);
796 rbb 89781 return NULL;
797     }
798    
799 trawick 94068 /* XXX For ungraceful termination/restart, we definitely don't want to
800     * wait for active connections to finish but we may want to wait
801     * for idle workers to get out of the queue code and release mutexes,
802     * since those mutexes are cleaned up pretty soon and some systems
803     * may not react favorably (i.e., segfault) if operations are attempted
804     * on cleaned-up mutexes.
805     */
806 wrowe 93264 static void * APR_THREAD_FUNC worker_thread(apr_thread_t *thd, void * dummy)
807 rbb 89781 {
808     proc_info * ti = dummy;
809     int process_slot = ti->pid;
810     int thread_slot = ti->tid;
811     apr_socket_t *csd = NULL;
812 jwoolley 94304 apr_bucket_alloc_t *bucket_alloc;
813 brianp 93386 apr_pool_t *last_ptrans = NULL;
814 jerenkrantz 92473 apr_pool_t *ptrans; /* Pool for per-transaction stuff */
815 rbb 90635 apr_status_t rv;
816 brianp 95270 int is_idle = 0;
817 rbb 89781
818     free(ti);
819    
820 trawick 156274 ap_scoreboard_image->servers[process_slot][thread_slot].pid = ap_my_pid;
821     ap_scoreboard_image->servers[process_slot][thread_slot].generation = ap_my_generation;
822 trawick 92512 ap_update_child_status_from_indexes(process_slot, thread_slot, SERVER_STARTING, NULL);
823 jwoolley 94304
824 rbb 89781 while (!workers_may_exit) {
825 brianp 95270 if (!is_idle) {
826     rv = ap_queue_info_set_idle(worker_queue_info, last_ptrans);
827     last_ptrans = NULL;
828     if (rv != APR_SUCCESS) {
829     ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf,
830     "ap_queue_info_set_idle failed. Attempting to "
831     "shutdown process gracefully.");
832     signal_threads(ST_GRACEFUL);
833     break;
834     }
835     is_idle = 1;
836 aaron 94824 }
837    
838 trawick 92512 ap_update_child_status_from_indexes(process_slot, thread_slot, SERVER_READY, NULL);
839 aaron 94840 worker_pop:
840     if (workers_may_exit) {
841     break;
842     }
843 brianp 94830 rv = ap_queue_pop(worker_queue, &csd, &ptrans);
844 brianp 93386
845 trawick 94067 if (rv != APR_SUCCESS) {
846 trawick 94106 /* We get APR_EOF during a graceful shutdown once all the connections
847     * accepted by this server process have been handled.
848     */
849 aaron 94840 if (APR_STATUS_IS_EOF(rv)) {
850 trawick 94106 break;
851     }
852 trawick 94067 /* We get APR_EINTR whenever ap_queue_pop() has been interrupted
853     * from an explicit call to ap_queue_interrupt_all(). This allows
854     * us to unblock threads stuck in ap_queue_pop() when a shutdown
855     * is pending.
856 trawick 94068 *
857     * If workers_may_exit is set and this is ungraceful termination/
858     * restart, we are bound to get an error on some systems (e.g.,
859     * AIX, which sanity-checks mutex operations) since the queue
860     * may have already been cleaned up. Don't log the "error" if
861     * workers_may_exit is set.
862 trawick 94067 */
863 aaron 94840 else if (APR_STATUS_IS_EINTR(rv)) {
864     goto worker_pop;
865     }
866     /* We got some other error. */
867     else if (!workers_may_exit) {
868 trawick 94067 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,
869     "ap_queue_pop failed");
870     }
871 rbb 90065 continue;
872     }
873 brianp 95270 is_idle = 0;
874 jerenkrantz 94886 worker_sockets[thread_slot] = csd;
875 jwoolley 101122 bucket_alloc = apr_bucket_alloc_create(ptrans);
876 jwoolley 94304 process_socket(ptrans, csd, process_slot, thread_slot, bucket_alloc);
877 jerenkrantz 94886 worker_sockets[thread_slot] = NULL;
878 rbb 90635 requests_this_child--; /* FIXME: should be synchronized - aaron */
879 brianp 93386 apr_pool_clear(ptrans);
880     last_ptrans = ptrans;
881 rbb 89781 }
882    
883 trawick 92512 ap_update_child_status_from_indexes(process_slot, thread_slot,
884 rbb 90771 (dying) ? SERVER_DEAD : SERVER_GRACEFUL, (request_rec *) NULL);
885 rbb 89781
886 aaron 92622 apr_thread_exit(thd, APR_SUCCESS);
887 rbb 89781 return NULL;
888     }
889    
890 aaron 93403 static int check_signal(int signum)
891     {
892     switch (signum) {
893     case SIGTERM:
894     case SIGINT:
895     return 1;
896     }
897     return 0;
898     }
899    
900 trawick 94420 static void create_listener_thread(thread_starter *ts)
901     {
902     int my_child_num = ts->child_num_arg;
903     apr_threadattr_t *thread_attr = ts->threadattr;
904     proc_info *my_info;
905     apr_status_t rv;
906    
907     my_info = (proc_info *)malloc(sizeof(proc_info));
908     my_info->pid = my_child_num;
909     my_info->tid = -1; /* listener thread doesn't have a thread slot */
910     my_info->sd = 0;
911     rv = apr_thread_create(&ts->listener, thread_attr, listener_thread,
912 trawick 94700 my_info, pchild);
913 trawick 94420 if (rv != APR_SUCCESS) {
914     ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
915     "apr_thread_create: unable to create listener thread");
916 gregames 168182 /* let the parent decide how bad this really is */
917     clean_child_exit(APEXIT_CHILDSICK);
918 trawick 94420 }
919     apr_os_thread_get(&listener_os_thread, ts->listener);
920     }
921    
922 trawick 94059 /* XXX under some circumstances not understood, children can get stuck
923     * in start_threads forever trying to take over slots which will
924     * never be cleaned up; for now there is an APLOG_DEBUG message issued
925     * every so often when this condition occurs
926 trawick 94030 */
927 wrowe 93264 static void * APR_THREAD_FUNC start_threads(apr_thread_t *thd, void *dummy)
928 rbb 89781 {
929     thread_starter *ts = dummy;
930     apr_thread_t **threads = ts->threads;
931     apr_threadattr_t *thread_attr = ts->threadattr;
932     int child_num_arg = ts->child_num_arg;
933     int my_child_num = child_num_arg;
934 trawick 94420 proc_info *my_info;
935 rbb 89781 apr_status_t rv;
936 trawick 94420 int i;
937 rbb 89781 int threads_created = 0;
938 stoddard 94889 int listener_started = 0;
939 trawick 94059 int loops;
940     int prev_threads_created;
941 rbb 89781
942 rbb 90771 /* We must create the fd queues before we start up the listener
943 rbb 90635 * and worker threads. */
944 rbb 91075 worker_queue = apr_pcalloc(pchild, sizeof(*worker_queue));
945 trawick 93530 rv = ap_queue_init(worker_queue, ap_threads_per_child, pchild);
946     if (rv != APR_SUCCESS) {
947     ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
948     "ap_queue_init() failed");
949     clean_child_exit(APEXIT_CHILDFATAL);
950     }
951 rbb 90635
952 brianp 94830 rv = ap_queue_info_create(&worker_queue_info, pchild,
953     ap_threads_per_child);
954 aaron 94824 if (rv != APR_SUCCESS) {
955     ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
956     "ap_queue_info_create() failed");
957     clean_child_exit(APEXIT_CHILDFATAL);
958     }
959    
960 jerenkrantz 94886 worker_sockets = apr_pcalloc(pchild, ap_threads_per_child
961     * sizeof(apr_socket_t *));
962    
963 trawick 94059 loops = prev_threads_created = 0;
964 rbb 89781 while (1) {
965 dougm 90673 /* ap_threads_per_child does not include the listener thread */
966 dougm 90670 for (i = 0; i < ap_threads_per_child; i++) {
967 rbb 89781 int status = ap_scoreboard_image->servers[child_num_arg][i].status;
968    
969     if (status != SERVER_GRACEFUL && status != SERVER_DEAD) {
970     continue;
971     }
972    
973 aaron 92632 my_info = (proc_info *)malloc(sizeof(proc_info));
974 rbb 89781 if (my_info == NULL) {
975     ap_log_error(APLOG_MARK, APLOG_ALERT, errno, ap_server_conf,
976 jerenkrantz 92473 "malloc: out of memory");
977 rbb 89781 clean_child_exit(APEXIT_CHILDFATAL);
978     }
979 jerenkrantz 92473 my_info->pid = my_child_num;
980 rbb 89781 my_info->tid = i;
981 jerenkrantz 92473 my_info->sd = 0;
982 jim 332309
983 aaron 92632 /* We are creating threads right now */
984     ap_update_child_status_from_indexes(my_child_num, i,
985     SERVER_STARTING, NULL);
986 rbb 89781 /* We let each thread update its own scoreboard entry. This is
987     * done because it lets us deal with tid better.
988 jerenkrantz 92473 */
989 jim 332309 rv = apr_thread_create(&threads[i], thread_attr,
990 trawick 94700 worker_thread, my_info, pchild);
991 aaron 92632 if (rv != APR_SUCCESS) {
992 jerenkrantz 92473 ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
993 aaron 92632 "apr_thread_create: unable to create worker thread");
994 gregames 168182 /* let the parent decide how bad this really is */
995     clean_child_exit(APEXIT_CHILDSICK);
996 jerenkrantz 92473 }
997 rbb 89781 threads_created++;
998     }
999 stoddard 94889 /* Start the listener only when there are workers available */
1000     if (!listener_started && threads_created) {
1001     create_listener_thread(ts);
1002     listener_started = 1;
1003     }
1004 trawick 94095 if (start_thread_may_exit || threads_created == ap_threads_per_child) {
1005 rbb 89781 break;
1006     }
1007 wrowe 93264 /* wait for previous generation to clean up an entry */
1008 brianp 95959 apr_sleep(apr_time_from_sec(1));
1009 trawick 94059 ++loops;
1010     if (loops % 120 == 0) { /* every couple of minutes */
1011     if (prev_threads_created == threads_created) {
1012     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
1013     "child %" APR_PID_T_FMT " isn't taking over "
1014     "slots very quickly (%d of %d)",
1015     ap_my_pid, threads_created, ap_threads_per_child);
1016     }
1017     prev_threads_created = threads_created;
1018     }
1019 rbb 89781 }
1020 jim 332309
1021     /* What state should this child_main process be listed as in the
1022 jerenkrantz 92473 * scoreboard...?
1023 jim 332309 * ap_update_child_status_from_indexes(my_child_num, i, SERVER_STARTING,
1024 trawick 92512 * (request_rec *) NULL);
1025 jim 332309 *
1026 rbb 89781 * This state should be listed separately in the scoreboard, in some kind
1027 jim 332309 * of process_status, not mixed in with the worker threads' status.
1028     * "life_status" is almost right, but it's in the worker's structure, and
1029 rbb 89781 * the name could be clearer. gla
1030     */
1031 aaron 92622 apr_thread_exit(thd, APR_SUCCESS);
1032 rbb 89781 return NULL;
1033     }
1034    
1035 trawick 94031 static void join_workers(apr_thread_t *listener, apr_thread_t **threads)
1036 trawick 93561 {
1037     int i;
1038     apr_status_t rv, thread_rv;
1039    
1040 trawick 94031 if (listener) {
1041     int iter;
1042 jim 332309
1043 trawick 94031 /* deal with a rare timing window which affects waking up the
1044     * listener thread... if the signal sent to the listener thread
1045     * is delivered between the time it verifies that the
1046 trawick 94095 * listener_may_exit flag is clear and the time it enters a
1047 trawick 94031 * blocking syscall, the signal didn't do any good... work around
1048     * that by sleeping briefly and sending it again
1049     */
1050    
1051     iter = 0;
1052 jim 332309 while (iter < 10 &&
1053 trawick 94417 #ifdef HAVE_PTHREAD_KILL
1054     pthread_kill(*listener_os_thread, 0)
1055     #else
1056     kill(ap_my_pid, 0)
1057     #endif
1058     == 0) {
1059 trawick 94031 /* listener not dead yet */
1060 brianp 95959 apr_sleep(apr_time_make(0, 500000));
1061 trawick 94031 wakeup_listener();
1062     ++iter;
1063     }
1064     if (iter >= 10) {
1065 trawick 101165 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
1066 trawick 94031 "the listener thread didn't exit");
1067     }
1068     else {
1069     rv = apr_thread_join(&thread_rv, listener);
1070     if (rv != APR_SUCCESS) {
1071     ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,
1072     "apr_thread_join: unable to join listener thread");
1073     }
1074     }
1075     }
1076 jim 332309
1077 trawick 93561 for (i = 0; i < ap_threads_per_child; i++) {
1078     if (threads[i]) { /* if we ever created this thread */
1079     rv = apr_thread_join(&thread_rv, threads[i]);
1080     if (rv != APR_SUCCESS) {
1081     ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,
1082     "apr_thread_join: unable to join worker "
1083     "thread %d",
1084     i);
1085     }
1086     }
1087     }
1088     }
1089    
1090     static void join_start_thread(apr_thread_t *start_thread_id)
1091     {
1092     apr_status_t rv, thread_rv;
1093    
1094 jim 332309 start_thread_may_exit = 1; /* tell it to give up in case it is still
1095     * trying to take over slots from a
1096 trawick 94095 * previous generation
1097     */
1098 trawick 93561 rv = apr_thread_join(&thread_rv, start_thread_id);
1099     if (rv != APR_SUCCESS) {
1100     ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf,
1101     "apr_thread_join: unable to join the start "
1102     "thread");
1103     }
1104     }
1105    
1106 rbb 89781 static void child_main(int child_num_arg)
1107     {
1108     apr_thread_t **threads;
1109     apr_status_t rv;
1110     thread_starter *ts;
1111     apr_threadattr_t *thread_attr;
1112     apr_thread_t *start_thread_id;
1113    
1114 trawick 102045 mpm_state = AP_MPMQ_STARTING; /* for benefit of any hooks that run as this
1115     * child initializes
1116     */
1117 rbb 89781 ap_my_pid = getpid();
1118 trawick 99312 ap_fatal_signal_child_setup(ap_server_conf);
1119 rbb 89781 apr_pool_create(&pchild, pconf);
1120    
1121     /*stuff to do before we switch id's, so we have permissions.*/
1122 rbb 93119 ap_reopen_scoreboard(pchild, NULL, 0);
1123 rbb 89781
1124 trawick 92412 rv = SAFE_ACCEPT(apr_proc_mutex_child_init(&accept_mutex, ap_lock_fname,
1125 aaron 91580 pchild));
1126 rbb 89781 if (rv != APR_SUCCESS) {
1127     ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf,
1128     "Couldn't initialize cross-process lock in child");
1129     clean_child_exit(APEXIT_CHILDFATAL);
1130     }
1131    
1132     if (unixd_setup_child()) {
1133 jerenkrantz 92473 clean_child_exit(APEXIT_CHILDFATAL);
1134 rbb 89781 }
1135    
1136     ap_run_child_init(pchild, ap_server_conf);
1137    
1138 rbb 90771 /* done with init critical section */
1139 rbb 89781
1140 rbb 93358 /* Just use the standard apr_setup_signal_thread to block all signals
1141     * from being received. The child processes no longer use signals for
1142     * any communication with the parent process.
1143     */
1144 rbb 89781 rv = apr_setup_signal_thread();
1145     if (rv != APR_SUCCESS) {
1146     ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf,
1147     "Couldn't initialize signal thread");
1148     clean_child_exit(APEXIT_CHILDFATAL);
1149     }
1150    
1151     if (ap_max_requests_per_child) {
1152     requests_this_child = ap_max_requests_per_child;
1153     }
1154     else {
1155     /* coding a value of zero means infinity */
1156     requests_this_child = INT_MAX;
1157     }
1158 jim 332309
1159 rbb 89781 /* Setup worker threads */
1160    
1161 jim 332309 /* clear the storage; we may not create all our threads immediately,
1162 jerenkrantz 92473 * and we want a 0 entry to indicate a thread which was not created
1163 rbb 89781 */
1164 jim 332309 threads = (apr_thread_t **)calloc(1,
1165 jerenkrantz 92473 sizeof(apr_thread_t *) * ap_threads_per_child);
1166 rbb 89781 if (threads == NULL) {
1167     ap_log_error(APLOG_MARK, APLOG_ALERT, errno, ap_server_conf,
1168     "malloc: out of memory");
1169     clean_child_exit(APEXIT_CHILDFATAL);
1170     }
1171    
1172 rbb 90635 ts = (thread_starter *)apr_palloc(pchild, sizeof(*ts));
1173 rbb 89781
1174     apr_threadattr_create(&thread_attr, pchild);
1175 jerenkrantz 92473 /* 0 means PTHREAD_CREATE_JOINABLE */
1176     apr_threadattr_detach_set(thread_attr, 0);
1177 rbb 89781
1178 trawick 102975 if (ap_thread_stacksize != 0) {
1179     apr_threadattr_stacksize_set(thread_attr, ap_thread_stacksize);
1180 trawick 102931 }
1181 jim 332309
1182 rbb 89781 ts->threads = threads;
1183 trawick 94031 ts->listener = NULL;
1184 rbb 89781 ts->child_num_arg = child_num_arg;
1185     ts->threadattr = thread_attr;
1186    
1187 aaron 92632 rv = apr_thread_create(&start_thread_id, thread_attr, start_threads,
1188 trawick 94700 ts, pchild);
1189 aaron 92632 if (rv != APR_SUCCESS) {
1190 rbb 89781 ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
1191     "apr_thread_create: unable to create worker thread");
1192 gregames 168649 /* let the parent decide how bad this really is */
1193     clean_child_exit(APEXIT_CHILDSICK);
1194 rbb 89781 }
1195    
1196 trawick 102045 mpm_state = AP_MPMQ_RUNNING;
1197    
1198 aaron 93403 /* If we are only running in one_process mode, we will want to
1199     * still handle signals. */
1200     if (one_process) {
1201 trawick 94091 /* Block until we get a terminating signal. */
1202 aaron 93403 apr_signal_thread(check_signal);
1203 jim 332309 /* make sure the start thread has finished; signal_threads()
1204 trawick 93561 * and join_workers() depend on that
1205     */
1206 trawick 94094 /* XXX join_start_thread() won't be awakened if one of our
1207     * threads encounters a critical error and attempts to
1208     * shutdown this child
1209     */
1210 trawick 93561 join_start_thread(start_thread_id);
1211 trawick 94095 signal_threads(ST_UNGRACEFUL); /* helps us terminate a little more
1212     * quickly than the dispatch of the signal thread
1213 aaron 93403 * beats the Pipe of Death and the browsers
1214     */
1215     /* A terminating signal was received. Now join each of the
1216     * workers to clean them up.
1217     * If the worker already exited, then the join frees
1218     * their resources and returns.
1219     * If the worker hasn't exited, then this blocks until
1220     * they have (then cleans up).
1221 rbb 93358 */
1222 trawick 94031 join_workers(ts->listener, threads);
1223 rbb 89781 }
1224 aaron 93403 else { /* !one_process */
1225 trawick 94232 /* remove SIGTERM from the set of blocked signals... if one of
1226     * the other threads in the process needs to take us down
1227     * (e.g., for MaxRequestsPerChild) it will send us SIGTERM
1228     */
1229     unblock_signal(SIGTERM);
1230     apr_signal(SIGTERM, dummy_signal_handler);
1231 aaron 93403 /* Watch for any messages from the parent over the POD */
1232     while (1) {
1233     rv = ap_mpm_pod_check(pod);
1234 trawick 94232 if (rv == AP_NORESTART) {
1235     /* see if termination was triggered while we slept */
1236     switch(terminate_mode) {
1237     case ST_GRACEFUL:
1238     rv = AP_GRACEFUL;
1239     break;
1240     case ST_UNGRACEFUL:
1241     rv = AP_RESTART;
1242     break;
1243     }
1244     }
1245 aaron 93403 if (rv == AP_GRACEFUL || rv == AP_RESTART) {
1246 jim 332309 /* make sure the start thread has finished;
1247 trawick 94095 * signal_threads() and join_workers depend on that
1248 trawick 93561 */
1249     join_start_thread(start_thread_id);
1250 trawick 94095 signal_threads(rv == AP_GRACEFUL ? ST_GRACEFUL : ST_UNGRACEFUL);
1251 aaron 93403 break;
1252     }
1253     }
1254 rbb 89781
1255 trawick 94892 /* A terminating signal was received. Now join each of the
1256     * workers to clean them up.
1257     * If the worker already exited, then the join frees
1258     * their resources and returns.
1259     * If the worker hasn't exited, then this blocks until
1260     * they have (then cleans up).
1261     */
1262     join_workers(ts->listener, threads);
1263 aaron 93403 }
1264    
1265 rbb 89781 free(threads);
1266    
1267 gregames 93366 clean_child_exit(resource_shortage ? APEXIT_CHILDSICK : 0);
1268 rbb 89781 }
1269    
1270 jim 332309 static int make_child(server_rec *s, int slot)
1271 rbb 89781 {
1272     int pid;
1273    
1274     if (slot + 1 > ap_max_daemons_limit) {
1275 jerenkrantz 92473 ap_max_daemons_limit = slot + 1;
1276 rbb 89781 }
1277    
1278     if (one_process) {
1279 jerenkrantz 92473 set_signals();
1280 rbb 89781 ap_scoreboard_image->parent[slot].pid = getpid();
1281 jerenkrantz 92473 child_main(slot);
1282 rbb 89781 }
1283    
1284     if ((pid = fork()) == -1) {
1285 jim 332309 ap_log_error(APLOG_MARK, APLOG_ERR, errno, s,
1286 jerenkrantz 92473 "fork: Unable to fork new process");
1287 rbb 89781
1288     /* fork didn't succeed. Fix the scoreboard or else
1289     * it will say SERVER_STARTING forever and ever
1290     */
1291 trawick 92512 ap_update_child_status_from_indexes(slot, 0, SERVER_DEAD, NULL);
1292 rbb 89781
1293 jerenkrantz 92473 /* In case system resources are maxxed out, we don't want
1294     Apache running away with the CPU trying to fork over and
1295     over and over again. */
1296 brianp 95959 apr_sleep(apr_time_from_sec(10));
1297 rbb 89781
1298 jerenkrantz 92473 return -1;
1299 rbb 89781 }
1300    
1301     if (!pid) {
1302     #ifdef HAVE_BINDPROCESSOR
1303     /* By default, AIX binds to a single processor. This bit unbinds
1304 jerenkrantz 92473 * children which will then bind to another CPU.
1305 rbb 89781 */
1306     int status = bindprocessor(BINDPROCESS, (int)getpid(),
1307 jerenkrantz 92473 PROCESSOR_CLASS_ANY);
1308     if (status != OK)
1309 jim 332309 ap_log_error(APLOG_MARK, APLOG_WARNING, errno,
1310 jerenkrantz 92473 ap_server_conf,
1311     "processor unbind failed %d", status);
1312 rbb 89781 #endif
1313     RAISE_SIGSTOP(MAKE_CHILD);
1314    
1315     apr_signal(SIGTERM, just_die);
1316     child_main(slot);
1317    
1318     clean_child_exit(0);
1319     }
1320     /* else */
1321 trawick 109510 if (ap_scoreboard_image->parent[slot].pid != 0) {
1322     /* This new child process is squatting on the scoreboard
1323     * entry owned by an exiting child process, which cannot
1324     * exit until all active requests complete.
1325     * Don't forget about this exiting child process, or we
1326     * won't be able to kill it if it doesn't exit by the
1327     * time the server is shut down.
1328     */
1329     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
1330     "taking over scoreboard slot from %" APR_PID_T_FMT "%s",
1331     ap_scoreboard_image->parent[slot].pid,
1332     ap_scoreboard_image->parent[slot].quiescing ?
1333     " (quiescing)" : "");
1334     ap_register_extra_mpm_process(ap_scoreboard_image->parent[slot].pid);
1335     }
1336 rbb 89781 ap_scoreboard_image->parent[slot].quiescing = 0;
1337     ap_scoreboard_image->parent[slot].pid = pid;
1338     return 0;
1339     }
1340    
1341     /* start up a bunch of children */
1342     static void startup_children(int number_to_start)
1343     {
1344     int i;
1345    
1346     for (i = 0; number_to_start && i < ap_daemons_limit; ++i) {
1347 jerenkrantz 92473 if (ap_scoreboard_image->parent[i].pid != 0) {
1348     continue;
1349     }
1350     if (make_child(ap_server_conf, i) < 0) {
1351     break;
1352     }
1353     --number_to_start;
1354 rbb 89781 }
1355     }
1356    
1357    
1358     /*
1359     * idle_spawn_rate is the number of children that will be spawned on the
1360     * next maintenance cycle if there aren't enough idle servers. It is
1361     * doubled up to MAX_SPAWN_RATE, and reset only when a cycle goes by
1362     * without the need to spawn.
1363     */
1364     static int idle_spawn_rate = 1;
1365     #ifndef MAX_SPAWN_RATE
1366 jerenkrantz 92473 #define MAX_SPAWN_RATE (32)
1367 rbb 89781 #endif
1368     static int hold_off_on_exponential_spawning;
1369    
1370     static void perform_idle_server_maintenance(void)
1371     {
1372     int i, j;
1373     int idle_thread_count;
1374     worker_score *ws;
1375     process_score *ps;
1376     int free_length;
1377 gregames 89928 int totally_free_length = 0;
1378 rbb 89781 int free_slots[MAX_SPAWN_RATE];
1379     int last_non_dead;
1380     int total_non_dead;
1381 gregames 168182 int active_thread_count = 0;
1382 rbb 89781
1383     /* initialize the free_list */
1384     free_length = 0;
1385    
1386     idle_thread_count = 0;
1387     last_non_dead = -1;
1388     total_non_dead = 0;
1389    
1390     for (i = 0; i < ap_daemons_limit; ++i) {
1391 jerenkrantz 92473 /* Initialization to satisfy the compiler. It doesn't know
1392     * that ap_threads_per_child is always > 0 */
1393     int status = SERVER_DEAD;
1394     int any_dying_threads = 0;
1395     int any_dead_threads = 0;
1396     int all_dead_threads = 1;
1397 rbb 89781
1398 jerenkrantz 92473 if (i >= ap_max_daemons_limit && totally_free_length == idle_spawn_rate)
1399     break;
1400 rbb 89781 ps = &ap_scoreboard_image->parent[i];
1401 jerenkrantz 92473 for (j = 0; j < ap_threads_per_child; j++) {
1402 rbb 89781 ws = &ap_scoreboard_image->servers[i][j];
1403 jerenkrantz 92473 status = ws->status;
1404 rbb 89781
1405 gregames 89928 /* XXX any_dying_threads is probably no longer needed GLA */
1406 jim 332309 any_dying_threads = any_dying_threads ||
1407 jerenkrantz 92473 (status == SERVER_GRACEFUL);
1408     any_dead_threads = any_dead_threads || (status == SERVER_DEAD);
1409     all_dead_threads = all_dead_threads &&
1410 gregames 89928 (status == SERVER_DEAD ||
1411     status == SERVER_GRACEFUL);
1412 rbb 89781
1413 jerenkrantz 92473 /* We consider a starting server as idle because we started it
1414     * at least a cycle ago, and if it still hasn't finished starting
1415     * then we're just going to swamp things worse by forking more.
1416     * So we hopefully won't need to fork more if we count it.
1417     * This depends on the ordering of SERVER_READY and SERVER_STARTING.
1418     */
1419 gregames 168182 if (ps->pid != 0) { /* XXX just set all_dead_threads in outer for
1420     loop if no pid? not much else matters */
1421     if (status <= SERVER_READY && status != SERVER_DEAD &&
1422     !ps->quiescing &&
1423     ps->generation == ap_my_generation) {
1424     ++idle_thread_count;
1425     }
1426     if (status >= SERVER_READY && status < SERVER_GRACEFUL) {
1427     ++active_thread_count;
1428     }
1429 jerenkrantz 92473 }
1430     }
1431 trawick 102425 if (any_dead_threads && totally_free_length < idle_spawn_rate
1432     && free_length < MAX_SPAWN_RATE
1433 rbb 89781 && (!ps->pid /* no process in the slot */
1434     || ps->quiescing)) { /* or at least one is going away */
1435 gregames 89928 if (all_dead_threads) {
1436     /* great! we prefer these, because the new process can
1437 jim 332309 * start more threads sooner. So prioritize this slot
1438 gregames 89928 * by putting it ahead of any slots with active threads.
1439     *
1440     * first, make room by moving a slot that's potentially still
1441     * in use to the end of the array
1442     */
1443     free_slots[free_length] = free_slots[totally_free_length];
1444     free_slots[totally_free_length++] = i;
1445     }
1446     else {
1447     /* slot is still in use - back of the bus
1448     */
1449 gregames 160211 free_slots[free_length] = i;
1450 gregames 89928 }
1451 jerenkrantz 92473 ++free_length;
1452     }
1453 gregames 89928 /* XXX if (!ps->quiescing) is probably more reliable GLA */
1454 jerenkrantz 92473 if (!any_dying_threads) {
1455 rbb 89781 last_non_dead = i;
1456     ++total_non_dead;
1457     }
1458     }
1459 gregames 168182
1460     if (sick_child_detected) {
1461     if (active_thread_count > 0) {
1462     /* some child processes appear to be working. don't kill the
1463     * whole server.
1464     */
1465     sick_child_detected = 0;
1466     }
1467     else {
1468 jim 332309 /* looks like a basket case. give up.
1469 gregames 168182 */
1470     shutdown_pending = 1;
1471     child_fatal = 1;
1472     ap_log_error(APLOG_MARK, APLOG_ALERT, 0,
1473     ap_server_conf,
1474     "No active workers found..."
1475     " Apache is exiting!");
1476     /* the child already logged the failure details */
1477     return;
1478     }
1479     }
1480 jim 332309
1481 rbb 89781 ap_max_daemons_limit = last_non_dead + 1;
1482    
1483     if (idle_thread_count > max_spare_threads) {
1484     /* Kill off one child */
1485 rbb 93358 ap_mpm_pod_signal(pod, TRUE);
1486 rbb 89781 idle_spawn_rate = 1;
1487     }
1488     else if (idle_thread_count < min_spare_threads) {
1489     /* terminate the free list */
1490     if (free_length == 0) {
1491 jerenkrantz 92473 /* only report this condition once */
1492     static int reported = 0;
1493 jim 332309
1494 jerenkrantz 92473 if (!reported) {
1495 jim 332309 ap_log_error(APLOG_MARK, APLOG_ERR, 0,
1496 jerenkrantz 92473 ap_server_conf,
1497     "server reached MaxClients setting, consider"
1498     " raising the MaxClients setting");
1499     reported = 1;
1500     }
1501     idle_spawn_rate = 1;
1502     }
1503     else {
1504 gregames 89928 if (free_length > idle_spawn_rate) {
1505     free_length = idle_spawn_rate;
1506     }
1507 jerenkrantz 92473 if (idle_spawn_rate >= 8) {
1508 jim 332309 ap_log_error(APLOG_MARK, APLOG_INFO, 0,
1509 jerenkrantz 92473 ap_server_conf,
1510     "server seems busy, (you may need "
1511     "to increase StartServers, ThreadsPerChild "
1512 rbb 89781 "or Min/MaxSpareThreads), "
1513 jerenkrantz 92473 "spawning %d children, there are around %d idle "
1514 rbb 89781 "threads, and %d total children", free_length,
1515 jerenkrantz 92473 idle_thread_count, total_non_dead);
1516     }
1517     for (i = 0; i < free_length; ++i) {
1518     make_child(ap_server_conf, free_slots[i]);
1519     }
1520     /* the next time around we want to spawn twice as many if this
1521     * wasn't good enough, but not if we've just done a graceful
1522     */
1523     if (hold_off_on_exponential_spawning) {
1524     --hold_off_on_exponential_spawning;
1525     }
1526     else if (idle_spawn_rate < MAX_SPAWN_RATE) {
1527     idle_spawn_rate *= 2;
1528     }
1529     }
1530 rbb 89781 }
1531     else {
1532     idle_spawn_rate = 1;
1533     }
1534     }
1535    
1536     static void server_main_loop(int remaining_children_to_start)
1537     {
1538     int child_slot;
1539 rbb 91648 apr_exit_why_e exitwhy;
1540 gregames 93366 int status, processed_status;
1541 rbb 89781 apr_proc_t pid;
1542     int i;
1543    
1544     while (!restart_pending && !shutdown_pending) {
1545 rbb 91648 ap_wait_or_timeout(&exitwhy, &status, &pid, pconf);
1546 jim 332309
1547 rbb 89781 if (pid.pid != -1) {
1548 gregames 93366 processed_status = ap_process_child_status(&pid, exitwhy, status);
1549     if (processed_status == APEXIT_CHILDFATAL) {
1550 trawick 92019 shutdown_pending = 1;
1551     child_fatal = 1;
1552     return;
1553     }
1554 gregames 168182 else if (processed_status == APEXIT_CHILDSICK) {
1555     /* tell perform_idle_server_maintenance to check into this
1556     * on the next timer pop
1557     */
1558     sick_child_detected = 1;
1559     }
1560 rbb 89781 /* non-fatal death... note that it's gone in the scoreboard. */
1561     child_slot = find_child_by_pid(&pid);
1562     if (child_slot >= 0) {
1563     for (i = 0; i < ap_threads_per_child; i++)
1564 jim 332309 ap_update_child_status_from_indexes(child_slot, i, SERVER_DEAD,
1565 trawick 92512 (request_rec *) NULL);
1566 jim 332309
1567 rbb 89781 ap_scoreboard_image->parent[child_slot].pid = 0;
1568     ap_scoreboard_image->parent[child_slot].quiescing = 0;
1569 gregames 93366 if (processed_status == APEXIT_CHILDSICK) {
1570     /* resource shortage, minimize the fork rate */
1571     idle_spawn_rate = 1;
1572     }
1573     else if (remaining_children_to_start
1574 jerenkrantz 92473 && child_slot < ap_daemons_limit) {
1575     /* we're still doing a 1-for-1 replacement of dead
1576 rbb 89781 * children with new children
1577     */
1578 jerenkrantz 92473 make_child(ap_server_conf, child_slot);
1579     --remaining_children_to_start;
1580     }
1581 trawick 109510 }
1582     else if (ap_unregister_extra_mpm_process(pid.pid) == 1) {
1583     /* handled */
1584 rbb 89781 #if APR_HAS_OTHER_CHILD
1585 jerenkrantz 92473 }
1586 brianp 101858 else if (apr_proc_other_child_alert(&pid, APR_OC_REASON_DEATH,
1587     status) == 0) {
1588 jerenkrantz 92473 /* handled */
1589 rbb 89781 #endif
1590 jerenkrantz 92473 }
1591     else if (is_graceful) {
1592     /* Great, we've probably just lost a slot in the
1593     * scoreboard. Somehow we don't know about this child.
1594     */
1595 trawick 95149 ap_log_error(APLOG_MARK, APLOG_WARNING, 0,
1596 jerenkrantz 92473 ap_server_conf,
1597     "long lost child came home! (pid %ld)",
1598     (long)pid.pid);
1599     }
1600     /* Don't perform idle maintenance when a child dies,
1601 rbb 89781 * only do it when there's a timeout. Remember only a
1602     * finite number of children can die, and it's pretty
1603     * pathological for a lot to die suddenly.
1604     */
1605 jerenkrantz 92473 continue;
1606     }
1607     else if (remaining_children_to_start) {
1608     /* we hit a 1 second timeout in which none of the previous
1609     * generation of children needed to be reaped... so assume
1610     * they're all done, and pick up the slack if any is left.
1611     */
1612     startup_children(remaining_children_to_start);
1613     remaining_children_to_start = 0;
1614     /* In any event we really shouldn't do the code below because
1615     * few of the servers we just started are in the IDLE state
1616     * yet, so we'd mistakenly create an extra server.
1617     */
1618     continue;
1619     }
1620 rbb 89781
1621 jerenkrantz 92473 perform_idle_server_maintenance();
1622 rbb 89781 }
1623     }
1624    
1625 rbb 91955 int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
1626     {
1627     int remaining_children_to_start;
1628     apr_status_t rv;
1629    
1630 rbb 93227 ap_log_pid(pconf, ap_pid_fname);
1631    
1632 trawick 92530 first_server_limit = server_limit;
1633     first_thread_limit = thread_limit;
1634     if (changed_limit_at_restart) {
1635 trawick 95149 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
1636 trawick 92530 "WARNING: Attempt to change ServerLimit or ThreadLimit "
1637     "ignored during restart");
1638     changed_limit_at_restart = 0;
1639     }
1640 jim 332309
1641 rbb 89781 /* Initialize cross-process accept lock */
1642 wrowe 93969 ap_lock_fname = apr_psprintf(_pconf, "%s.%" APR_PID_T_FMT,
1643 trawick 92412 ap_server_root_relative(_pconf, ap_lock_fname),
1644     ap_my_pid);
1645 dreid 92596
1646 jim 332309 rv = apr_proc_mutex_create(&accept_mutex, ap_lock_fname,
1647 trawick 92653 ap_accept_lock_mech, _pconf);
1648 rbb 89781 if (rv != APR_SUCCESS) {
1649     ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s,
1650     "Couldn't create accept lock");
1651 trawick 102045 mpm_state = AP_MPMQ_STOPPING;
1652 rbb 89781 return 1;
1653     }
1654    
1655 trawick 90213 #if APR_USE_SYSVSEM_SERIALIZE
1656 jim 332309 if (ap_accept_lock_mech == APR_LOCK_DEFAULT ||
1657 trawick 90213 ap_accept_lock_mech == APR_LOCK_SYSVSEM) {
1658     #else
1659     if (ap_accept_lock_mech == APR_LOCK_SYSVSEM) {
1660     #endif
1661 aaron 91580 rv = unixd_set_proc_mutex_perms(accept_mutex);
1662 trawick 90213 if (rv != APR_SUCCESS) {
1663     ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s,
1664 trawick 94541 "Couldn't set permissions on cross-process lock; "
1665     "check User and Group directives");
1666 trawick 102045 mpm_state = AP_MPMQ_STOPPING;
1667 trawick 90213 return 1;
1668     }
1669     }
1670    
1671 rbb 89781 if (!is_graceful) {
1672 wrowe 94039 if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) {
1673 trawick 102045 mpm_state = AP_MPMQ_STOPPING;
1674 trawick 93055 return 1;
1675     }
1676 trawick 93998 /* fix the generation number in the global score; we just got a new,
1677     * cleared scoreboard
1678     */
1679     ap_scoreboard_image->global->running_generation = ap_my_generation;
1680 rbb 89781 }
1681    
1682     set_signals();
1683     /* Don't thrash... */
1684     if (max_spare_threads < min_spare_threads + ap_threads_per_child)
1685 jerenkrantz 92473 max_spare_threads = min_spare_threads + ap_threads_per_child;
1686 rbb 89781
1687     /* If we're doing a graceful_restart then we're going to see a lot
1688     * of children exiting immediately when we get into the main loop
1689 jerenkrantz 91076 * below (because we just sent them AP_SIG_GRACEFUL). This happens pretty
1690 rbb 89781 * rapidly... and for each one that exits we'll start a new one until
1691     * we reach at least daemons_min_free. But we may be permitted to
1692     * start more than that, so we'll just keep track of how many we're
1693     * supposed to start up without the 1 second penalty between each fork.
1694     */
1695     remaining_children_to_start = ap_daemons_to_start;
1696     if (remaining_children_to_start > ap_daemons_limit) {
1697 jerenkrantz 92473 remaining_children_to_start = ap_daemons_limit;
1698 rbb 89781 }
1699     if (!is_graceful) {
1700 jerenkrantz 92473 startup_children(remaining_children_to_start);
1701     remaining_children_to_start = 0;
1702 rbb 89781 }
1703     else {
1704 jerenkrantz 92473 /* give the system some time to recover before kicking into
1705     * exponential mode */
1706     hold_off_on_exponential_spawning = 10;
1707 rbb 89781 }
1708    
1709 trawick 95149 ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,
1710 jerenkrantz 92473 "%s configured -- resuming normal operations",
1711     ap_get_server_version());
1712 trawick 95149 ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf,
1713 jerenkrantz 92473 "Server built: %s", ap_get_server_built());
1714 jim 94055 #ifdef AP_MPM_WANT_SET_ACCEPT_LOCK_MECH
1715 trawick 95149 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
1716 jim 332307 "AcceptMutex: %s (default: %s)",
1717     apr_proc_mutex_name(accept_mutex),
1718     apr_proc_mutex_defname());
1719 jim 94055 #endif
1720 rbb 89781 restart_pending = shutdown_pending = 0;
1721 trawick 102045 mpm_state = AP_MPMQ_RUNNING;
1722 jim 332309
1723 rbb 89781 server_main_loop(remaining_children_to_start);
1724 trawick 102045 mpm_state = AP_MPMQ_STOPPING;
1725 rbb 89781
1726 colm 290189 if (shutdown_pending && !is_graceful) {
1727     /* Time to shut down:
1728 rbb 89781 * Kill child processes, tell them to call child_exit, etc...
1729     */
1730 trawick 94024 ap_mpm_pod_killpg(pod, ap_daemons_limit, FALSE);
1731 jerenkrantz 92473 ap_reclaim_child_processes(1); /* Start with SIGTERM */
1732 trawick 92019
1733     if (!child_fatal) {
1734     /* cleanup pid file on normal shutdown */
1735 rbb 89781 const char *pidfile = NULL;
1736     pidfile = ap_server_root_relative (pconf, ap_pid_fname);
1737     if ( pidfile != NULL && unlink(pidfile) == 0)
1738 trawick 95149 ap_log_error(APLOG_MARK, APLOG_INFO, 0,
1739 jerenkrantz 92473 ap_server_conf,
1740 colm 290189 "removed PID file %s (pid=%" APR_PID_T_FMT ")",
1741     pidfile, getpid());
1742 jim 332309
1743 trawick 95149 ap_log_error(APLOG_MARK, APLOG_NOTICE, 0,
1744 trawick 92019 ap_server_conf, "caught SIGTERM, shutting down");
1745 rbb 89781 }
1746 jerenkrantz 92473 return 1;
1747 colm 290189 } else if (shutdown_pending) {
1748     /* Time to gracefully shut down:
1749     * Kill child processes, tell them to call child_exit, etc...
1750     */
1751     int active_children;
1752     int index;
1753     apr_time_t cutoff = 0;
1754    
1755     /* Close our listeners, and then ask our children to do same */
1756     ap_close_listeners();
1757     ap_mpm_pod_killpg(pod, ap_daemons_limit, TRUE);
1758     ap_relieve_child_processes();
1759    
1760     if (!child_fatal) {
1761     /* cleanup pid file on normal shutdown */
1762     const char *pidfile = NULL;
1763     pidfile = ap_server_root_relative (pconf, ap_pid_fname);
1764     if ( pidfile != NULL && unlink(pidfile) == 0)
1765     ap_log_error(APLOG_MARK, APLOG_INFO, 0,
1766     ap_server_conf,
1767     "removed PID file %s (pid=%" APR_PID_T_FMT ")",
1768     pidfile, getpid());
1769 jim 332309
1770 colm 290189 ap_log_error(APLOG_MARK, APLOG_NOTICE, 0,
1771     ap_server_conf, "caught SIGTERM, shutting down");
1772     }
1773    
1774     /* Don't really exit until each child has finished */
1775     shutdown_pending = 0;
1776     do {
1777     /* Pause for a second */
1778     apr_sleep(apr_time_from_sec(1));
1779 jim 332309
1780 colm 290189 /* Relieve any children which have now exited */
1781     ap_relieve_child_processes();
1782 jim 332309
1783 colm 290189 active_children = 0;
1784     for (index = 0; index < ap_daemons_limit; ++index) {
1785     if (MPM_CHILD_PID(index) != 0) {
1786     if (kill(MPM_CHILD_PID(index), 0) == 0) {
1787     active_children = 1;
1788     /* Having just one child is enough to stay around */
1789