View | Details | Raw Unified | Return to bug 60487
Collapse All | Expand All

(-)os/unix/unixd.h (+25 lines)
Lines 27-32 Link Here
27
27
28
#include "httpd.h"
28
#include "httpd.h"
29
#include "http_config.h"
29
#include "http_config.h"
30
#include "scoreboard.h"
30
#include "ap_listen.h"
31
#include "ap_listen.h"
31
#ifdef HAVE_SYS_TIME_H
32
#ifdef HAVE_SYS_TIME_H
32
#include <sys/time.h>
33
#include <sys/time.h>
Lines 109-114 AP_DECLARE(apr_status_t) ap_unixd_accept(void **ac Link Here
109
#define ap_os_killpg(x, y)      (kill (-(x), (y)))
110
#define ap_os_killpg(x, y)      (kill (-(x), (y)))
110
#endif /* HAVE_KILLPG */
111
#endif /* HAVE_KILLPG */
111
112
113
typedef struct {
114
    void            *baton;  /* MPM's */
115
116
    /* volatile because they're updated from signals' handlers */
117
    int volatile    mpm_state;
118
    int volatile    shutdown_pending;
119
    int volatile    restart_pending;
120
    int volatile    is_ungraceful;
121
122
    ap_generation_t my_generation;
123
    int             module_loads;
124
    int             was_graceful;
125
126
    /*
127
     * Current number of listeners buckets and maximum reached across
128
     * restarts (to size retained data according to dynamic num_buckets,
129
     * eg. idle_spawn_rate).
130
     */
131
    int num_buckets, max_buckets;
132
} ap_unixd_mpm_retained_data;
133
134
AP_DECLARE(ap_unixd_mpm_retained_data *) ap_unixd_mpm_get_retained_data(void);
135
AP_DECLARE(void) ap_unixd_mpm_set_signals(apr_pool_t *pconf, int once_process);
136
112
#ifdef __cplusplus
137
#ifdef __cplusplus
113
}
138
}
114
#endif
139
#endif
(-)os/unix/unixd.c (+204 lines)
Lines 434-439 AP_DECLARE(apr_status_t) ap_unixd_accept(void **ac Link Here
434
}
434
}
435
435
436
436
437
/* Unixes MPMs' */
438
439
static ap_unixd_mpm_retained_data *retained_data = NULL;
440
AP_DECLARE(ap_unixd_mpm_retained_data *) ap_unixd_mpm_get_retained_data()
441
{
442
    if (!retained_data) {
443
        retained_data = ap_retained_data_create("ap_unixd_mpm_retained_data",
444
                                                sizeof(*retained_data));
445
        retained_data->mpm_state = AP_MPMQ_STARTING;
446
    }
447
    return retained_data;
448
}
449
450
static void sig_term(int sig)
451
{
452
    retained_data->mpm_state = AP_MPMQ_STOPPING;
453
    if (retained_data->shutdown_pending) {
454
        /* Um, is this _probably_ not an error, if the user has
455
         * tried to do a shutdown twice quickly, so we won't
456
         * worry about reporting it.
457
         */
458
        return;
459
    }
460
461
    retained_data->shutdown_pending = 1;
462
    if (sig != AP_SIG_GRACEFUL_STOP) {
463
        retained_data->is_ungraceful = 1;
464
    }
465
}
466
467
static void sig_restart(int sig)
468
{
469
    retained_data->mpm_state = AP_MPMQ_STOPPING;
470
    if (retained_data->restart_pending) {
471
        /* Probably not an error - don't bother reporting it */
472
        return;
473
    }
474
475
    retained_data->restart_pending = 1;
476
    if (sig != AP_SIG_GRACEFUL) {
477
        retained_data->is_ungraceful = 1;
478
    }
479
}
480
481
static apr_status_t unset_signals(void *unused)
482
{
483
#if 0  /* We can handle signals while restarting, and possibly be asked to
484
        * stop immediately, or restart after a lightning fast configuration
485
        * change... Better to not ignore them.
486
        */
487
#ifndef NO_USE_SIGACTION
488
    struct sigaction sa;
489
#endif
490
    (void)unused;
491
492
#ifndef NO_USE_SIGACTION
493
    memset(&sa, 0, sizeof sa);
494
    sigemptyset(&sa.sa_mask);
495
    sa.sa_handler = SIG_IGN;
496
497
    if (sigaction(SIGTERM, &sa, NULL) < 0)
498
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO()
499
                     "sigaction(SIGTERM)");
500
#ifdef AP_SIG_GRACEFUL_STOP
501
    if (sigaction(AP_SIG_GRACEFUL_STOP, &sa, NULL) < 0)
502
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO()
503
                     "sigaction(" AP_SIG_GRACEFUL_STOP_STRING ")");
504
#endif
505
#ifdef SIGINT
506
    if (sigaction(SIGINT, &sa, NULL) < 0)
507
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO()
508
                     "sigaction(SIGINT)");
509
#endif
510
    if (sigaction(SIGHUP, &sa, NULL) < 0)
511
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO()
512
                     "sigaction(SIGHUP)");
513
    if (sigaction(AP_SIG_GRACEFUL, &sa, NULL) < 0)
514
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO()
515
                     "sigaction(" AP_SIG_GRACEFUL_STRING ")");
516
#else
517
    apr_signal(SIGTERM, SIG_IGN);
518
#ifdef SIGHUP
519
    apr_signal(SIGHUP, SIG_IGN);
520
#endif /* SIGHUP */
521
#ifdef AP_SIG_GRACEFUL
522
    apr_signal(AP_SIG_GRACEFUL, SIG_IGN);
523
#endif /* AP_SIG_GRACEFUL */
524
#ifdef AP_SIG_GRACEFUL_STOP
525
    apr_signal(AP_SIG_GRACEFUL_STOP, SIG_IGN);
526
#endif /* AP_SIG_GRACEFUL_STOP */
527
528
#endif
529
#endif /* 0 */
530
531
    retained_data->shutdown_pending = retained_data->restart_pending = 0;
532
    retained_data->was_graceful = !retained_data->is_ungraceful;
533
    retained_data->is_ungraceful = 0;
534
535
    return APR_SUCCESS;
536
}
537
538
AP_DECLARE(void) ap_unixd_mpm_set_signals(apr_pool_t *pconf, int one_process)
539
{
540
#ifndef NO_USE_SIGACTION
541
    struct sigaction sa;
542
#endif
543
544
    /* Signals' handlers depend on retained data */
545
    (void)ap_unixd_mpm_get_retained_data();
546
547
    if (!one_process) {
548
        ap_fatal_signal_setup(ap_server_conf, pconf);
549
    }
550
551
#ifndef NO_USE_SIGACTION
552
    memset(&sa, 0, sizeof sa);
553
    sigemptyset(&sa.sa_mask);
554
555
#ifdef SIGPIPE
556
    sa.sa_handler = SIG_IGN;
557
    if (sigaction(SIGPIPE, &sa, NULL) < 0)
558
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00269)
559
                     "sigaction(SIGPIPE)");
560
#endif
561
#ifdef SIGXCPU
562
    sa.sa_handler = SIG_DFL;
563
    if (sigaction(SIGXCPU, &sa, NULL) < 0)
564
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00267)
565
                     "sigaction(SIGXCPU)");
566
#endif
567
#ifdef SIGXFSZ
568
    /* For systems following the LFS standard, ignoring SIGXFSZ allows
569
     * a write() beyond the 2GB limit to fail gracefully with E2BIG
570
     * rather than terminate the process. */
571
    sa.sa_handler = SIG_IGN;
572
    if (sigaction(SIGXFSZ, &sa, NULL) < 0)
573
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00268)
574
                     "sigaction(SIGXFSZ)");
575
#endif
576
577
    sa.sa_handler = sig_term;
578
    if (sigaction(SIGTERM, &sa, NULL) < 0)
579
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00264)
580
                     "sigaction(SIGTERM)");
581
#ifdef SIGINT
582
    if (sigaction(SIGINT, &sa, NULL) < 0)
583
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00266)
584
                     "sigaction(SIGINT)");
585
#endif
586
#ifdef AP_SIG_GRACEFUL_STOP
587
    if (sigaction(AP_SIG_GRACEFUL_STOP, &sa, NULL) < 0)
588
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00265)
589
                     "sigaction(" AP_SIG_GRACEFUL_STOP_STRING ")");
590
#endif
591
592
    /* Don't restart in ONE_PROCESS mode :) */
593
    if (!one_process) {
594
        /* we want to ignore HUPs and AP_SIG_GRACEFUL while we're busy
595
         * processing one */
596
        sa.sa_handler = sig_restart;
597
        sigaddset(&sa.sa_mask, SIGHUP);
598
        sigaddset(&sa.sa_mask, AP_SIG_GRACEFUL);
599
        if (sigaction(SIGHUP, &sa, NULL) < 0)
600
            ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00270)
601
                         "sigaction(SIGHUP)");
602
        if (sigaction(AP_SIG_GRACEFUL, &sa, NULL) < 0)
603
            ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00271)
604
                         "sigaction(" AP_SIG_GRACEFUL_STRING ")");
605
    }
606
607
#else  /* NO_USE_SIGACTION */
608
609
#ifdef SIGPIPE
610
    apr_signal(SIGPIPE, SIG_IGN);
611
#endif /* SIGPIPE */
612
    if (!one_process) {
613
#ifdef SIGXCPU
614
        apr_signal(SIGXCPU, SIG_DFL);
615
#endif /* SIGXCPU */
616
#ifdef SIGXFSZ
617
        apr_signal(SIGXFSZ, SIG_IGN);
618
#endif /* SIGXFSZ */
619
620
        /* Don't restart in ONE_PROCESS mode :) */
621
#ifdef SIGHUP
622
        apr_signal(SIGHUP, sig_restart);
623
#endif /* SIGHUP */
624
#ifdef AP_SIG_GRACEFUL
625
        apr_signal(AP_SIG_GRACEFUL, sig_restart);
626
#endif /* AP_SIG_GRACEFUL */
627
    }
628
629
    apr_signal(SIGTERM, sig_term);
630
#ifdef AP_SIG_GRACEFUL_STOP
631
    apr_signal(AP_SIG_GRACEFUL_STOP, sig_term);
632
#endif /* AP_SIG_GRACEFUL_STOP */
633
634
#endif /* NO_USE_SIGACTION */
635
636
    apr_pool_cleanup_register(pconf, NULL, unset_signals,
637
                              apr_pool_cleanup_null);
638
}
639
640
437
#ifdef _OSD_POSIX
641
#ifdef _OSD_POSIX
438
642
439
#include "apr_lib.h"
643
#include "apr_lib.h"
(-)server/mpm/event/event.c (-209 / +63 lines)
Lines 197-203 static apr_uint32_t threads_shutdown = 0; /* Num Link Here
197
static int resource_shortage = 0;
197
static int resource_shortage = 0;
198
static fd_queue_t *worker_queue;
198
static fd_queue_t *worker_queue;
199
static fd_queue_info_t *worker_queue_info;
199
static fd_queue_info_t *worker_queue_info;
200
static int mpm_state = AP_MPMQ_STARTING;
201
200
202
static apr_thread_mutex_t *timeout_mutex;
201
static apr_thread_mutex_t *timeout_mutex;
203
202
Lines 382-393 typedef struct Link Here
382
 * subsequent calls to pre-config hook
381
 * subsequent calls to pre-config hook
383
 */
382
 */
384
typedef struct event_retained_data {
383
typedef struct event_retained_data {
384
    ap_unixd_mpm_retained_data *mpm;
385
385
    int first_server_limit;
386
    int first_server_limit;
386
    int first_thread_limit;
387
    int first_thread_limit;
387
    int module_loads;
388
    int sick_child_detected;
388
    int sick_child_detected;
389
    ap_generation_t my_generation;
390
    int volatile is_graceful; /* set from signal handler */
391
    int maxclients_reported;
389
    int maxclients_reported;
392
    /*
390
    /*
393
     * The max child slot ever assigned, preserved across restarts.  Necessary
391
     * The max child slot ever assigned, preserved across restarts.  Necessary
Lines 415-426 typedef struct event_retained_data { Link Here
415
#define MAX_SPAWN_RATE        (32)
413
#define MAX_SPAWN_RATE        (32)
416
#endif
414
#endif
417
    int hold_off_on_exponential_spawning;
415
    int hold_off_on_exponential_spawning;
418
    /*
419
     * Current number of listeners buckets and maximum reached across
420
     * restarts (to size retained data according to dynamic num_buckets,
421
     * eg. idle_spawn_rate).
422
     */
423
    int num_buckets, max_buckets;
424
} event_retained_data;
416
} event_retained_data;
425
static event_retained_data *retained;
417
static event_retained_data *retained;
426
418
Lines 566-572 static void signal_threads(int mode) Link Here
566
        return;
558
        return;
567
    }
559
    }
568
    terminate_mode = mode;
560
    terminate_mode = mode;
569
    mpm_state = AP_MPMQ_STOPPING;
561
    retained->mpm->mpm_state = AP_MPMQ_STOPPING;
570
562
571
    /* in case we weren't called from the listener thread, wake up the
563
    /* in case we weren't called from the listener thread, wake up the
572
     * listener thread
564
     * listener thread
Lines 631-640 static int event_query(int query_code, int *result Link Here
631
        *result = active_daemons_limit;
623
        *result = active_daemons_limit;
632
        break;
624
        break;
633
    case AP_MPMQ_MPM_STATE:
625
    case AP_MPMQ_MPM_STATE:
634
        *result = mpm_state;
626
        *result = retained->mpm->mpm_state;
635
        break;
627
        break;
636
    case AP_MPMQ_GENERATION:
628
    case AP_MPMQ_GENERATION:
637
        *result = retained->my_generation;
629
        *result = retained->mpm->my_generation;
638
        break;
630
        break;
639
    case AP_MPMQ_CAN_SUSPEND:
631
    case AP_MPMQ_CAN_SUSPEND:
640
        *result = 1;
632
        *result = 1;
Lines 668-674 static void event_note_child_started(int slot, pid Link Here
668
    ap_scoreboard_image->parent[slot].pid = pid;
660
    ap_scoreboard_image->parent[slot].pid = pid;
669
    ap_run_child_status(ap_server_conf,
661
    ap_run_child_status(ap_server_conf,
670
                        ap_scoreboard_image->parent[slot].pid,
662
                        ap_scoreboard_image->parent[slot].pid,
671
                        retained->my_generation, slot, MPM_CHILD_STARTED);
663
                        retained->mpm->my_generation, slot, MPM_CHILD_STARTED);
672
}
664
}
673
665
674
static const char *event_get_name(void)
666
static const char *event_get_name(void)
Lines 680-686 static const char *event_get_name(void) Link Here
680
static void clean_child_exit(int code) __attribute__ ((noreturn));
672
static void clean_child_exit(int code) __attribute__ ((noreturn));
681
static void clean_child_exit(int code)
673
static void clean_child_exit(int code)
682
{
674
{
683
    mpm_state = AP_MPMQ_STOPPING;
675
    retained->mpm->mpm_state = AP_MPMQ_STOPPING;
684
    if (pchild) {
676
    if (pchild) {
685
        apr_pool_destroy(pchild);
677
        apr_pool_destroy(pchild);
686
    }
678
    }
Lines 703-712 static void just_die(int sig) Link Here
703
695
704
static int child_fatal;
696
static int child_fatal;
705
697
706
/* volatile because they're updated from a signal handler */
707
static int volatile shutdown_pending;
708
static int volatile restart_pending;
709
710
static apr_status_t decrement_connection_count(void *cs_)
698
static apr_status_t decrement_connection_count(void *cs_)
711
{
699
{
712
    event_conn_state_t *cs = cs_;
700
    event_conn_state_t *cs = cs_;
Lines 729-877 static apr_status_t decrement_connection_count(voi Link Here
729
    return APR_SUCCESS;
717
    return APR_SUCCESS;
730
}
718
}
731
719
732
/*
733
 * ap_start_shutdown() and ap_start_restart(), below, are a first stab at
734
 * functions to initiate shutdown or restart without relying on signals.
735
 * Previously this was initiated in sig_term() and restart() signal handlers,
736
 * but we want to be able to start a shutdown/restart from other sources --
737
 * e.g. on Win32, from the service manager. Now the service manager can
738
 * call ap_start_shutdown() or ap_start_restart() as appropriate.  Note that
739
 * these functions can also be called by the child processes, since global
740
 * variables are no longer used to pass on the required action to the parent.
741
 *
742
 * These should only be called from the parent process itself, since the
743
 * parent process will use the shutdown_pending and restart_pending variables
744
 * to determine whether to shutdown or restart. The child process should
745
 * call signal_parent() directly to tell the parent to die -- this will
746
 * cause neither of those variable to be set, which the parent will
747
 * assume means something serious is wrong (which it will be, for the
748
 * child to force an exit) and so do an exit anyway.
749
 */
750
751
static void ap_start_shutdown(int graceful)
752
{
753
    mpm_state = AP_MPMQ_STOPPING;
754
    if (shutdown_pending == 1) {
755
        /* Um, is this _probably_ not an error, if the user has
756
         * tried to do a shutdown twice quickly, so we won't
757
         * worry about reporting it.
758
         */
759
        return;
760
    }
761
    shutdown_pending = 1;
762
    retained->is_graceful = graceful;
763
}
764
765
/* do a graceful restart if graceful == 1 */
766
static void ap_start_restart(int graceful)
767
{
768
    mpm_state = AP_MPMQ_STOPPING;
769
    if (restart_pending == 1) {
770
        /* Probably not an error - don't bother reporting it */
771
        return;
772
    }
773
    restart_pending = 1;
774
    retained->is_graceful = graceful;
775
}
776
777
static void sig_term(int sig)
778
{
779
    ap_start_shutdown(sig == AP_SIG_GRACEFUL_STOP);
780
}
781
782
static void restart(int sig)
783
{
784
    ap_start_restart(sig == AP_SIG_GRACEFUL);
785
}
786
787
static void set_signals(void)
788
{
789
#ifndef NO_USE_SIGACTION
790
    struct sigaction sa;
791
#endif
792
793
    if (!one_process) {
794
        ap_fatal_signal_setup(ap_server_conf, pconf);
795
    }
796
797
#ifndef NO_USE_SIGACTION
798
    sigemptyset(&sa.sa_mask);
799
    sa.sa_flags = 0;
800
801
    sa.sa_handler = sig_term;
802
    if (sigaction(SIGTERM, &sa, NULL) < 0)
803
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00459)
804
                     "sigaction(SIGTERM)");
805
#ifdef AP_SIG_GRACEFUL_STOP
806
    if (sigaction(AP_SIG_GRACEFUL_STOP, &sa, NULL) < 0)
807
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00460)
808
                     "sigaction(" AP_SIG_GRACEFUL_STOP_STRING ")");
809
#endif
810
#ifdef SIGINT
811
    if (sigaction(SIGINT, &sa, NULL) < 0)
812
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00461)
813
                     "sigaction(SIGINT)");
814
#endif
815
#ifdef SIGXCPU
816
    sa.sa_handler = SIG_DFL;
817
    if (sigaction(SIGXCPU, &sa, NULL) < 0)
818
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00462)
819
                     "sigaction(SIGXCPU)");
820
#endif
821
#ifdef SIGXFSZ
822
    /* For systems following the LFS standard, ignoring SIGXFSZ allows
823
     * a write() beyond the 2GB limit to fail gracefully with E2BIG
824
     * rather than terminate the process. */
825
    sa.sa_handler = SIG_IGN;
826
    if (sigaction(SIGXFSZ, &sa, NULL) < 0)
827
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00463)
828
                     "sigaction(SIGXFSZ)");
829
#endif
830
#ifdef SIGPIPE
831
    sa.sa_handler = SIG_IGN;
832
    if (sigaction(SIGPIPE, &sa, NULL) < 0)
833
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00464)
834
                     "sigaction(SIGPIPE)");
835
#endif
836
837
    /* we want to ignore HUPs and AP_SIG_GRACEFUL while we're busy
838
     * processing one */
839
    sigaddset(&sa.sa_mask, SIGHUP);
840
    sigaddset(&sa.sa_mask, AP_SIG_GRACEFUL);
841
    sa.sa_handler = restart;
842
    if (sigaction(SIGHUP, &sa, NULL) < 0)
843
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00465)
844
                     "sigaction(SIGHUP)");
845
    if (sigaction(AP_SIG_GRACEFUL, &sa, NULL) < 0)
846
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00466)
847
                     "sigaction(" AP_SIG_GRACEFUL_STRING ")");
848
#else
849
    if (!one_process) {
850
#ifdef SIGXCPU
851
        apr_signal(SIGXCPU, SIG_DFL);
852
#endif /* SIGXCPU */
853
#ifdef SIGXFSZ
854
        apr_signal(SIGXFSZ, SIG_IGN);
855
#endif /* SIGXFSZ */
856
    }
857
858
    apr_signal(SIGTERM, sig_term);
859
#ifdef SIGHUP
860
    apr_signal(SIGHUP, restart);
861
#endif /* SIGHUP */
862
#ifdef AP_SIG_GRACEFUL
863
    apr_signal(AP_SIG_GRACEFUL, restart);
864
#endif /* AP_SIG_GRACEFUL */
865
#ifdef AP_SIG_GRACEFUL_STOP
866
     apr_signal(AP_SIG_GRACEFUL_STOP, sig_term);
867
#endif /* AP_SIG_GRACEFUL_STOP */
868
#ifdef SIGPIPE
869
    apr_signal(SIGPIPE, SIG_IGN);
870
#endif /* SIGPIPE */
871
872
#endif
873
}
874
875
static void notify_suspend(event_conn_state_t *cs)
720
static void notify_suspend(event_conn_state_t *cs)
876
{
721
{
877
    ap_run_suspend_connection(cs->c, cs->r);
722
    ap_run_suspend_connection(cs->c, cs->r);
Lines 2316-2322 static void *APR_THREAD_FUNC worker_thread(apr_thr Link Here
2316
2161
2317
    ap_scoreboard_image->servers[process_slot][thread_slot].pid = ap_my_pid;
2162
    ap_scoreboard_image->servers[process_slot][thread_slot].pid = ap_my_pid;
2318
    ap_scoreboard_image->servers[process_slot][thread_slot].tid = apr_os_thread_current();
2163
    ap_scoreboard_image->servers[process_slot][thread_slot].tid = apr_os_thread_current();
2319
    ap_scoreboard_image->servers[process_slot][thread_slot].generation = retained->my_generation;
2164
    ap_scoreboard_image->servers[process_slot][thread_slot].generation = retained->mpm->my_generation;
2320
    ap_update_child_status_from_indexes(process_slot, thread_slot,
2165
    ap_update_child_status_from_indexes(process_slot, thread_slot,
2321
                                        SERVER_STARTING, NULL);
2166
                                        SERVER_STARTING, NULL);
2322
2167
Lines 2676-2690 static void child_main(int child_num_arg, int chil Link Here
2676
    apr_pool_t *pskip;
2521
    apr_pool_t *pskip;
2677
    int i;
2522
    int i;
2678
2523
2679
    mpm_state = AP_MPMQ_STARTING;       /* for benefit of any hooks that run as this
2524
    /* for benefit of any hooks that run as this child initializes */
2680
                                         * child initializes
2525
    retained->mpm->mpm_state = AP_MPMQ_STARTING;
2681
                                         */
2526
2682
    ap_my_pid = getpid();
2527
    ap_my_pid = getpid();
2683
    ap_fatal_signal_child_setup(ap_server_conf);
2528
    ap_fatal_signal_child_setup(ap_server_conf);
2684
    apr_pool_create(&pchild, pconf);
2529
    apr_pool_create(&pchild, pconf);
2685
2530
2686
    /* close unused listeners and pods */
2531
    /* close unused listeners and pods */
2687
    for (i = 0; i < retained->num_buckets; i++) {
2532
    for (i = 0; i < retained->mpm->num_buckets; i++) {
2688
        if (i != child_bucket) {
2533
        if (i != child_bucket) {
2689
            ap_close_listeners_ex(all_buckets[i].listeners);
2534
            ap_close_listeners_ex(all_buckets[i].listeners);
2690
            ap_mpm_podx_close(all_buckets[i].pod);
2535
            ap_mpm_podx_close(all_buckets[i].pod);
Lines 2762-2768 static void child_main(int child_num_arg, int chil Link Here
2762
        clean_child_exit(APEXIT_CHILDSICK);
2607
        clean_child_exit(APEXIT_CHILDSICK);
2763
    }
2608
    }
2764
2609
2765
    mpm_state = AP_MPMQ_RUNNING;
2610
    retained->mpm->mpm_state = AP_MPMQ_RUNNING;
2766
2611
2767
    /* If we are only running in one_process mode, we will want to
2612
    /* If we are only running in one_process mode, we will want to
2768
     * still handle signals. */
2613
     * still handle signals. */
Lines 2859-2865 static int make_child(server_rec * s, int slot, in Link Here
2859
    if (one_process) {
2704
    if (one_process) {
2860
        my_bucket = &all_buckets[0];
2705
        my_bucket = &all_buckets[0];
2861
2706
2862
        set_signals();
2863
        event_note_child_started(slot, getpid());
2707
        event_note_child_started(slot, getpid());
2864
        child_main(slot, 0);
2708
        child_main(slot, 0);
2865
        /* NOTREACHED */
2709
        /* NOTREACHED */
Lines 2927-2933 static void startup_children(int number_to_start) Link Here
2927
        if (ap_scoreboard_image->parent[i].pid != 0) {
2771
        if (ap_scoreboard_image->parent[i].pid != 0) {
2928
            continue;
2772
            continue;
2929
        }
2773
        }
2930
        if (make_child(ap_server_conf, i, i % retained->num_buckets) < 0) {
2774
        if (make_child(ap_server_conf, i, i % retained->mpm->num_buckets) < 0) {
2931
            break;
2775
            break;
2932
        }
2776
        }
2933
        --number_to_start;
2777
        --number_to_start;
Lines 2972-2978 static void perform_idle_server_maintenance(int ch Link Here
2972
                 * This depends on the ordering of SERVER_READY and SERVER_STARTING.
2816
                 * This depends on the ordering of SERVER_READY and SERVER_STARTING.
2973
                 */
2817
                 */
2974
                if (status <= SERVER_READY && !ps->quiescing && !ps->not_accepting
2818
                if (status <= SERVER_READY && !ps->quiescing && !ps->not_accepting
2975
                    && ps->generation == retained->my_generation
2819
                    && ps->generation == retained->mpm->my_generation
2976
                    && ps->bucket == child_bucket)
2820
                    && ps->bucket == child_bucket)
2977
                {
2821
                {
2978
                    ++idle_thread_count;
2822
                    ++idle_thread_count;
Lines 3001-3007 static void perform_idle_server_maintenance(int ch Link Here
3001
        else {
2845
        else {
3002
            /* looks like a basket case, as no child ever fully initialized; give up.
2846
            /* looks like a basket case, as no child ever fully initialized; give up.
3003
             */
2847
             */
3004
            shutdown_pending = 1;
2848
            retained->mpm->shutdown_pending = 1;
3005
            child_fatal = 1;
2849
            child_fatal = 1;
3006
            ap_log_error(APLOG_MARK, APLOG_ALERT, 0,
2850
            ap_log_error(APLOG_MARK, APLOG_ALERT, 0,
3007
                         ap_server_conf, APLOGNO(02324)
2851
                         ap_server_conf, APLOGNO(02324)
Lines 3113-3119 static void server_main_loop(int remaining_childre Link Here
3113
    apr_proc_t pid;
2957
    apr_proc_t pid;
3114
    int i;
2958
    int i;
3115
2959
3116
    while (!restart_pending && !shutdown_pending) {
2960
    while (!retained->mpm->restart_pending && !retained->mpm->shutdown_pending) {
3117
        ap_wait_or_timeout(&exitwhy, &status, &pid, pconf, ap_server_conf);
2961
        ap_wait_or_timeout(&exitwhy, &status, &pid, pconf, ap_server_conf);
3118
2962
3119
        if (pid.pid != -1) {
2963
        if (pid.pid != -1) {
Lines 3127-3134 static void server_main_loop(int remaining_childre Link Here
3127
                 */
2971
                 */
3128
                if (child_slot < 0
2972
                if (child_slot < 0
3129
                    || ap_get_scoreboard_process(child_slot)->generation
2973
                    || ap_get_scoreboard_process(child_slot)->generation
3130
                       == retained->my_generation) {
2974
                       == retained->mpm->my_generation) {
3131
                    shutdown_pending = 1;
2975
                    retained->mpm->shutdown_pending = 1;
3132
                    child_fatal = 1;
2976
                    child_fatal = 1;
3133
                    /*
2977
                    /*
3134
                     * total_daemons counting will be off now, but as we
2978
                     * total_daemons counting will be off now, but as we
Lines 3183-3189 static void server_main_loop(int remaining_childre Link Here
3183
                /* handled */
3027
                /* handled */
3184
            }
3028
            }
3185
#endif
3029
#endif
3186
            else if (retained->is_graceful) {
3030
            else if (retained->mpm->was_graceful) {
3187
                /* Great, we've probably just lost a slot in the
3031
                /* Great, we've probably just lost a slot in the
3188
                 * scoreboard.  Somehow we don't know about this child.
3032
                 * scoreboard.  Somehow we don't know about this child.
3189
                 */
3033
                 */
Lines 3221-3245 static void server_main_loop(int remaining_childre Link Here
3221
3065
3222
static int event_run(apr_pool_t * _pconf, apr_pool_t * plog, server_rec * s)
3066
static int event_run(apr_pool_t * _pconf, apr_pool_t * plog, server_rec * s)
3223
{
3067
{
3224
    int num_buckets = retained->num_buckets;
3068
    int num_buckets = retained->mpm->num_buckets;
3225
    int remaining_children_to_start;
3069
    int remaining_children_to_start;
3226
    int i;
3070
    int i;
3227
3071
3228
    ap_log_pid(pconf, ap_pid_fname);
3072
    ap_log_pid(pconf, ap_pid_fname);
3229
3073
3230
    if (!retained->is_graceful) {
3074
    if (!retained->mpm->was_graceful) {
3231
        if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) {
3075
        if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) {
3232
            mpm_state = AP_MPMQ_STOPPING;
3076
            retained->mpm->mpm_state = AP_MPMQ_STOPPING;
3233
            return !OK;
3077
            return !OK;
3234
        }
3078
        }
3235
        /* fix the generation number in the global score; we just got a new,
3079
        /* fix the generation number in the global score; we just got a new,
3236
         * cleared scoreboard
3080
         * cleared scoreboard
3237
         */
3081
         */
3238
        ap_scoreboard_image->global->running_generation = retained->my_generation;
3082
        ap_scoreboard_image->global->running_generation = retained->mpm->my_generation;
3239
    }
3083
    }
3240
3084
3241
    restart_pending = shutdown_pending = 0;
3085
    ap_unixd_mpm_set_signals(pconf, one_process);
3242
    set_signals();
3243
3086
3244
    /* Don't thrash since num_buckets depends on the
3087
    /* Don't thrash since num_buckets depends on the
3245
     * system and the number of online CPU cores...
3088
     * system and the number of online CPU cores...
Lines 3272-3278 static int event_run(apr_pool_t * _pconf, apr_pool Link Here
3272
    if (remaining_children_to_start > active_daemons_limit) {
3115
    if (remaining_children_to_start > active_daemons_limit) {
3273
        remaining_children_to_start = active_daemons_limit;
3116
        remaining_children_to_start = active_daemons_limit;
3274
    }
3117
    }
3275
    if (!retained->is_graceful) {
3118
    if (!retained->mpm->was_graceful) {
3276
        startup_children(remaining_children_to_start);
3119
        startup_children(remaining_children_to_start);
3277
        remaining_children_to_start = 0;
3120
        remaining_children_to_start = 0;
3278
    }
3121
    }
Lines 3290-3301 static int event_run(apr_pool_t * _pconf, apr_pool Link Here
3290
    ap_log_command_line(plog, s);
3133
    ap_log_command_line(plog, s);
3291
    ap_log_mpm_common(s);
3134
    ap_log_mpm_common(s);
3292
3135
3293
    mpm_state = AP_MPMQ_RUNNING;
3136
    retained->mpm->mpm_state = AP_MPMQ_RUNNING;
3294
3137
3295
    server_main_loop(remaining_children_to_start, num_buckets);
3138
    server_main_loop(remaining_children_to_start, num_buckets);
3296
    mpm_state = AP_MPMQ_STOPPING;
3139
    retained->mpm->mpm_state = AP_MPMQ_STOPPING;
3297
3140
3298
    if (shutdown_pending && !retained->is_graceful) {
3141
    if (retained->mpm->shutdown_pending && retained->mpm->is_ungraceful) {
3299
        /* Time to shut down:
3142
        /* Time to shut down:
3300
         * Kill child processes, tell them to call child_exit, etc...
3143
         * Kill child processes, tell them to call child_exit, etc...
3301
         */
3144
         */
Lines 3313-3319 static int event_run(apr_pool_t * _pconf, apr_pool Link Here
3313
                         ap_server_conf, APLOGNO(00491) "caught SIGTERM, shutting down");
3156
                         ap_server_conf, APLOGNO(00491) "caught SIGTERM, shutting down");
3314
        }
3157
        }
3315
        return DONE;
3158
        return DONE;
3316
    } else if (shutdown_pending) {
3159
    } else if (retained->mpm->shutdown_pending) {
3317
        /* Time to gracefully shut down:
3160
        /* Time to gracefully shut down:
3318
         * Kill child processes, tell them to call child_exit, etc...
3161
         * Kill child processes, tell them to call child_exit, etc...
3319
         */
3162
         */
Lines 3343-3349 static int event_run(apr_pool_t * _pconf, apr_pool Link Here
3343
        }
3186
        }
3344
3187
3345
        /* Don't really exit until each child has finished */
3188
        /* Don't really exit until each child has finished */
3346
        shutdown_pending = 0;
3189
        retained->mpm->shutdown_pending = 0;
3347
        do {
3190
        do {
3348
            /* Pause for a second */
3191
            /* Pause for a second */
3349
            apr_sleep(apr_time_from_sec(1));
3192
            apr_sleep(apr_time_from_sec(1));
Lines 3359-3365 static int event_run(apr_pool_t * _pconf, apr_pool Link Here
3359
                    break;
3202
                    break;
3360
                }
3203
                }
3361
            }
3204
            }
3362
        } while (!shutdown_pending && active_children &&
3205
        } while (!retained->mpm->shutdown_pending && active_children &&
3363
                 (!ap_graceful_shutdown_timeout || apr_time_now() < cutoff));
3206
                 (!ap_graceful_shutdown_timeout || apr_time_now() < cutoff));
3364
3207
3365
        /* We might be here because we received SIGTERM, either
3208
        /* We might be here because we received SIGTERM, either
Lines 3387-3396 static int event_run(apr_pool_t * _pconf, apr_pool Link Here
3387
    /* XXX: we really need to make sure this new generation number isn't in
3230
    /* XXX: we really need to make sure this new generation number isn't in
3388
     * use by any of the children.
3231
     * use by any of the children.
3389
     */
3232
     */
3390
    ++retained->my_generation;
3233
    ++retained->mpm->my_generation;
3391
    ap_scoreboard_image->global->running_generation = retained->my_generation;
3234
    ap_scoreboard_image->global->running_generation = retained->mpm->my_generation;
3392
3235
3393
    if (retained->is_graceful) {
3236
    if (!retained->mpm->is_ungraceful) {
3394
        ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00493)
3237
        ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00493)
3395
                     AP_SIG_GRACEFUL_STRING
3238
                     AP_SIG_GRACEFUL_STRING
3396
                     " received.  Doing graceful restart");
3239
                     " received.  Doing graceful restart");
Lines 3491-3497 static int event_open_logs(apr_pool_t * p, apr_poo Link Here
3491
    pconf = p;
3334
    pconf = p;
3492
3335
3493
    /* the reverse of pre_config, we want this only the first time around */
3336
    /* the reverse of pre_config, we want this only the first time around */
3494
    if (retained->module_loads == 1) {
3337
    if (retained->mpm->module_loads == 1) {
3495
        startup = 1;
3338
        startup = 1;
3496
        level_flags |= APLOG_STARTUP;
3339
        level_flags |= APLOG_STARTUP;
3497
    }
3340
    }
Lines 3506-3514 static int event_open_logs(apr_pool_t * p, apr_poo Link Here
3506
    if (one_process) {
3349
    if (one_process) {
3507
        num_buckets = 1;
3350
        num_buckets = 1;
3508
    }
3351
    }
3509
    else if (retained->is_graceful) {
3352
    else if (retained->mpm->was_graceful) {
3510
        /* Preserve the number of buckets on graceful restarts. */
3353
        /* Preserve the number of buckets on graceful restarts. */
3511
        num_buckets = retained->num_buckets;
3354
        num_buckets = retained->mpm->num_buckets;
3512
    }
3355
    }
3513
    if ((rv = ap_duplicate_listeners(pconf, ap_server_conf,
3356
    if ((rv = ap_duplicate_listeners(pconf, ap_server_conf,
3514
                                     &listen_buckets, &num_buckets))) {
3357
                                     &listen_buckets, &num_buckets))) {
Lines 3530-3554 static int event_open_logs(apr_pool_t * p, apr_poo Link Here
3530
        all_buckets[i].listeners = listen_buckets[i];
3373
        all_buckets[i].listeners = listen_buckets[i];
3531
    }
3374
    }
3532
3375
3533
    if (retained->max_buckets < num_buckets) {
3376
    if (retained->mpm->max_buckets < num_buckets) {
3534
        int new_max, *new_ptr;
3377
        int new_max, *new_ptr;
3535
        new_max = retained->max_buckets * 2;
3378
        new_max = retained->mpm->max_buckets * 2;
3536
        if (new_max < num_buckets) {
3379
        if (new_max < num_buckets) {
3537
            new_max = num_buckets;
3380
            new_max = num_buckets;
3538
        }
3381
        }
3539
        new_ptr = (int *)apr_palloc(ap_pglobal, new_max * sizeof(int));
3382
        new_ptr = (int *)apr_palloc(ap_pglobal, new_max * sizeof(int));
3540
        memcpy(new_ptr, retained->idle_spawn_rate,
3383
        memcpy(new_ptr, retained->idle_spawn_rate,
3541
               retained->num_buckets * sizeof(int));
3384
               retained->mpm->num_buckets * sizeof(int));
3542
        retained->idle_spawn_rate = new_ptr;
3385
        retained->idle_spawn_rate = new_ptr;
3543
        retained->max_buckets = new_max;
3386
        retained->mpm->max_buckets = new_max;
3544
    }
3387
    }
3545
    if (retained->num_buckets < num_buckets) {
3388
    if (retained->mpm->num_buckets < num_buckets) {
3546
        int rate_max = 1;
3389
        int rate_max = 1;
3547
        /* If new buckets are added, set their idle spawn rate to
3390
        /* If new buckets are added, set their idle spawn rate to
3548
         * the highest so far, so that they get filled as quickly
3391
         * the highest so far, so that they get filled as quickly
3549
         * as the existing ones.
3392
         * as the existing ones.
3550
         */
3393
         */
3551
        for (i = 0; i < retained->num_buckets; i++) {
3394
        for (i = 0; i < retained->mpm->num_buckets; i++) {
3552
            if (rate_max < retained->idle_spawn_rate[i]) {
3395
            if (rate_max < retained->idle_spawn_rate[i]) {
3553
                rate_max = retained->idle_spawn_rate[i];
3396
                rate_max = retained->idle_spawn_rate[i];
3554
            }
3397
            }
Lines 3557-3563 static int event_open_logs(apr_pool_t * p, apr_poo Link Here
3557
            retained->idle_spawn_rate[i] = rate_max;
3400
            retained->idle_spawn_rate[i] = rate_max;
3558
        }
3401
        }
3559
    }
3402
    }
3560
    retained->num_buckets = num_buckets;
3403
    retained->mpm->num_buckets = num_buckets;
3561
3404
3562
    /* for skiplist */
3405
    /* for skiplist */
3563
    srand((unsigned int)apr_time_now());
3406
    srand((unsigned int)apr_time_now());
Lines 3570-3578 static int event_pre_config(apr_pool_t * pconf, ap Link Here
3570
    int no_detach, debug, foreground;
3413
    int no_detach, debug, foreground;
3571
    apr_status_t rv;
3414
    apr_status_t rv;
3572
    const char *userdata_key = "mpm_event_module";
3415
    const char *userdata_key = "mpm_event_module";
3416
    int test_atomics = 0;
3573
3417
3574
    mpm_state = AP_MPMQ_STARTING;
3575
3576
    debug = ap_exists_config_define("DEBUG");
3418
    debug = ap_exists_config_define("DEBUG");
3577
3419
3578
    if (debug) {
3420
    if (debug) {
Lines 3585-3599 static int event_pre_config(apr_pool_t * pconf, ap Link Here
3585
        foreground = ap_exists_config_define("FOREGROUND");
3427
        foreground = ap_exists_config_define("FOREGROUND");
3586
    }
3428
    }
3587
3429
3588
    /* sigh, want this only the second time around */
3589
    retained = ap_retained_data_get(userdata_key);
3430
    retained = ap_retained_data_get(userdata_key);
3590
    if (!retained) {
3431
    if (!retained) {
3591
        retained = ap_retained_data_create(userdata_key, sizeof(*retained));
3432
        retained = ap_retained_data_create(userdata_key, sizeof(*retained));
3433
        retained->mpm = ap_unixd_mpm_get_retained_data();
3592
        retained->max_daemons_limit = -1;
3434
        retained->max_daemons_limit = -1;
3435
        if (retained->mpm->module_loads) {
3436
            test_atomics = 1;
3437
        }
3593
    }
3438
    }
3594
    ++retained->module_loads;
3439
    if (retained->mpm->baton != retained) {
3595
    if (retained->module_loads == 2) {
3440
        retained->mpm->was_graceful = 0;
3596
        /* test for correct operation of fdqueue */
3441
        retained->mpm->baton = retained;
3442
    }
3443
    retained->mpm->mpm_state = AP_MPMQ_STARTING;
3444
    ++retained->mpm->module_loads;
3445
3446
    /* test once for correct operation of fdqueue */
3447
    if (test_atomics || retained->mpm->module_loads == 2) {
3597
        static apr_uint32_t foo1, foo2;
3448
        static apr_uint32_t foo1, foo2;
3598
3449
3599
        apr_atomic_set32(&foo1, 100);
3450
        apr_atomic_set32(&foo1, 100);
Lines 3603-3609 static int event_pre_config(apr_pool_t * pconf, ap Link Here
3603
                         "atomics not working as expected - add32 of negative number");
3454
                         "atomics not working as expected - add32 of negative number");
3604
            return HTTP_INTERNAL_SERVER_ERROR;
3455
            return HTTP_INTERNAL_SERVER_ERROR;
3605
        }
3456
        }
3457
    }
3606
3458
3459
    /* sigh, want this only the second time around */
3460
    if (retained->mpm->module_loads == 2) {
3607
        rv = apr_pollset_create(&event_pollset, 1, plog,
3461
        rv = apr_pollset_create(&event_pollset, 1, plog,
3608
                                APR_POLLSET_THREADSAFE | APR_POLLSET_NOCOPY);
3462
                                APR_POLLSET_THREADSAFE | APR_POLLSET_NOCOPY);
3609
        if (rv != APR_SUCCESS) {
3463
        if (rv != APR_SUCCESS) {
Lines 3714-3720 static int event_check_config(apr_pool_t *p, apr_p Link Here
3714
    int startup = 0;
3568
    int startup = 0;
3715
3569
3716
    /* the reverse of pre_config, we want this only the first time around */
3570
    /* the reverse of pre_config, we want this only the first time around */
3717
    if (retained->module_loads == 1) {
3571
    if (retained->mpm->module_loads == 1) {
3718
        startup = 1;
3572
        startup = 1;
3719
    }
3573
    }
3720
3574
(-)server/mpm/motorz/motorz.c (-178 / +62 lines)
Lines 23-29 static motorz_core_t *g_motorz_core; Link Here
23
static int threads_per_child = 16;
23
static int threads_per_child = 16;
24
static int ap_num_kids = DEFAULT_START_DAEMON;
24
static int ap_num_kids = DEFAULT_START_DAEMON;
25
static int thread_limit = MAX_THREAD_LIMIT/10;
25
static int thread_limit = MAX_THREAD_LIMIT/10;
26
static int mpm_state = AP_MPMQ_STARTING;
27
26
28
/* one_process --- debugging mode variable; can be set from the command line
27
/* one_process --- debugging mode variable; can be set from the command line
29
 * with the -X flag.  If set, this gets you the child_main loop running
28
 * with the -X flag.  If set, this gets you the child_main loop running
Lines 43-49 static apr_pool_t *pchild; /* Pool fo Link Here
43
static pid_t ap_my_pid; /* it seems silly to call getpid all the time */
42
static pid_t ap_my_pid; /* it seems silly to call getpid all the time */
44
static pid_t parent_pid;
43
static pid_t parent_pid;
45
static int my_child_num;
44
static int my_child_num;
46
static int num_buckets; /* Number of listeners buckets */
47
static motorz_child_bucket *all_buckets, /* All listeners buckets */
45
static motorz_child_bucket *all_buckets, /* All listeners buckets */
48
                            *my_bucket;   /* Current child bucket */
46
                            *my_bucket;   /* Current child bucket */
49
47
Lines 571-584 static void motorz_note_child_started(motorz_core_ Link Here
571
    ap_scoreboard_image->parent[slot].pid = pid;
569
    ap_scoreboard_image->parent[slot].pid = pid;
572
    ap_run_child_status(ap_server_conf,
570
    ap_run_child_status(ap_server_conf,
573
                        ap_scoreboard_image->parent[slot].pid,
571
                        ap_scoreboard_image->parent[slot].pid,
574
                        mz->my_generation, slot, MPM_CHILD_STARTED);
572
                        mz->mpm->my_generation, slot, MPM_CHILD_STARTED);
575
}
573
}
576
574
577
/* a clean exit from a child with proper cleanup */
575
/* a clean exit from a child with proper cleanup */
578
static void clean_child_exit(int code)
576
static void clean_child_exit(int code)
579
{
577
{
580
    mpm_state = AP_MPMQ_STOPPING;
578
    motorz_core_t *mz = motorz_core_get();
581
579
580
    mz->mpm->mpm_state = AP_MPMQ_STOPPING;
581
582
    apr_signal(SIGHUP, SIG_IGN);
582
    apr_signal(SIGHUP, SIG_IGN);
583
    apr_signal(SIGTERM, SIG_IGN);
583
    apr_signal(SIGTERM, SIG_IGN);
584
584
Lines 602-608 static apr_status_t accept_mutex_on(void) Link Here
602
    if (rv != APR_SUCCESS) {
602
    if (rv != APR_SUCCESS) {
603
        const char *msg = "couldn't grab the accept mutex";
603
        const char *msg = "couldn't grab the accept mutex";
604
604
605
        if (mz->my_generation !=
605
        if (mz->mpm->my_generation !=
606
            ap_scoreboard_image->global->running_generation) {
606
            ap_scoreboard_image->global->running_generation) {
607
            ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, ap_server_conf, APLOGNO(02855) "%s", msg);
607
            ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, ap_server_conf, APLOGNO(02855) "%s", msg);
608
            clean_child_exit(0);
608
            clean_child_exit(0);
Lines 622-628 static apr_status_t accept_mutex_off(void) Link Here
622
    if (rv != APR_SUCCESS) {
622
    if (rv != APR_SUCCESS) {
623
        const char *msg = "couldn't release the accept mutex";
623
        const char *msg = "couldn't release the accept mutex";
624
624
625
        if (mz->my_generation !=
625
        if (mz->mpm->my_generation !=
626
            ap_scoreboard_image->global->running_generation) {
626
            ap_scoreboard_image->global->running_generation) {
627
            ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, ap_server_conf, APLOGNO(02857) "%s", msg);
627
            ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, ap_server_conf, APLOGNO(02857) "%s", msg);
628
            /* don't exit here... we have a connection to
628
            /* don't exit here... we have a connection to
Lines 695-704 static int motorz_query(int query_code, int *resul Link Here
695
        *result = ap_num_kids;
695
        *result = ap_num_kids;
696
        break;
696
        break;
697
    case AP_MPMQ_MPM_STATE:
697
    case AP_MPMQ_MPM_STATE:
698
        *result = mpm_state;
698
        *result = mz->mpm->mpm_state;
699
        break;
699
        break;
700
    case AP_MPMQ_GENERATION:
700
    case AP_MPMQ_GENERATION:
701
        *result = mz->my_generation;
701
        *result = mz->mpm->my_generation;
702
        break;
702
        break;
703
    default:
703
    default:
704
        *rv = APR_ENOTIMPL;
704
        *rv = APR_ENOTIMPL;
Lines 721-734 static void just_die(int sig) Link Here
721
    clean_child_exit(0);
721
    clean_child_exit(0);
722
}
722
}
723
723
724
/* volatile because they're updated from a signal handler */
724
/* volatile because it's updated from a signal handler */
725
static int volatile shutdown_pending;
726
static int volatile restart_pending;
727
static int volatile die_now = 0;
725
static int volatile die_now = 0;
728
726
729
static void stop_listening(int sig)
727
static void stop_listening(int sig)
730
{
728
{
731
    mpm_state = AP_MPMQ_STOPPING;
729
    motorz_core_t *mz = motorz_core_get();
730
731
    mz->mpm->mpm_state = AP_MPMQ_STOPPING;
732
    ap_close_listeners_ex(my_bucket->listeners);
732
    ap_close_listeners_ex(my_bucket->listeners);
733
733
734
    /* For a graceful stop, we want the child to exit when done */
734
    /* For a graceful stop, we want the child to exit when done */
Lines 735-852 static void stop_listening(int sig) Link Here
735
    die_now = 1;
735
    die_now = 1;
736
}
736
}
737
737
738
static void sig_term(int sig)
739
{
740
    motorz_core_t *mz = motorz_core_get();
741
    if (shutdown_pending == 1) {
742
        /* Um, is this _probably_ not an error, if the user has
743
         * tried to do a shutdown twice quickly, so we won't
744
         * worry about reporting it.
745
         */
746
        return;
747
    }
748
    mpm_state = AP_MPMQ_STOPPING;
749
    shutdown_pending = 1;
750
    mz->is_graceful = (sig == AP_SIG_GRACEFUL_STOP);
751
}
752
753
/* restart() is the signal handler for SIGHUP and AP_SIG_GRACEFUL
754
 * in the parent process, unless running in ONE_PROCESS mode
755
 */
756
static void restart(int sig)
757
{
758
    motorz_core_t *mz = motorz_core_get();
759
    if (restart_pending == 1) {
760
        /* Probably not an error - don't bother reporting it */
761
        return;
762
    }
763
    mpm_state = AP_MPMQ_STOPPING;
764
    restart_pending = 1;
765
    mz->is_graceful = (sig == AP_SIG_GRACEFUL);
766
}
767
768
static void set_signals(void)
769
{
770
#ifndef NO_USE_SIGACTION
771
    struct sigaction sa;
772
#endif
773
774
    if (!one_process) {
775
        ap_fatal_signal_setup(ap_server_conf, pconf);
776
    }
777
778
#ifndef NO_USE_SIGACTION
779
    sigemptyset(&sa.sa_mask);
780
    sa.sa_flags = 0;
781
782
    sa.sa_handler = sig_term;
783
    if (sigaction(SIGTERM, &sa, NULL) < 0)
784
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(02859) "sigaction(SIGTERM)");
785
#ifdef AP_SIG_GRACEFUL_STOP
786
    if (sigaction(AP_SIG_GRACEFUL_STOP, &sa, NULL) < 0)
787
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(02860)
788
                     "sigaction(" AP_SIG_GRACEFUL_STOP_STRING ")");
789
#endif
790
#ifdef SIGINT
791
    if (sigaction(SIGINT, &sa, NULL) < 0)
792
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(02861) "sigaction(SIGINT)");
793
#endif
794
#ifdef SIGXCPU
795
    sa.sa_handler = SIG_DFL;
796
    if (sigaction(SIGXCPU, &sa, NULL) < 0)
797
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(02862) "sigaction(SIGXCPU)");
798
#endif
799
#ifdef SIGXFSZ
800
    /* For systems following the LFS standard, ignoring SIGXFSZ allows
801
     * a write() beyond the 2GB limit to fail gracefully with E2BIG
802
     * rather than terminate the process. */
803
    sa.sa_handler = SIG_IGN;
804
    if (sigaction(SIGXFSZ, &sa, NULL) < 0)
805
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(02863) "sigaction(SIGXFSZ)");
806
#endif
807
#ifdef SIGPIPE
808
    sa.sa_handler = SIG_IGN;
809
    if (sigaction(SIGPIPE, &sa, NULL) < 0)
810
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(02864) "sigaction(SIGPIPE)");
811
#endif
812
813
    /* we want to ignore HUPs and AP_SIG_GRACEFUL while we're busy
814
     * processing one
815
     */
816
    sigaddset(&sa.sa_mask, SIGHUP);
817
    sigaddset(&sa.sa_mask, AP_SIG_GRACEFUL);
818
    sa.sa_handler = restart;
819
    if (sigaction(SIGHUP, &sa, NULL) < 0)
820
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(02865) "sigaction(SIGHUP)");
821
    if (sigaction(AP_SIG_GRACEFUL, &sa, NULL) < 0)
822
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(02866) "sigaction(" AP_SIG_GRACEFUL_STRING ")");
823
#else
824
    if (!one_process) {
825
#ifdef SIGXCPU
826
        apr_signal(SIGXCPU, SIG_DFL);
827
#endif /* SIGXCPU */
828
#ifdef SIGXFSZ
829
        apr_signal(SIGXFSZ, SIG_IGN);
830
#endif /* SIGXFSZ */
831
    }
832
833
    apr_signal(SIGTERM, sig_term);
834
#ifdef SIGHUP
835
    apr_signal(SIGHUP, restart);
836
#endif /* SIGHUP */
837
#ifdef AP_SIG_GRACEFUL
838
    apr_signal(AP_SIG_GRACEFUL, restart);
839
#endif /* AP_SIG_GRACEFUL */
840
#ifdef AP_SIG_GRACEFUL_STOP
841
    apr_signal(AP_SIG_GRACEFUL_STOP, sig_term);
842
#endif /* AP_SIG_GRACEFUL */
843
#ifdef SIGPIPE
844
    apr_signal(SIGPIPE, SIG_IGN);
845
#endif /* SIGPIPE */
846
847
#endif
848
}
849
850
/*****************************************************************
738
/*****************************************************************
851
 * Child process main loop.
739
 * Child process main loop.
852
 * The following vars are static to avoid getting clobbered by longjmp();
740
 * The following vars are static to avoid getting clobbered by longjmp();
Lines 870-878 static void child_main(motorz_core_t *mz, int chil Link Here
870
    ap_sb_handle_t *sbh;
758
    ap_sb_handle_t *sbh;
871
    const char *lockfile;
759
    const char *lockfile;
872
760
873
    mpm_state = AP_MPMQ_STARTING; /* for benefit of any hooks that run as this
761
    /* for benefit of any hooks that run as this child initializes */
874
                                   * child initializes
762
    mz->mpm->mpm_state = AP_MPMQ_STARTING;
875
                                   */
876
763
877
    my_child_num = child_num_arg;
764
    my_child_num = child_num_arg;
878
    ap_my_pid = getpid();
765
    ap_my_pid = getpid();
Lines 898-904 static void child_main(motorz_core_t *mz, int chil Link Here
898
    apr_pool_tag(ptrans, "transaction");
785
    apr_pool_tag(ptrans, "transaction");
899
786
900
    /* close unused listeners and pods */
787
    /* close unused listeners and pods */
901
    for (i = 0; i < num_buckets; i++) {
788
    for (i = 0; i < mz->mpm->num_buckets; i++) {
902
        if (i != child_bucket) {
789
        if (i != child_bucket) {
903
            ap_close_listeners_ex(all_buckets[i].listeners);
790
            ap_close_listeners_ex(all_buckets[i].listeners);
904
            ap_mpm_pod_close(all_buckets[i].pod);
791
            ap_mpm_pod_close(all_buckets[i].pod);
Lines 984-995 static void child_main(motorz_core_t *mz, int chil Link Here
984
        lr->accept_func = ap_unixd_accept;
871
        lr->accept_func = ap_unixd_accept;
985
    }
872
    }
986
873
987
    mpm_state = AP_MPMQ_RUNNING;
874
    mz->mpm->mpm_state = AP_MPMQ_RUNNING;
988
875
989
    /* die_now is set when AP_SIG_GRACEFUL is received in the child;
876
    /* die_now is set when AP_SIG_GRACEFUL is received in the child;
990
     * shutdown_pending is set when SIGTERM is received when running
877
     * shutdown_pending is set when SIGTERM is received when running
991
     * in single process mode.  */
878
     * in single process mode.  */
992
    while (!die_now && !shutdown_pending) {
879
    while (!die_now && !mz->mpm->shutdown_pending) {
993
        /*
880
        /*
994
         * (Re)initialize this child to a pre-connection state.
881
         * (Re)initialize this child to a pre-connection state.
995
         */
882
         */
Lines 1049-1055 static void child_main(motorz_core_t *mz, int chil Link Here
1049
        if (ap_mpm_pod_check(my_bucket->pod) == APR_SUCCESS) { /* selected as idle? */
936
        if (ap_mpm_pod_check(my_bucket->pod) == APR_SUCCESS) { /* selected as idle? */
1050
            die_now = 1;
937
            die_now = 1;
1051
        }
938
        }
1052
        else if (mz->my_generation !=
939
        else if (mz->mpm->my_generation !=
1053
                 ap_scoreboard_image->global->running_generation) { /* restart? */
940
                 ap_scoreboard_image->global->running_generation) { /* restart? */
1054
            /* yeah, this could be non-graceful restart, in which case the
941
            /* yeah, this could be non-graceful restart, in which case the
1055
             * parent will kill us soon enough, but why bother checking?
942
             * parent will kill us soon enough, but why bother checking?
Lines 1072-1084 static int make_child(motorz_core_t *mz, server_re Link Here
1072
    if (one_process) {
959
    if (one_process) {
1073
        my_bucket = &all_buckets[0];
960
        my_bucket = &all_buckets[0];
1074
961
1075
        apr_signal(SIGHUP, sig_term);
1076
        /* Don't catch AP_SIG_GRACEFUL in ONE_PROCESS mode :) */
1077
        apr_signal(SIGINT, sig_term);
1078
#ifdef SIGQUIT
1079
        apr_signal(SIGQUIT, SIG_DFL);
1080
#endif
1081
        apr_signal(SIGTERM, sig_term);
1082
        motorz_note_child_started(mz, slot, getpid());
962
        motorz_note_child_started(mz, slot, getpid());
1083
        child_main(mz, slot, 0);
963
        child_main(mz, slot, 0);
1084
        /* NOTREACHED */
964
        /* NOTREACHED */
Lines 1156-1162 static void startup_children(motorz_core_t *mz, in Link Here
1156
        if (ap_scoreboard_image->servers[i][0].status != SERVER_DEAD) {
1036
        if (ap_scoreboard_image->servers[i][0].status != SERVER_DEAD) {
1157
            continue;
1037
            continue;
1158
        }
1038
        }
1159
        if (make_child(mz, ap_server_conf, i, i % num_buckets) < 0) {
1039
        if (make_child(mz, ap_server_conf, i, i % mz->mpm->num_buckets) < 0) {
1160
            break;
1040
            break;
1161
        }
1041
        }
1162
        --number_to_start;
1042
        --number_to_start;
Lines 1194-1205 static void perform_idle_server_maintenance(motorz Link Here
1194
         * shut down gracefully, in case it happened to pick up a request
1074
         * shut down gracefully, in case it happened to pick up a request
1195
         * while we were counting
1075
         * while we were counting
1196
         */
1076
         */
1197
        bucket_kill_child_record = (bucket_kill_child_record + 1) % num_buckets;
1077
        bucket_kill_child_record = (bucket_kill_child_record + 1) % mz->mpm->num_buckets;
1198
        ap_mpm_pod_signal(all_buckets[bucket_kill_child_record].pod);
1078
        ap_mpm_pod_signal(all_buckets[bucket_kill_child_record].pod);
1199
    }
1079
    }
1200
    else if (active < ap_num_kids) {
1080
    else if (active < ap_num_kids) {
1201
        bucket_make_child_record++;
1081
        bucket_make_child_record++;
1202
        bucket_make_child_record %= num_buckets;
1082
        bucket_make_child_record %= mz->mpm->num_buckets;
1203
        make_child(mz, ap_server_conf, free_slots[0],
1083
        make_child(mz, ap_server_conf, free_slots[0],
1204
                   bucket_make_child_record);
1084
                   bucket_make_child_record);
1205
    }
1085
    }
Lines 1218-1236 static int motorz_run(apr_pool_t *_pconf, apr_pool Link Here
1218
1098
1219
    ap_log_pid(pconf, ap_pid_fname);
1099
    ap_log_pid(pconf, ap_pid_fname);
1220
1100
1221
    if (!mz->is_graceful) {
1101
    if (!mz->mpm->was_graceful) {
1222
        if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) {
1102
        if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) {
1223
            mpm_state = AP_MPMQ_STOPPING;
1103
            mz->mpm->mpm_state = AP_MPMQ_STOPPING;
1224
            return !OK;
1104
            return !OK;
1225
        }
1105
        }
1226
        /* fix the generation number in the global score; we just got a new,
1106
        /* fix the generation number in the global score; we just got a new,
1227
         * cleared scoreboard
1107
         * cleared scoreboard
1228
         */
1108
         */
1229
        ap_scoreboard_image->global->running_generation = mz->my_generation;
1109
        ap_scoreboard_image->global->running_generation = mz->mpm->my_generation;
1230
    }
1110
    }
1231
1111
1232
    restart_pending = shutdown_pending = 0;
1112
    ap_unixd_mpm_set_signals(pconf, one_process);
1233
    set_signals();
1234
1113
1235
    if (one_process) {
1114
    if (one_process) {
1236
        AP_MONCONTROL(1);
1115
        AP_MONCONTROL(1);
Lines 1243-1250 static int motorz_run(apr_pool_t *_pconf, apr_pool Link Here
1243
    /* Don't thrash since num_buckets depends on the
1122
    /* Don't thrash since num_buckets depends on the
1244
     * system and the number of online CPU cores...
1123
     * system and the number of online CPU cores...
1245
     */
1124
     */
1246
    if (ap_num_kids < num_buckets)
1125
    if (ap_num_kids < mz->mpm->num_buckets)
1247
        ap_num_kids = num_buckets;
1126
        ap_num_kids = mz->mpm->num_buckets;
1248
1127
1249
    /* If we're doing a graceful_restart then we're going to see a lot
1128
    /* If we're doing a graceful_restart then we're going to see a lot
1250
     * of children exiting immediately when we get into the main loop
1129
     * of children exiting immediately when we get into the main loop
Lines 1255-1261 static int motorz_run(apr_pool_t *_pconf, apr_pool Link Here
1255
     * supposed to start up without the 1 second penalty between each fork.
1134
     * supposed to start up without the 1 second penalty between each fork.
1256
     */
1135
     */
1257
    remaining_children_to_start = ap_num_kids;
1136
    remaining_children_to_start = ap_num_kids;
1258
    if (!mz->is_graceful) {
1137
    if (!mz->mpm->was_graceful) {
1259
        startup_children(mz, remaining_children_to_start);
1138
        startup_children(mz, remaining_children_to_start);
1260
        remaining_children_to_start = 0;
1139
        remaining_children_to_start = 0;
1261
    }
1140
    }
Lines 1274-1282 static int motorz_run(apr_pool_t *_pconf, apr_pool Link Here
1274
                    : "none",
1153
                    : "none",
1275
                apr_proc_mutex_defname());
1154
                apr_proc_mutex_defname());
1276
1155
1277
    mpm_state = AP_MPMQ_RUNNING;
1156
    mz->mpm->mpm_state = AP_MPMQ_RUNNING;
1278
1157
1279
    while (!restart_pending && !shutdown_pending) {
1158
    while (!mz->mpm->restart_pending && !mz->mpm->shutdown_pending) {
1280
        int child_slot;
1159
        int child_slot;
1281
        apr_exit_why_e exitwhy;
1160
        apr_exit_why_e exitwhy;
1282
        int status, processed_status;
1161
        int status, processed_status;
Lines 1300-1307 static int motorz_run(apr_pool_t *_pconf, apr_pool Link Here
1300
                 */
1179
                 */
1301
                if (child_slot < 0
1180
                if (child_slot < 0
1302
                    || ap_get_scoreboard_process(child_slot)->generation
1181
                    || ap_get_scoreboard_process(child_slot)->generation
1303
                       == mz->my_generation) {
1182
                       == mz->mpm->my_generation) {
1304
                    mpm_state = AP_MPMQ_STOPPING;
1183
                    mz->mpm->mpm_state = AP_MPMQ_STOPPING;
1305
                    return !OK;
1184
                    return !OK;
1306
                }
1185
                }
1307
                else {
1186
                else {
Lines 1332-1338 static int motorz_run(apr_pool_t *_pconf, apr_pool Link Here
1332
                /* handled */
1211
                /* handled */
1333
#endif
1212
#endif
1334
            }
1213
            }
1335
            else if (mz->is_graceful) {
1214
            else if (mz->mpm->was_graceful) {
1336
                /* Great, we've probably just lost a slot in the
1215
                /* Great, we've probably just lost a slot in the
1337
                 * scoreboard.  Somehow we don't know about this
1216
                 * scoreboard.  Somehow we don't know about this
1338
                 * child.
1217
                 * child.
Lines 1365-1373 static int motorz_run(apr_pool_t *_pconf, apr_pool Link Here
1365
        perform_idle_server_maintenance(mz, pconf);
1244
        perform_idle_server_maintenance(mz, pconf);
1366
    }
1245
    }
1367
1246
1368
    mpm_state = AP_MPMQ_STOPPING;
1247
    mz->mpm->mpm_state = AP_MPMQ_STOPPING;
1369
1248
1370
    if (shutdown_pending && !mz->is_graceful) {
1249
    if (mz->mpm->shutdown_pending && mz->mpm->is_ungraceful) {
1371
        /* Time to shut down:
1250
        /* Time to shut down:
1372
         * Kill child processes, tell them to call child_exit, etc...
1251
         * Kill child processes, tell them to call child_exit, etc...
1373
         */
1252
         */
Lines 1383-1389 static int motorz_run(apr_pool_t *_pconf, apr_pool Link Here
1383
                    "caught SIGTERM, shutting down");
1262
                    "caught SIGTERM, shutting down");
1384
1263
1385
        return DONE;
1264
        return DONE;
1386
    } else if (shutdown_pending) {
1265
    } else if (mz->mpm->shutdown_pending) {
1387
        /* Time to perform a graceful shut down:
1266
        /* Time to perform a graceful shut down:
1388
         * Reap the inactive children, and ask the active ones
1267
         * Reap the inactive children, and ask the active ones
1389
         * to close their listeners, then wait until they are
1268
         * to close their listeners, then wait until they are
Lines 1396-1402 static int motorz_run(apr_pool_t *_pconf, apr_pool Link Here
1396
        ap_close_listeners();
1275
        ap_close_listeners();
1397
1276
1398
        /* kill off the idle ones */
1277
        /* kill off the idle ones */
1399
        for (i = 0; i < num_buckets; i++) {
1278
        for (i = 0; i < mz->mpm->num_buckets; i++) {
1400
            ap_mpm_pod_killpg(all_buckets[i].pod, mz->max_daemons_limit);
1279
            ap_mpm_pod_killpg(all_buckets[i].pod, mz->max_daemons_limit);
1401
        }
1280
        }
1402
1281
Lines 1424-1430 static int motorz_run(apr_pool_t *_pconf, apr_pool Link Here
1424
        }
1303
        }
1425
1304
1426
        /* Don't really exit until each child has finished */
1305
        /* Don't really exit until each child has finished */
1427
        shutdown_pending = 0;
1306
        mz->mpm->shutdown_pending = 0;
1428
        do {
1307
        do {
1429
            /* Pause for a second */
1308
            /* Pause for a second */
1430
            sleep(1);
1309
            sleep(1);
Lines 1440-1446 static int motorz_run(apr_pool_t *_pconf, apr_pool Link Here
1440
                    break;
1319
                    break;
1441
                }
1320
                }
1442
            }
1321
            }
1443
        } while (!shutdown_pending && active_children &&
1322
        } while (!mz->mpm->shutdown_pending && active_children &&
1444
                 (!ap_graceful_shutdown_timeout || apr_time_now() < cutoff));
1323
                 (!ap_graceful_shutdown_timeout || apr_time_now() < cutoff));
1445
1324
1446
        /* We might be here because we received SIGTERM, either
1325
        /* We might be here because we received SIGTERM, either
Lines 1464-1478 static int motorz_run(apr_pool_t *_pconf, apr_pool Link Here
1464
    /* XXX: we really need to make sure this new generation number isn't in
1343
    /* XXX: we really need to make sure this new generation number isn't in
1465
     * use by any of the children.
1344
     * use by any of the children.
1466
     */
1345
     */
1467
    ++mz->my_generation;
1346
    ++mz->mpm->my_generation;
1468
    ap_scoreboard_image->global->running_generation = mz->my_generation;
1347
    ap_scoreboard_image->global->running_generation = mz->mpm->my_generation;
1469
1348
1470
    if (mz->is_graceful) {
1349
    if (!mz->mpm->is_ungraceful) {
1471
        ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(02882)
1350
        ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(02882)
1472
                    "Graceful restart requested, doing restart");
1351
                    "Graceful restart requested, doing restart");
1473
1352
1474
        /* kill off the idle ones */
1353
        /* kill off the idle ones */
1475
        for (i = 0; i < num_buckets; i++) {
1354
        for (i = 0; i < mz->mpm->num_buckets; i++) {
1476
            ap_mpm_pod_killpg(all_buckets[i].pod, mz->max_daemons_limit);
1355
            ap_mpm_pod_killpg(all_buckets[i].pod, mz->max_daemons_limit);
1477
        }
1356
        }
1478
1357
Lines 1525-1531 static int motorz_open_logs(apr_pool_t *p, apr_poo Link Here
1525
    pconf = p;
1404
    pconf = p;
1526
1405
1527
    /* the reverse of pre_config, we want this only the first time around */
1406
    /* the reverse of pre_config, we want this only the first time around */
1528
    if (mz->module_loads == 1) {
1407
    if (mz->mpm->module_loads == 1) {
1529
        startup = 1;
1408
        startup = 1;
1530
        level_flags |= APLOG_STARTUP;
1409
        level_flags |= APLOG_STARTUP;
1531
    }
1410
    }
Lines 1538-1559 static int motorz_open_logs(apr_pool_t *p, apr_poo Link Here
1538
    }
1417
    }
1539
1418
1540
    if (one_process) {
1419
    if (one_process) {
1541
        num_buckets = 1;
1420
        mz->mpm->num_buckets = 1;
1542
    }
1421
    }
1543
    else if (!mz->is_graceful) { /* Preserve the number of buckets
1422
    else if (!mz->mpm->was_graceful) {
1544
                                          on graceful restarts. */
1423
        /* Preserve the number of buckets on graceful restarts. */
1545
        num_buckets = 0;
1424
        mz->mpm->num_buckets = 0;
1546
    }
1425
    }
1547
    if ((rv = ap_duplicate_listeners(pconf, ap_server_conf,
1426
    if ((rv = ap_duplicate_listeners(pconf, ap_server_conf,
1548
                                     &listen_buckets, &num_buckets))) {
1427
                                     &listen_buckets, &mz->mpm->num_buckets))) {
1549
        ap_log_error(APLOG_MARK, APLOG_CRIT | level_flags, rv,
1428
        ap_log_error(APLOG_MARK, APLOG_CRIT | level_flags, rv,
1550
                     (startup ? NULL : s), APLOGNO(03276)
1429
                     (startup ? NULL : s), APLOGNO(03276)
1551
                     "could not duplicate listeners");
1430
                     "could not duplicate listeners");
1552
        return !OK;
1431
        return !OK;
1553
    }
1432
    }
1554
    all_buckets = apr_pcalloc(pconf, num_buckets *
1433
    all_buckets = apr_pcalloc(pconf, mz->mpm->num_buckets *
1555
                                     sizeof(motorz_child_bucket));
1434
                                     sizeof(motorz_child_bucket));
1556
    for (i = 0; i < num_buckets; i++) {
1435
    for (i = 0; i < mz->mpm->num_buckets; i++) {
1557
        if ((rv = ap_mpm_pod_open(pconf, &all_buckets[i].pod))) {
1436
        if ((rv = ap_mpm_pod_open(pconf, &all_buckets[i].pod))) {
1558
            ap_log_error(APLOG_MARK, APLOG_CRIT | level_flags, rv,
1437
            ap_log_error(APLOG_MARK, APLOG_CRIT | level_flags, rv,
1559
                         (startup ? NULL : s), APLOGNO(03277)
1438
                         (startup ? NULL : s), APLOGNO(03277)
Lines 1583-1590 static int motorz_pre_config(apr_pool_t *p, apr_po Link Here
1583
    const char *userdata_key = "mpm_motorz_module";
1462
    const char *userdata_key = "mpm_motorz_module";
1584
    motorz_core_t *mz;
1463
    motorz_core_t *mz;
1585
1464
1586
    mpm_state = AP_MPMQ_STARTING;
1587
1588
    debug = ap_exists_config_define("DEBUG");
1465
    debug = ap_exists_config_define("DEBUG");
1589
1466
1590
    if (debug) {
1467
    if (debug) {
Lines 1600-1615 static int motorz_pre_config(apr_pool_t *p, apr_po Link Here
1600
1477
1601
    ap_mutex_register(p, AP_ACCEPT_MUTEX_TYPE, NULL, APR_LOCK_DEFAULT, 0);
1478
    ap_mutex_register(p, AP_ACCEPT_MUTEX_TYPE, NULL, APR_LOCK_DEFAULT, 0);
1602
1479
1603
    /* sigh, want this only the second time around */
1604
    mz = g_motorz_core = ap_retained_data_get(userdata_key);
1480
    mz = g_motorz_core = ap_retained_data_get(userdata_key);
1605
    if (!g_motorz_core) {
1481
    if (!g_motorz_core) {
1606
        mz = g_motorz_core = ap_retained_data_create(userdata_key, sizeof(*g_motorz_core));
1482
        mz = g_motorz_core = ap_retained_data_create(userdata_key, sizeof(*g_motorz_core));
1483
        mz->mpm = ap_unixd_mpm_get_retained_data();
1607
        mz->max_daemons_limit = -1;
1484
        mz->max_daemons_limit = -1;
1608
        mz->timeout_ring = motorz_timer_ring;
1485
        mz->timeout_ring = motorz_timer_ring;
1609
        mz->pollset = motorz_pollset;
1486
        mz->pollset = motorz_pollset;
1610
    }
1487
    }
1611
    ++mz->module_loads;
1488
    if (mz->mpm->baton != mz) {
1612
    if (mz->module_loads == 2) {
1489
        mz->mpm->was_graceful = 0;
1490
        mz->mpm->baton = mz;
1491
    }
1492
    mz->mpm->mpm_state = AP_MPMQ_STARTING;
1493
    ++mz->mpm->module_loads;
1494
1495
    /* sigh, want this only the second time around */
1496
    if (mz->mpm->module_loads == 2) {
1613
        if (!one_process && !foreground) {
1497
        if (!one_process && !foreground) {
1614
            /* before we detach, setup crash handlers to log to errorlog */
1498
            /* before we detach, setup crash handlers to log to errorlog */
1615
            ap_fatal_signal_setup(ap_server_conf, pconf);
1499
            ap_fatal_signal_setup(ap_server_conf, pconf);
Lines 1647-1653 static int motorz_check_config(apr_pool_t *p, apr_ Link Here
1647
    motorz_core_t *mz = motorz_core_get();
1531
    motorz_core_t *mz = motorz_core_get();
1648
1532
1649
    /* the reverse of pre_config, we want this only the first time around */
1533
    /* the reverse of pre_config, we want this only the first time around */
1650
    if (mz->module_loads == 1) {
1534
    if (mz->mpm->module_loads == 1) {
1651
        startup = 1;
1535
        startup = 1;
1652
    }
1536
    }
1653
1537
(-)server/mpm/motorz/motorz.h (-3 / +2 lines)
Lines 115-124 Link Here
115
 */
115
 */
116
typedef struct motorz_core_t motorz_core_t;
116
typedef struct motorz_core_t motorz_core_t;
117
struct motorz_core_t {
117
struct motorz_core_t {
118
    ap_unixd_mpm_retained_data *mpm;
119
118
    int first_server_limit;
120
    int first_server_limit;
119
    int module_loads;
120
    ap_generation_t my_generation;
121
    int volatile is_graceful; /* set from signal handler */
122
    int maxclients_reported;
121
    int maxclients_reported;
123
    /*
122
    /*
124
     * The max child slot ever assigned, preserved across restarts.  Necessary
123
     * The max child slot ever assigned, preserved across restarts.  Necessary
(-)server/mpm/prefork/prefork.c (-186 / +67 lines)
Lines 94-100 static int ap_daemons_min_free=0; Link Here
94
static int ap_daemons_max_free=0;
94
static int ap_daemons_max_free=0;
95
static int ap_daemons_limit=0;      /* MaxRequestWorkers */
95
static int ap_daemons_limit=0;      /* MaxRequestWorkers */
96
static int server_limit = 0;
96
static int server_limit = 0;
97
static int mpm_state = AP_MPMQ_STARTING;
98
97
99
/* data retained by prefork across load/unload of the module
98
/* data retained by prefork across load/unload of the module
100
 * allocated on first call to pre-config hook; located on
99
 * allocated on first call to pre-config hook; located on
Lines 101-110 static int server_limit = 0; Link Here
101
 * subsequent calls to pre-config hook
100
 * subsequent calls to pre-config hook
102
 */
101
 */
103
typedef struct prefork_retained_data {
102
typedef struct prefork_retained_data {
103
    ap_unixd_mpm_retained_data *mpm;
104
104
    int first_server_limit;
105
    int first_server_limit;
105
    int module_loads;
106
    ap_generation_t my_generation;
107
    int volatile is_graceful; /* set from signal handler */
108
    int maxclients_reported;
106
    int maxclients_reported;
109
    /*
107
    /*
110
     * The max child slot ever assigned, preserved across restarts.  Necessary
108
     * The max child slot ever assigned, preserved across restarts.  Necessary
Lines 131-137 typedef struct prefork_child_bucket { Link Here
131
    ap_listen_rec *listeners;
129
    ap_listen_rec *listeners;
132
    apr_proc_mutex_t *mutex;
130
    apr_proc_mutex_t *mutex;
133
} prefork_child_bucket;
131
} prefork_child_bucket;
134
static int                   num_buckets; /* Number of listeners buckets */
135
static prefork_child_bucket *all_buckets, /* All listeners buckets */
132
static prefork_child_bucket *all_buckets, /* All listeners buckets */
136
                            *my_bucket;   /* Current child bucket */
133
                            *my_bucket;   /* Current child bucket */
137
134
Lines 215-221 static void prefork_note_child_started(int slot, p Link Here
215
    ap_scoreboard_image->parent[slot].pid = pid;
212
    ap_scoreboard_image->parent[slot].pid = pid;
216
    ap_run_child_status(ap_server_conf,
213
    ap_run_child_status(ap_server_conf,
217
                        ap_scoreboard_image->parent[slot].pid,
214
                        ap_scoreboard_image->parent[slot].pid,
218
                        retained->my_generation, slot, MPM_CHILD_STARTED);
215
                        retained->mpm->my_generation, slot, MPM_CHILD_STARTED);
219
}
216
}
220
217
221
/* a clean exit from a child with proper cleanup */
218
/* a clean exit from a child with proper cleanup */
Lines 222-228 static void prefork_note_child_started(int slot, p Link Here
222
static void clean_child_exit(int code) __attribute__ ((noreturn));
219
static void clean_child_exit(int code) __attribute__ ((noreturn));
223
static void clean_child_exit(int code)
220
static void clean_child_exit(int code)
224
{
221
{
225
    mpm_state = AP_MPMQ_STOPPING;
222
    retained->mpm->mpm_state = AP_MPMQ_STOPPING;
226
223
227
    apr_signal(SIGHUP, SIG_IGN);
224
    apr_signal(SIGHUP, SIG_IGN);
228
    apr_signal(SIGTERM, SIG_IGN);
225
    apr_signal(SIGTERM, SIG_IGN);
Lines 246-252 static apr_status_t accept_mutex_on(void) Link Here
246
    if (rv != APR_SUCCESS) {
243
    if (rv != APR_SUCCESS) {
247
        const char *msg = "couldn't grab the accept mutex";
244
        const char *msg = "couldn't grab the accept mutex";
248
245
249
        if (retained->my_generation !=
246
        if (retained->mpm->my_generation !=
250
            ap_scoreboard_image->global->running_generation) {
247
            ap_scoreboard_image->global->running_generation) {
251
            ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, ap_server_conf, APLOGNO(00143) "%s", msg);
248
            ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, ap_server_conf, APLOGNO(00143) "%s", msg);
252
            clean_child_exit(0);
249
            clean_child_exit(0);
Lines 265-271 static apr_status_t accept_mutex_off(void) Link Here
265
    if (rv != APR_SUCCESS) {
262
    if (rv != APR_SUCCESS) {
266
        const char *msg = "couldn't release the accept mutex";
263
        const char *msg = "couldn't release the accept mutex";
267
264
268
        if (retained->my_generation !=
265
        if (retained->mpm->my_generation !=
269
            ap_scoreboard_image->global->running_generation) {
266
            ap_scoreboard_image->global->running_generation) {
270
            ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, ap_server_conf, APLOGNO(00145) "%s", msg);
267
            ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, ap_server_conf, APLOGNO(00145) "%s", msg);
271
            /* don't exit here... we have a connection to
268
            /* don't exit here... we have a connection to
Lines 333-342 static int prefork_query(int query_code, int *resu Link Here
333
        *result = ap_daemons_limit;
330
        *result = ap_daemons_limit;
334
        break;
331
        break;
335
    case AP_MPMQ_MPM_STATE:
332
    case AP_MPMQ_MPM_STATE:
336
        *result = mpm_state;
333
        *result = retained->mpm->mpm_state;
337
        break;
334
        break;
338
    case AP_MPMQ_GENERATION:
335
    case AP_MPMQ_GENERATION:
339
        *result = retained->my_generation;
336
        *result = retained->mpm->my_generation;
340
        break;
337
        break;
341
    default:
338
    default:
342
        *rv = APR_ENOTIMPL;
339
        *rv = APR_ENOTIMPL;
Lines 359-372 static void just_die(int sig) Link Here
359
    clean_child_exit(0);
356
    clean_child_exit(0);
360
}
357
}
361
358
362
/* volatile because they're updated from a signal handler */
359
/* volatile because it's updated from a signal handler */
363
static int volatile shutdown_pending;
364
static int volatile restart_pending;
365
static int volatile die_now = 0;
360
static int volatile die_now = 0;
366
361
367
static void stop_listening(int sig)
362
static void stop_listening(int sig)
368
{
363
{
369
    mpm_state = AP_MPMQ_STOPPING;
364
    retained->mpm->mpm_state = AP_MPMQ_STOPPING;
370
    ap_close_listeners_ex(my_bucket->listeners);
365
    ap_close_listeners_ex(my_bucket->listeners);
371
366
372
    /* For a graceful stop, we want the child to exit when done */
367
    /* For a graceful stop, we want the child to exit when done */
Lines 373-488 static void stop_listening(int sig) Link Here
373
    die_now = 1;
368
    die_now = 1;
374
}
369
}
375
370
376
static void sig_term(int sig)
377
{
378
    if (shutdown_pending == 1) {
379
        /* Um, is this _probably_ not an error, if the user has
380
         * tried to do a shutdown twice quickly, so we won't
381
         * worry about reporting it.
382
         */
383
        return;
384
    }
385
    mpm_state = AP_MPMQ_STOPPING;
386
    shutdown_pending = 1;
387
    retained->is_graceful = (sig == AP_SIG_GRACEFUL_STOP);
388
}
389
390
/* restart() is the signal handler for SIGHUP and AP_SIG_GRACEFUL
391
 * in the parent process, unless running in ONE_PROCESS mode
392
 */
393
static void restart(int sig)
394
{
395
    if (restart_pending == 1) {
396
        /* Probably not an error - don't bother reporting it */
397
        return;
398
    }
399
    mpm_state = AP_MPMQ_STOPPING;
400
    restart_pending = 1;
401
    retained->is_graceful = (sig == AP_SIG_GRACEFUL);
402
}
403
404
static void set_signals(void)
405
{
406
#ifndef NO_USE_SIGACTION
407
    struct sigaction sa;
408
#endif
409
410
    if (!one_process) {
411
        ap_fatal_signal_setup(ap_server_conf, pconf);
412
    }
413
414
#ifndef NO_USE_SIGACTION
415
    sigemptyset(&sa.sa_mask);
416
    sa.sa_flags = 0;
417
418
    sa.sa_handler = sig_term;
419
    if (sigaction(SIGTERM, &sa, NULL) < 0)
420
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00147) "sigaction(SIGTERM)");
421
#ifdef AP_SIG_GRACEFUL_STOP
422
    if (sigaction(AP_SIG_GRACEFUL_STOP, &sa, NULL) < 0)
423
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00148)
424
                     "sigaction(" AP_SIG_GRACEFUL_STOP_STRING ")");
425
#endif
426
#ifdef SIGINT
427
    if (sigaction(SIGINT, &sa, NULL) < 0)
428
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00149) "sigaction(SIGINT)");
429
#endif
430
#ifdef SIGXCPU
431
    sa.sa_handler = SIG_DFL;
432
    if (sigaction(SIGXCPU, &sa, NULL) < 0)
433
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00150) "sigaction(SIGXCPU)");
434
#endif
435
#ifdef SIGXFSZ
436
    /* For systems following the LFS standard, ignoring SIGXFSZ allows
437
     * a write() beyond the 2GB limit to fail gracefully with E2BIG
438
     * rather than terminate the process. */
439
    sa.sa_handler = SIG_IGN;
440
    if (sigaction(SIGXFSZ, &sa, NULL) < 0)
441
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00151) "sigaction(SIGXFSZ)");
442
#endif
443
#ifdef SIGPIPE
444
    sa.sa_handler = SIG_IGN;
445
    if (sigaction(SIGPIPE, &sa, NULL) < 0)
446
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00152) "sigaction(SIGPIPE)");
447
#endif
448
449
    /* we want to ignore HUPs and AP_SIG_GRACEFUL while we're busy
450
     * processing one
451
     */
452
    sigaddset(&sa.sa_mask, SIGHUP);
453
    sigaddset(&sa.sa_mask, AP_SIG_GRACEFUL);
454
    sa.sa_handler = restart;
455
    if (sigaction(SIGHUP, &sa, NULL) < 0)
456
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00153) "sigaction(SIGHUP)");
457
    if (sigaction(AP_SIG_GRACEFUL, &sa, NULL) < 0)
458
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00154) "sigaction(" AP_SIG_GRACEFUL_STRING ")");
459
#else
460
    if (!one_process) {
461
#ifdef SIGXCPU
462
        apr_signal(SIGXCPU, SIG_DFL);
463
#endif /* SIGXCPU */
464
#ifdef SIGXFSZ
465
        apr_signal(SIGXFSZ, SIG_IGN);
466
#endif /* SIGXFSZ */
467
    }
468
469
    apr_signal(SIGTERM, sig_term);
470
#ifdef SIGHUP
471
    apr_signal(SIGHUP, restart);
472
#endif /* SIGHUP */
473
#ifdef AP_SIG_GRACEFUL
474
    apr_signal(AP_SIG_GRACEFUL, restart);
475
#endif /* AP_SIG_GRACEFUL */
476
#ifdef AP_SIG_GRACEFUL_STOP
477
    apr_signal(AP_SIG_GRACEFUL_STOP, sig_term);
478
#endif /* AP_SIG_GRACEFUL */
479
#ifdef SIGPIPE
480
    apr_signal(SIGPIPE, SIG_IGN);
481
#endif /* SIGPIPE */
482
483
#endif
484
}
485
486
/*****************************************************************
371
/*****************************************************************
487
 * Child process main loop.
372
 * Child process main loop.
488
 * The following vars are static to avoid getting clobbered by longjmp();
373
 * The following vars are static to avoid getting clobbered by longjmp();
Lines 509-517 static void child_main(int child_num_arg, int chil Link Here
509
    int last_poll_idx = 0;
394
    int last_poll_idx = 0;
510
    const char *lockfile;
395
    const char *lockfile;
511
396
512
    mpm_state = AP_MPMQ_STARTING; /* for benefit of any hooks that run as this
397
    /* for benefit of any hooks that run as this child initializes */
513
                                   * child initializes
398
    retained->mpm->mpm_state = AP_MPMQ_STARTING;
514
                                   */
515
399
516
    my_child_num = child_num_arg;
400
    my_child_num = child_num_arg;
517
    ap_my_pid = getpid();
401
    ap_my_pid = getpid();
Lines 537-543 static void child_main(int child_num_arg, int chil Link Here
537
    apr_pool_tag(ptrans, "transaction");
421
    apr_pool_tag(ptrans, "transaction");
538
422
539
    /* close unused listeners and pods */
423
    /* close unused listeners and pods */
540
    for (i = 0; i < num_buckets; i++) {
424
    for (i = 0; i < retained->mpm->num_buckets; i++) {
541
        if (i != child_bucket) {
425
        if (i != child_bucket) {
542
            ap_close_listeners_ex(all_buckets[i].listeners);
426
            ap_close_listeners_ex(all_buckets[i].listeners);
543
            ap_mpm_pod_close(all_buckets[i].pod);
427
            ap_mpm_pod_close(all_buckets[i].pod);
Lines 603-609 static void child_main(int child_num_arg, int chil Link Here
603
        lr->accept_func = ap_unixd_accept;
487
        lr->accept_func = ap_unixd_accept;
604
    }
488
    }
605
489
606
    mpm_state = AP_MPMQ_RUNNING;
490
    retained->mpm->mpm_state = AP_MPMQ_RUNNING;
607
491
608
    bucket_alloc = apr_bucket_alloc_create(pchild);
492
    bucket_alloc = apr_bucket_alloc_create(pchild);
609
493
Lines 610-616 static void child_main(int child_num_arg, int chil Link Here
610
    /* die_now is set when AP_SIG_GRACEFUL is received in the child;
494
    /* die_now is set when AP_SIG_GRACEFUL is received in the child;
611
     * shutdown_pending is set when SIGTERM is received when running
495
     * shutdown_pending is set when SIGTERM is received when running
612
     * in single process mode.  */
496
     * in single process mode.  */
613
    while (!die_now && !shutdown_pending) {
497
    while (!die_now && !retained->mpm->shutdown_pending) {
614
        conn_rec *current_conn;
498
        conn_rec *current_conn;
615
        void *csd;
499
        void *csd;
616
500
Lines 648-654 static void child_main(int child_num_arg, int chil Link Here
648
                 * poll if already signalled
532
                 * poll if already signalled
649
                 */
533
                 */
650
                if (die_now         /* in graceful stop/restart */
534
                if (die_now         /* in graceful stop/restart */
651
                    || (one_process && shutdown_pending)) {
535
                    || (one_process && retained->mpm->shutdown_pending)) {
652
                    SAFE_ACCEPT(accept_mutex_off());
536
                    SAFE_ACCEPT(accept_mutex_off());
653
                    clean_child_exit(0);
537
                    clean_child_exit(0);
654
                }
538
                }
Lines 737-743 static void child_main(int child_num_arg, int chil Link Here
737
        if (ap_mpm_pod_check(my_bucket->pod) == APR_SUCCESS) { /* selected as idle? */
621
        if (ap_mpm_pod_check(my_bucket->pod) == APR_SUCCESS) { /* selected as idle? */
738
            die_now = 1;
622
            die_now = 1;
739
        }
623
        }
740
        else if (retained->my_generation !=
624
        else if (retained->mpm->my_generation !=
741
                 ap_scoreboard_image->global->running_generation) { /* restart? */
625
                 ap_scoreboard_image->global->running_generation) { /* restart? */
742
            /* yeah, this could be non-graceful restart, in which case the
626
            /* yeah, this could be non-graceful restart, in which case the
743
             * parent will kill us soon enough, but why bother checking?
627
             * parent will kill us soon enough, but why bother checking?
Lines 761-773 static int make_child(server_rec *s, int slot, int Link Here
761
    if (one_process) {
645
    if (one_process) {
762
        my_bucket = &all_buckets[0];
646
        my_bucket = &all_buckets[0];
763
647
764
        apr_signal(SIGHUP, sig_term);
765
        /* Don't catch AP_SIG_GRACEFUL in ONE_PROCESS mode :) */
766
        apr_signal(SIGINT, sig_term);
767
#ifdef SIGQUIT
768
        apr_signal(SIGQUIT, SIG_DFL);
769
#endif
770
        apr_signal(SIGTERM, sig_term);
771
        prefork_note_child_started(slot, getpid());
648
        prefork_note_child_started(slot, getpid());
772
        child_main(slot, 0);
649
        child_main(slot, 0);
773
        /* NOTREACHED */
650
        /* NOTREACHED */
Lines 852-858 static void startup_children(int number_to_start) Link Here
852
        if (ap_scoreboard_image->servers[i][0].status != SERVER_DEAD) {
729
        if (ap_scoreboard_image->servers[i][0].status != SERVER_DEAD) {
853
            continue;
730
            continue;
854
        }
731
        }
855
        if (make_child(ap_server_conf, i, i % num_buckets) < 0) {
732
        if (make_child(ap_server_conf, i, i % retained->mpm->num_buckets) < 0) {
856
            break;
733
            break;
857
        }
734
        }
858
        --number_to_start;
735
        --number_to_start;
Lines 913-919 static void perform_idle_server_maintenance(apr_po Link Here
913
         * shut down gracefully, in case it happened to pick up a request
790
         * shut down gracefully, in case it happened to pick up a request
914
         * while we were counting
791
         * while we were counting
915
         */
792
         */
916
        bucket_kill_child_record = (bucket_kill_child_record + 1) % num_buckets;
793
        bucket_kill_child_record = (bucket_kill_child_record + 1) % retained->mpm->num_buckets;
917
        ap_mpm_pod_signal(all_buckets[bucket_kill_child_record].pod);
794
        ap_mpm_pod_signal(all_buckets[bucket_kill_child_record].pod);
918
        retained->idle_spawn_rate = 1;
795
        retained->idle_spawn_rate = 1;
919
    }
796
    }
Lines 940-946 static void perform_idle_server_maintenance(apr_po Link Here
940
            }
817
            }
941
            for (i = 0; i < free_length; ++i) {
818
            for (i = 0; i < free_length; ++i) {
942
                bucket_make_child_record++;
819
                bucket_make_child_record++;
943
                bucket_make_child_record %= num_buckets;
820
                bucket_make_child_record %= retained->mpm->num_buckets;
944
                make_child(ap_server_conf, free_slots[i],
821
                make_child(ap_server_conf, free_slots[i],
945
                           bucket_make_child_record);
822
                           bucket_make_child_record);
946
            }
823
            }
Lines 972-990 static int prefork_run(apr_pool_t *_pconf, apr_poo Link Here
972
849
973
    ap_log_pid(pconf, ap_pid_fname);
850
    ap_log_pid(pconf, ap_pid_fname);
974
851
975
    if (!retained->is_graceful) {
852
    if (!retained->mpm->was_graceful) {
976
        if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) {
853
        if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) {
977
            mpm_state = AP_MPMQ_STOPPING;
854
            retained->mpm->mpm_state = AP_MPMQ_STOPPING;
978
            return !OK;
855
            return !OK;
979
        }
856
        }
980
        /* fix the generation number in the global score; we just got a new,
857
        /* fix the generation number in the global score; we just got a new,
981
         * cleared scoreboard
858
         * cleared scoreboard
982
         */
859
         */
983
        ap_scoreboard_image->global->running_generation = retained->my_generation;
860
        ap_scoreboard_image->global->running_generation = retained->mpm->my_generation;
984
    }
861
    }
985
862
986
    restart_pending = shutdown_pending = 0;
863
    ap_unixd_mpm_set_signals(pconf, one_process);
987
    set_signals();
988
864
989
    if (one_process) {
865
    if (one_process) {
990
        AP_MONCONTROL(1);
866
        AP_MONCONTROL(1);
Lines 997-1010 static int prefork_run(apr_pool_t *_pconf, apr_poo Link Here
997
    /* Don't thrash since num_buckets depends on the
873
    /* Don't thrash since num_buckets depends on the
998
     * system and the number of online CPU cores...
874
     * system and the number of online CPU cores...
999
     */
875
     */
1000
    if (ap_daemons_limit < num_buckets)
876
    if (ap_daemons_limit < retained->mpm->num_buckets)
1001
        ap_daemons_limit = num_buckets;
877
        ap_daemons_limit = retained->mpm->num_buckets;
1002
    if (ap_daemons_to_start < num_buckets)
878
    if (ap_daemons_to_start < retained->mpm->num_buckets)
1003
        ap_daemons_to_start = num_buckets;
879
        ap_daemons_to_start = retained->mpm->num_buckets;
1004
    if (ap_daemons_min_free < num_buckets)
880
    if (ap_daemons_min_free < retained->mpm->num_buckets)
1005
        ap_daemons_min_free = num_buckets;
881
        ap_daemons_min_free = retained->mpm->num_buckets;
1006
    if (ap_daemons_max_free < ap_daemons_min_free + num_buckets)
882
    if (ap_daemons_max_free < ap_daemons_min_free + retained->mpm->num_buckets)
1007
        ap_daemons_max_free = ap_daemons_min_free + num_buckets;
883
        ap_daemons_max_free = ap_daemons_min_free + retained->mpm->num_buckets;
1008
884
1009
    /* If we're doing a graceful_restart then we're going to see a lot
885
    /* If we're doing a graceful_restart then we're going to see a lot
1010
     * of children exiting immediately when we get into the main loop
886
     * of children exiting immediately when we get into the main loop
Lines 1018-1024 static int prefork_run(apr_pool_t *_pconf, apr_poo Link Here
1018
    if (remaining_children_to_start > ap_daemons_limit) {
894
    if (remaining_children_to_start > ap_daemons_limit) {
1019
        remaining_children_to_start = ap_daemons_limit;
895
        remaining_children_to_start = ap_daemons_limit;
1020
    }
896
    }
1021
    if (!retained->is_graceful) {
897
    if (!retained->mpm->was_graceful) {
1022
        startup_children(remaining_children_to_start);
898
        startup_children(remaining_children_to_start);
1023
        remaining_children_to_start = 0;
899
        remaining_children_to_start = 0;
1024
    }
900
    }
Lines 1043-1051 static int prefork_run(apr_pool_t *_pconf, apr_poo Link Here
1043
                    : "none",
919
                    : "none",
1044
                apr_proc_mutex_defname());
920
                apr_proc_mutex_defname());
1045
921
1046
    mpm_state = AP_MPMQ_RUNNING;
922
    retained->mpm->mpm_state = AP_MPMQ_RUNNING;
1047
923
1048
    while (!restart_pending && !shutdown_pending) {
924
    while (!retained->mpm->restart_pending && !retained->mpm->shutdown_pending) {
1049
        int child_slot;
925
        int child_slot;
1050
        apr_exit_why_e exitwhy;
926
        apr_exit_why_e exitwhy;
1051
        int status, processed_status;
927
        int status, processed_status;
Lines 1069-1076 static int prefork_run(apr_pool_t *_pconf, apr_poo Link Here
1069
                 */
945
                 */
1070
                if (child_slot < 0
946
                if (child_slot < 0
1071
                    || ap_get_scoreboard_process(child_slot)->generation
947
                    || ap_get_scoreboard_process(child_slot)->generation
1072
                       == retained->my_generation) {
948
                       == retained->mpm->my_generation) {
1073
                    mpm_state = AP_MPMQ_STOPPING;
949
                    retained->mpm->mpm_state = AP_MPMQ_STOPPING;
1074
                    return !OK;
950
                    return !OK;
1075
                }
951
                }
1076
                else {
952
                else {
Lines 1107-1113 static int prefork_run(apr_pool_t *_pconf, apr_poo Link Here
1107
                /* handled */
983
                /* handled */
1108
#endif
984
#endif
1109
            }
985
            }
1110
            else if (retained->is_graceful) {
986
            else if (retained->mpm->was_graceful) {
1111
                /* Great, we've probably just lost a slot in the
987
                /* Great, we've probably just lost a slot in the
1112
                 * scoreboard.  Somehow we don't know about this
988
                 * scoreboard.  Somehow we don't know about this
1113
                 * child.
989
                 * child.
Lines 1140-1148 static int prefork_run(apr_pool_t *_pconf, apr_poo Link Here
1140
        perform_idle_server_maintenance(pconf);
1016
        perform_idle_server_maintenance(pconf);
1141
    }
1017
    }
1142
1018
1143
    mpm_state = AP_MPMQ_STOPPING;
1019
    retained->mpm->mpm_state = AP_MPMQ_STOPPING;
1144
1020
1145
    if (shutdown_pending && !retained->is_graceful) {
1021
    if (retained->mpm->shutdown_pending && retained->mpm->is_ungraceful) {
1146
        /* Time to shut down:
1022
        /* Time to shut down:
1147
         * Kill child processes, tell them to call child_exit, etc...
1023
         * Kill child processes, tell them to call child_exit, etc...
1148
         */
1024
         */
Lines 1158-1164 static int prefork_run(apr_pool_t *_pconf, apr_poo Link Here
1158
                    "caught SIGTERM, shutting down");
1034
                    "caught SIGTERM, shutting down");
1159
1035
1160
        return DONE;
1036
        return DONE;
1161
    } else if (shutdown_pending) {
1037
    } else if (retained->mpm->shutdown_pending) {
1162
        /* Time to perform a graceful shut down:
1038
        /* Time to perform a graceful shut down:
1163
         * Reap the inactive children, and ask the active ones
1039
         * Reap the inactive children, and ask the active ones
1164
         * to close their listeners, then wait until they are
1040
         * to close their listeners, then wait until they are
Lines 1171-1177 static int prefork_run(apr_pool_t *_pconf, apr_poo Link Here
1171
        ap_close_listeners();
1047
        ap_close_listeners();
1172
1048
1173
        /* kill off the idle ones */
1049
        /* kill off the idle ones */
1174
        for (i = 0; i < num_buckets; i++) {
1050
        for (i = 0; i < retained->mpm->num_buckets; i++) {
1175
            ap_mpm_pod_killpg(all_buckets[i].pod, retained->max_daemons_limit);
1051
            ap_mpm_pod_killpg(all_buckets[i].pod, retained->max_daemons_limit);
1176
        }
1052
        }
1177
1053
Lines 1199-1205 static int prefork_run(apr_pool_t *_pconf, apr_poo Link Here
1199
        }
1075
        }
1200
1076
1201
        /* Don't really exit until each child has finished */
1077
        /* Don't really exit until each child has finished */
1202
        shutdown_pending = 0;
1078
        retained->mpm->shutdown_pending = 0;
1203
        do {
1079
        do {
1204
            /* Pause for a second */
1080
            /* Pause for a second */
1205
            sleep(1);
1081
            sleep(1);
Lines 1215-1221 static int prefork_run(apr_pool_t *_pconf, apr_poo Link Here
1215
                    break;
1091
                    break;
1216
                }
1092
                }
1217
            }
1093
            }
1218
        } while (!shutdown_pending && active_children &&
1094
        } while (!retained->mpm->shutdown_pending && active_children &&
1219
                 (!ap_graceful_shutdown_timeout || apr_time_now() < cutoff));
1095
                 (!ap_graceful_shutdown_timeout || apr_time_now() < cutoff));
1220
1096
1221
        /* We might be here because we received SIGTERM, either
1097
        /* We might be here because we received SIGTERM, either
Lines 1239-1253 static int prefork_run(apr_pool_t *_pconf, apr_poo Link Here
1239
    /* XXX: we really need to make sure this new generation number isn't in
1115
    /* XXX: we really need to make sure this new generation number isn't in
1240
     * use by any of the children.
1116
     * use by any of the children.
1241
     */
1117
     */
1242
    ++retained->my_generation;
1118
    ++retained->mpm->my_generation;
1243
    ap_scoreboard_image->global->running_generation = retained->my_generation;
1119
    ap_scoreboard_image->global->running_generation = retained->mpm->my_generation;
1244
1120
1245
    if (retained->is_graceful) {
1121
    if (!retained->mpm->is_ungraceful) {
1246
        ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00171)
1122
        ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00171)
1247
                    "Graceful restart requested, doing restart");
1123
                    "Graceful restart requested, doing restart");
1248
1124
1249
        /* kill off the idle ones */
1125
        /* kill off the idle ones */
1250
        for (i = 0; i < num_buckets; i++) {
1126
        for (i = 0; i < retained->mpm->num_buckets; i++) {
1251
            ap_mpm_pod_killpg(all_buckets[i].pod, retained->max_daemons_limit);
1127
            ap_mpm_pod_killpg(all_buckets[i].pod, retained->max_daemons_limit);
1252
        }
1128
        }
1253
1129
Lines 1299-1305 static int prefork_open_logs(apr_pool_t *p, apr_po Link Here
1299
    pconf = p;
1175
    pconf = p;
1300
1176
1301
    /* the reverse of pre_config, we want this only the first time around */
1177
    /* the reverse of pre_config, we want this only the first time around */
1302
    if (retained->module_loads == 1) {
1178
    if (retained->mpm->module_loads == 1) {
1303
        startup = 1;
1179
        startup = 1;
1304
        level_flags |= APLOG_STARTUP;
1180
        level_flags |= APLOG_STARTUP;
1305
    }
1181
    }
Lines 1312-1333 static int prefork_open_logs(apr_pool_t *p, apr_po Link Here
1312
    }
1188
    }
1313
1189
1314
    if (one_process) {
1190
    if (one_process) {
1315
        num_buckets = 1;
1191
        retained->mpm->num_buckets = 1;
1316
    }
1192
    }
1317
    else if (!retained->is_graceful) { /* Preserve the number of buckets
1193
    else if (!retained->mpm->was_graceful) {
1318
                                          on graceful restarts. */
1194
        /* Preserve the number of buckets on graceful restarts. */
1319
        num_buckets = 0;
1195
        retained->mpm->num_buckets = 0;
1320
    }
1196
    }
1321
    if ((rv = ap_duplicate_listeners(pconf, ap_server_conf,
1197
    if ((rv = ap_duplicate_listeners(pconf, ap_server_conf,
1322
                                     &listen_buckets, &num_buckets))) {
1198
                                     &listen_buckets, &retained->mpm->num_buckets))) {
1323
        ap_log_error(APLOG_MARK, APLOG_CRIT | level_flags, rv,
1199
        ap_log_error(APLOG_MARK, APLOG_CRIT | level_flags, rv,
1324
                     (startup ? NULL : s), APLOGNO(03280)
1200
                     (startup ? NULL : s), APLOGNO(03280)
1325
                     "could not duplicate listeners");
1201
                     "could not duplicate listeners");
1326
        return !OK;
1202
        return !OK;
1327
    }
1203
    }
1328
    all_buckets = apr_pcalloc(pconf, num_buckets *
1204
    all_buckets = apr_pcalloc(pconf, retained->mpm->num_buckets *
1329
                                     sizeof(prefork_child_bucket));
1205
                                     sizeof(prefork_child_bucket));
1330
    for (i = 0; i < num_buckets; i++) {
1206
    for (i = 0; i < retained->mpm->num_buckets; i++) {
1331
        if ((rv = ap_mpm_pod_open(pconf, &all_buckets[i].pod))) {
1207
        if ((rv = ap_mpm_pod_open(pconf, &all_buckets[i].pod))) {
1332
            ap_log_error(APLOG_MARK, APLOG_CRIT | level_flags, rv,
1208
            ap_log_error(APLOG_MARK, APLOG_CRIT | level_flags, rv,
1333
                         (startup ? NULL : s), APLOGNO(03281)
1209
                         (startup ? NULL : s), APLOGNO(03281)
Lines 1356-1363 static int prefork_pre_config(apr_pool_t *p, apr_p Link Here
1356
    apr_status_t rv;
1232
    apr_status_t rv;
1357
    const char *userdata_key = "mpm_prefork_module";
1233
    const char *userdata_key = "mpm_prefork_module";
1358
1234
1359
    mpm_state = AP_MPMQ_STARTING;
1360
1361
    debug = ap_exists_config_define("DEBUG");
1235
    debug = ap_exists_config_define("DEBUG");
1362
1236
1363
    if (debug) {
1237
    if (debug) {
Lines 1373-1387 static int prefork_pre_config(apr_pool_t *p, apr_p Link Here
1373
1247
1374
    ap_mutex_register(p, AP_ACCEPT_MUTEX_TYPE, NULL, APR_LOCK_DEFAULT, 0);
1248
    ap_mutex_register(p, AP_ACCEPT_MUTEX_TYPE, NULL, APR_LOCK_DEFAULT, 0);
1375
1249
1376
    /* sigh, want this only the second time around */
1377
    retained = ap_retained_data_get(userdata_key);
1250
    retained = ap_retained_data_get(userdata_key);
1378
    if (!retained) {
1251
    if (!retained) {
1379
        retained = ap_retained_data_create(userdata_key, sizeof(*retained));
1252
        retained = ap_retained_data_create(userdata_key, sizeof(*retained));
1253
        retained->mpm = ap_unixd_mpm_get_retained_data();
1380
        retained->max_daemons_limit = -1;
1254
        retained->max_daemons_limit = -1;
1381
        retained->idle_spawn_rate = 1;
1255
        retained->idle_spawn_rate = 1;
1382
    }
1256
    }
1383
    ++retained->module_loads;
1257
    if (retained->mpm->baton != retained) {
1384
    if (retained->module_loads == 2) {
1258
        retained->mpm->was_graceful = 0;
1259
        retained->mpm->baton = retained;
1260
    }
1261
    retained->mpm->mpm_state = AP_MPMQ_STARTING;
1262
    ++retained->mpm->module_loads;
1263
1264
    /* sigh, want this only the second time around */
1265
    if (retained->mpm->module_loads == 2) {
1385
        if (!one_process && !foreground) {
1266
        if (!one_process && !foreground) {
1386
            /* before we detach, setup crash handlers to log to errorlog */
1267
            /* before we detach, setup crash handlers to log to errorlog */
1387
            ap_fatal_signal_setup(ap_server_conf, pconf);
1268
            ap_fatal_signal_setup(ap_server_conf, pconf);
Lines 1414-1420 static int prefork_check_config(apr_pool_t *p, apr Link Here
1414
    int startup = 0;
1295
    int startup = 0;
1415
1296
1416
    /* the reverse of pre_config, we want this only the first time around */
1297
    /* the reverse of pre_config, we want this only the first time around */
1417
    if (retained->module_loads == 1) {
1298
    if (retained->mpm->module_loads == 1) {
1418
        startup = 1;
1299
        startup = 1;
1419
    }
1300
    }
1420
1301
(-)server/mpm/worker/worker.c (-209 / +57 lines)
Lines 135-141 static int num_listensocks = 0; Link Here
135
static int resource_shortage = 0;
135
static int resource_shortage = 0;
136
static fd_queue_t *worker_queue;
136
static fd_queue_t *worker_queue;
137
static fd_queue_info_t *worker_queue_info;
137
static fd_queue_info_t *worker_queue_info;
138
static int mpm_state = AP_MPMQ_STARTING;
139
138
140
/* data retained by worker across load/unload of the module
139
/* data retained by worker across load/unload of the module
141
 * allocated on first call to pre-config hook; located on
140
 * allocated on first call to pre-config hook; located on
Lines 142-153 static fd_queue_info_t *worker_queue_info; Link Here
142
 * subsequent calls to pre-config hook
141
 * subsequent calls to pre-config hook
143
 */
142
 */
144
typedef struct worker_retained_data {
143
typedef struct worker_retained_data {
144
    ap_unixd_mpm_retained_data *mpm;
145
145
    int first_server_limit;
146
    int first_server_limit;
146
    int first_thread_limit;
147
    int first_thread_limit;
147
    int module_loads;
148
    int sick_child_detected;
148
    int sick_child_detected;
149
    ap_generation_t my_generation;
150
    int volatile is_graceful; /* set from signal handler */
151
    int maxclients_reported;
149
    int maxclients_reported;
152
    int near_maxclients_reported;
150
    int near_maxclients_reported;
153
    /*
151
    /*
Lines 168-179 typedef struct worker_retained_data { Link Here
168
#define MAX_SPAWN_RATE        (32)
166
#define MAX_SPAWN_RATE        (32)
169
#endif
167
#endif
170
    int hold_off_on_exponential_spawning;
168
    int hold_off_on_exponential_spawning;
171
    /*
172
     * Current number of listeners buckets and maximum reached across
173
     * restarts (to size retained data according to dynamic num_buckets,
174
     * eg. idle_spawn_rate).
175
     */
176
    int num_buckets, max_buckets;
177
} worker_retained_data;
169
} worker_retained_data;
178
static worker_retained_data *retained;
170
static worker_retained_data *retained;
179
171
Lines 314-320 static void signal_threads(int mode) Link Here
314
        return;
306
        return;
315
    }
307
    }
316
    terminate_mode = mode;
308
    terminate_mode = mode;
317
    mpm_state = AP_MPMQ_STOPPING;
309
    retained->mpm->mpm_state = AP_MPMQ_STOPPING;
318
310
319
    /* in case we weren't called from the listener thread, wake up the
311
    /* in case we weren't called from the listener thread, wake up the
320
     * listener thread
312
     * listener thread
Lines 373-382 static int worker_query(int query_code, int *resul Link Here
373
            *result = ap_daemons_limit;
365
            *result = ap_daemons_limit;
374
            break;
366
            break;
375
        case AP_MPMQ_MPM_STATE:
367
        case AP_MPMQ_MPM_STATE:
376
            *result = mpm_state;
368
            *result = retained->mpm->mpm_state;
377
            break;
369
            break;
378
        case AP_MPMQ_GENERATION:
370
        case AP_MPMQ_GENERATION:
379
            *result = retained->my_generation;
371
            *result = retained->mpm->my_generation;
380
            break;
372
            break;
381
        default:
373
        default:
382
            *rv = APR_ENOTIMPL;
374
            *rv = APR_ENOTIMPL;
Lines 404-410 static void worker_note_child_started(int slot, pi Link Here
404
    ap_scoreboard_image->parent[slot].pid = pid;
396
    ap_scoreboard_image->parent[slot].pid = pid;
405
    ap_run_child_status(ap_server_conf,
397
    ap_run_child_status(ap_server_conf,
406
                        ap_scoreboard_image->parent[slot].pid,
398
                        ap_scoreboard_image->parent[slot].pid,
407
                        retained->my_generation, slot, MPM_CHILD_STARTED);
399
                        retained->mpm->my_generation, slot, MPM_CHILD_STARTED);
408
}
400
}
409
401
410
static void worker_note_child_lost_slot(int slot, pid_t newpid)
402
static void worker_note_child_lost_slot(int slot, pid_t newpid)
Lines 437-443 static const char *worker_get_name(void) Link Here
437
static void clean_child_exit(int code) __attribute__ ((noreturn));
429
static void clean_child_exit(int code) __attribute__ ((noreturn));
438
static void clean_child_exit(int code)
430
static void clean_child_exit(int code)
439
{
431
{
440
    mpm_state = AP_MPMQ_STOPPING;
432
    retained->mpm->mpm_state = AP_MPMQ_STOPPING;
441
    if (pchild) {
433
    if (pchild) {
442
        apr_pool_destroy(pchild);
434
        apr_pool_destroy(pchild);
443
    }
435
    }
Lines 460-612 static void just_die(int sig) Link Here
460
452
461
static int child_fatal;
453
static int child_fatal;
462
454
463
/* volatile because they're updated from a signal handler */
464
static int volatile shutdown_pending;
465
static int volatile restart_pending;
466
467
/*
468
 * ap_start_shutdown() and ap_start_restart(), below, are a first stab at
469
 * functions to initiate shutdown or restart without relying on signals.
470
 * Previously this was initiated in sig_term() and restart() signal handlers,
471
 * but we want to be able to start a shutdown/restart from other sources --
472
 * e.g. on Win32, from the service manager. Now the service manager can
473
 * call ap_start_shutdown() or ap_start_restart() as appropriate.  Note that
474
 * these functions can also be called by the child processes, since global
475
 * variables are no longer used to pass on the required action to the parent.
476
 *
477
 * These should only be called from the parent process itself, since the
478
 * parent process will use the shutdown_pending and restart_pending variables
479
 * to determine whether to shutdown or restart. The child process should
480
 * call signal_parent() directly to tell the parent to die -- this will
481
 * cause neither of those variable to be set, which the parent will
482
 * assume means something serious is wrong (which it will be, for the
483
 * child to force an exit) and so do an exit anyway.
484
 */
485
486
static void ap_start_shutdown(int graceful)
487
{
488
    mpm_state = AP_MPMQ_STOPPING;
489
    if (shutdown_pending == 1) {
490
        /* Um, is this _probably_ not an error, if the user has
491
         * tried to do a shutdown twice quickly, so we won't
492
         * worry about reporting it.
493
         */
494
        return;
495
    }
496
    shutdown_pending = 1;
497
    retained->is_graceful = graceful;
498
}
499
500
/* do a graceful restart if graceful == 1 */
501
static void ap_start_restart(int graceful)
502
{
503
    mpm_state = AP_MPMQ_STOPPING;
504
    if (restart_pending == 1) {
505
        /* Probably not an error - don't bother reporting it */
506
        return;
507
    }
508
    restart_pending = 1;
509
    retained->is_graceful = graceful;
510
}
511
512
static void sig_term(int sig)
513
{
514
    ap_start_shutdown(sig == AP_SIG_GRACEFUL_STOP);
515
}
516
517
static void restart(int sig)
518
{
519
    ap_start_restart(sig == AP_SIG_GRACEFUL);
520
}
521
522
static void set_signals(void)
523
{
524
#ifndef NO_USE_SIGACTION
525
    struct sigaction sa;
526
#endif
527
528
    if (!one_process) {
529
        ap_fatal_signal_setup(ap_server_conf, pconf);
530
    }
531
532
#ifndef NO_USE_SIGACTION
533
    sigemptyset(&sa.sa_mask);
534
    sa.sa_flags = 0;
535
536
    sa.sa_handler = sig_term;
537
    if (sigaction(SIGTERM, &sa, NULL) < 0)
538
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00264)
539
                     "sigaction(SIGTERM)");
540
#ifdef AP_SIG_GRACEFUL_STOP
541
    if (sigaction(AP_SIG_GRACEFUL_STOP, &sa, NULL) < 0)
542
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00265)
543
                     "sigaction(" AP_SIG_GRACEFUL_STOP_STRING ")");
544
#endif
545
#ifdef SIGINT
546
    if (sigaction(SIGINT, &sa, NULL) < 0)
547
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00266)
548
                     "sigaction(SIGINT)");
549
#endif
550
#ifdef SIGXCPU
551
    sa.sa_handler = SIG_DFL;
552
    if (sigaction(SIGXCPU, &sa, NULL) < 0)
553
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00267)
554
                     "sigaction(SIGXCPU)");
555
#endif
556
#ifdef SIGXFSZ
557
    /* For systems following the LFS standard, ignoring SIGXFSZ allows
558
     * a write() beyond the 2GB limit to fail gracefully with E2BIG
559
     * rather than terminate the process. */
560
    sa.sa_handler = SIG_IGN;
561
    if (sigaction(SIGXFSZ, &sa, NULL) < 0)
562
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00268)
563
                     "sigaction(SIGXFSZ)");
564
#endif
565
#ifdef SIGPIPE
566
    sa.sa_handler = SIG_IGN;
567
    if (sigaction(SIGPIPE, &sa, NULL) < 0)
568
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00269)
569
                     "sigaction(SIGPIPE)");
570
#endif
571
572
    /* we want to ignore HUPs and AP_SIG_GRACEFUL while we're busy
573
     * processing one */
574
    sigaddset(&sa.sa_mask, SIGHUP);
575
    sigaddset(&sa.sa_mask, AP_SIG_GRACEFUL);
576
    sa.sa_handler = restart;
577
    if (sigaction(SIGHUP, &sa, NULL) < 0)
578
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00270)
579
                     "sigaction(SIGHUP)");
580
    if (sigaction(AP_SIG_GRACEFUL, &sa, NULL) < 0)
581
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00271)
582
                     "sigaction(" AP_SIG_GRACEFUL_STRING ")");
583
#else
584
    if (!one_process) {
585
#ifdef SIGXCPU
586
        apr_signal(SIGXCPU, SIG_DFL);
587
#endif /* SIGXCPU */
588
#ifdef SIGXFSZ
589
        apr_signal(SIGXFSZ, SIG_IGN);
590
#endif /* SIGXFSZ */
591
    }
592
593
    apr_signal(SIGTERM, sig_term);
594
#ifdef SIGHUP
595
    apr_signal(SIGHUP, restart);
596
#endif /* SIGHUP */
597
#ifdef AP_SIG_GRACEFUL
598
    apr_signal(AP_SIG_GRACEFUL, restart);
599
#endif /* AP_SIG_GRACEFUL */
600
#ifdef AP_SIG_GRACEFUL_STOP
601
    apr_signal(AP_SIG_GRACEFUL_STOP, sig_term);
602
#endif /* AP_SIG_GRACEFUL_STOP */
603
#ifdef SIGPIPE
604
    apr_signal(SIGPIPE, SIG_IGN);
605
#endif /* SIGPIPE */
606
607
#endif
608
}
609
610
/*****************************************************************
455
/*****************************************************************
611
 * Here follows a long bunch of generic server bookkeeping stuff...
456
 * Here follows a long bunch of generic server bookkeeping stuff...
612
 */
457
 */
Lines 929-935 static void * APR_THREAD_FUNC worker_thread(apr_th Link Here
929
774
930
    ap_scoreboard_image->servers[process_slot][thread_slot].pid = ap_my_pid;
775
    ap_scoreboard_image->servers[process_slot][thread_slot].pid = ap_my_pid;
931
    ap_scoreboard_image->servers[process_slot][thread_slot].tid = apr_os_thread_current();
776
    ap_scoreboard_image->servers[process_slot][thread_slot].tid = apr_os_thread_current();
932
    ap_scoreboard_image->servers[process_slot][thread_slot].generation = retained->my_generation;
777
    ap_scoreboard_image->servers[process_slot][thread_slot].generation = retained->mpm->my_generation;
933
    ap_update_child_status_from_indexes(process_slot, thread_slot,
778
    ap_update_child_status_from_indexes(process_slot, thread_slot,
934
                                        SERVER_STARTING, NULL);
779
                                        SERVER_STARTING, NULL);
935
780
Lines 1235-1249 static void child_main(int child_num_arg, int chil Link Here
1235
    apr_thread_t *start_thread_id;
1080
    apr_thread_t *start_thread_id;
1236
    int i;
1081
    int i;
1237
1082
1238
    mpm_state = AP_MPMQ_STARTING; /* for benefit of any hooks that run as this
1083
    /* for benefit of any hooks that run as this child initializes */
1239
                                   * child initializes
1084
    retained->mpm->mpm_state = AP_MPMQ_STARTING;
1240
                                   */
1085
1241
    ap_my_pid = getpid();
1086
    ap_my_pid = getpid();
1242
    ap_fatal_signal_child_setup(ap_server_conf);
1087
    ap_fatal_signal_child_setup(ap_server_conf);
1243
    apr_pool_create(&pchild, pconf);
1088
    apr_pool_create(&pchild, pconf);
1244
1089
1245
    /* close unused listeners and pods */
1090
    /* close unused listeners and pods */
1246
    for (i = 0; i < retained->num_buckets; i++) {
1091
    for (i = 0; i < retained->mpm->num_buckets; i++) {
1247
        if (i != child_bucket) {
1092
        if (i != child_bucket) {
1248
            ap_close_listeners_ex(all_buckets[i].listeners);
1093
            ap_close_listeners_ex(all_buckets[i].listeners);
1249
            ap_mpm_podx_close(all_buckets[i].pod);
1094
            ap_mpm_podx_close(all_buckets[i].pod);
Lines 1326-1332 static void child_main(int child_num_arg, int chil Link Here
1326
        clean_child_exit(APEXIT_CHILDSICK);
1171
        clean_child_exit(APEXIT_CHILDSICK);
1327
    }
1172
    }
1328
1173
1329
    mpm_state = AP_MPMQ_RUNNING;
1174
    retained->mpm->mpm_state = AP_MPMQ_RUNNING;
1330
1175
1331
    /* If we are only running in one_process mode, we will want to
1176
    /* If we are only running in one_process mode, we will want to
1332
     * still handle signals. */
1177
     * still handle signals. */
Lines 1412-1418 static int make_child(server_rec *s, int slot, int Link Here
1412
    if (one_process) {
1257
    if (one_process) {
1413
        my_bucket = &all_buckets[0];
1258
        my_bucket = &all_buckets[0];
1414
1259
1415
        set_signals();
1416
        worker_note_child_started(slot, getpid());
1260
        worker_note_child_started(slot, getpid());
1417
        child_main(slot, 0);
1261
        child_main(slot, 0);
1418
        /* NOTREACHED */
1262
        /* NOTREACHED */
Lines 1483-1489 static void startup_children(int number_to_start) Link Here
1483
        if (ap_scoreboard_image->parent[i].pid != 0) {
1327
        if (ap_scoreboard_image->parent[i].pid != 0) {
1484
            continue;
1328
            continue;
1485
        }
1329
        }
1486
        if (make_child(ap_server_conf, i, i % retained->num_buckets) < 0) {
1330
        if (make_child(ap_server_conf, i, i % retained->mpm->num_buckets) < 0) {
1487
            break;
1331
            break;
1488
        }
1332
        }
1489
        --number_to_start;
1333
        --number_to_start;
Lines 1549-1555 static void perform_idle_server_maintenance(int ch Link Here
1549
                                   loop if no pid?  not much else matters */
1393
                                   loop if no pid?  not much else matters */
1550
                if (status <= SERVER_READY &&
1394
                if (status <= SERVER_READY &&
1551
                        !ps->quiescing &&
1395
                        !ps->quiescing &&
1552
                        ps->generation == retained->my_generation &&
1396
                        ps->generation == retained->mpm->my_generation &&
1553
                        ps->bucket == child_bucket) {
1397
                        ps->bucket == child_bucket) {
1554
                    ++idle_thread_count;
1398
                    ++idle_thread_count;
1555
                }
1399
                }
Lines 1603-1609 static void perform_idle_server_maintenance(int ch Link Here
1603
        else {
1447
        else {
1604
            /* looks like a basket case, as no child ever fully initialized; give up.
1448
            /* looks like a basket case, as no child ever fully initialized; give up.
1605
             */
1449
             */
1606
            shutdown_pending = 1;
1450
            retained->mpm->shutdown_pending = 1;
1607
            child_fatal = 1;
1451
            child_fatal = 1;
1608
            ap_log_error(APLOG_MARK, APLOG_ALERT, 0,
1452
            ap_log_error(APLOG_MARK, APLOG_ALERT, 0,
1609
                         ap_server_conf, APLOGNO(02325)
1453
                         ap_server_conf, APLOGNO(02325)
Lines 1699-1705 static void server_main_loop(int remaining_childre Link Here
1699
    apr_proc_t pid;
1543
    apr_proc_t pid;
1700
    int i;
1544
    int i;
1701
1545
1702
    while (!restart_pending && !shutdown_pending) {
1546
    while (!retained->mpm->restart_pending && !retained->mpm->shutdown_pending) {
1703
        ap_wait_or_timeout(&exitwhy, &status, &pid, pconf, ap_server_conf);
1547
        ap_wait_or_timeout(&exitwhy, &status, &pid, pconf, ap_server_conf);
1704
1548
1705
        if (pid.pid != -1) {
1549
        if (pid.pid != -1) {
Lines 1713-1720 static void server_main_loop(int remaining_childre Link Here
1713
                 */
1557
                 */
1714
                if (child_slot < 0
1558
                if (child_slot < 0
1715
                    || ap_get_scoreboard_process(child_slot)->generation
1559
                    || ap_get_scoreboard_process(child_slot)->generation
1716
                       == retained->my_generation) {
1560
                       == retained->mpm->my_generation) {
1717
                    shutdown_pending = 1;
1561
                    retained->mpm->shutdown_pending = 1;
1718
                    child_fatal = 1;
1562
                    child_fatal = 1;
1719
                    return;
1563
                    return;
1720
                }
1564
                }
Lines 1760-1766 static void server_main_loop(int remaining_childre Link Here
1760
                worker_note_child_killed(-1, /* already out of the scoreboard */
1604
                worker_note_child_killed(-1, /* already out of the scoreboard */
1761
                                         pid.pid, old_gen);
1605
                                         pid.pid, old_gen);
1762
                if (processed_status == APEXIT_CHILDSICK
1606
                if (processed_status == APEXIT_CHILDSICK
1763
                    && old_gen == retained->my_generation) {
1607
                    && old_gen == retained->mpm->my_generation) {
1764
                    /* resource shortage, minimize the fork rate */
1608
                    /* resource shortage, minimize the fork rate */
1765
                    for (i = 0; i < num_buckets; i++) {
1609
                    for (i = 0; i < num_buckets; i++) {
1766
                        retained->idle_spawn_rate[i] = 1;
1610
                        retained->idle_spawn_rate[i] = 1;
Lines 1773-1779 static void server_main_loop(int remaining_childre Link Here
1773
                /* handled */
1617
                /* handled */
1774
#endif
1618
#endif
1775
            }
1619
            }
1776
            else if (retained->is_graceful) {
1620
            else if (retained->mpm->was_graceful) {
1777
                /* Great, we've probably just lost a slot in the
1621
                /* Great, we've probably just lost a slot in the
1778
                 * scoreboard.  Somehow we don't know about this child.
1622
                 * scoreboard.  Somehow we don't know about this child.
1779
                 */
1623
                 */
Lines 1811-1835 static void server_main_loop(int remaining_childre Link Here
1811
1655
1812
static int worker_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
1656
static int worker_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
1813
{
1657
{
1814
    int num_buckets = retained->num_buckets;
1658
    int num_buckets = retained->mpm->num_buckets;
1815
    int remaining_children_to_start;
1659
    int remaining_children_to_start;
1816
    int i;
1660
    int i;
1817
1661
1818
    ap_log_pid(pconf, ap_pid_fname);
1662
    ap_log_pid(pconf, ap_pid_fname);
1819
1663
1820
    if (!retained->is_graceful) {
1664
    if (!retained->mpm->was_graceful) {
1821
        if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) {
1665
        if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) {
1822
            mpm_state = AP_MPMQ_STOPPING;
1666
            retained->mpm->mpm_state = AP_MPMQ_STOPPING;
1823
            return !OK;
1667
            return !OK;
1824
        }
1668
        }
1825
        /* fix the generation number in the global score; we just got a new,
1669
        /* fix the generation number in the global score; we just got a new,
1826
         * cleared scoreboard
1670
         * cleared scoreboard
1827
         */
1671
         */
1828
        ap_scoreboard_image->global->running_generation = retained->my_generation;
1672
        ap_scoreboard_image->global->running_generation = retained->mpm->my_generation;
1829
    }
1673
    }
1830
1674
1831
    restart_pending = shutdown_pending = 0;
1675
    ap_unixd_mpm_set_signals(pconf, one_process);
1832
    set_signals();
1833
1676
1834
    /* Don't thrash since num_buckets depends on the
1677
    /* Don't thrash since num_buckets depends on the
1835
     * system and the number of online CPU cores...
1678
     * system and the number of online CPU cores...
Lines 1862-1868 static int worker_run(apr_pool_t *_pconf, apr_pool Link Here
1862
    if (remaining_children_to_start > ap_daemons_limit) {
1705
    if (remaining_children_to_start > ap_daemons_limit) {
1863
        remaining_children_to_start = ap_daemons_limit;
1706
        remaining_children_to_start = ap_daemons_limit;
1864
    }
1707
    }
1865
    if (!retained->is_graceful) {
1708
    if (!retained->mpm->was_graceful) {
1866
        startup_children(remaining_children_to_start);
1709
        startup_children(remaining_children_to_start);
1867
        remaining_children_to_start = 0;
1710
        remaining_children_to_start = 0;
1868
    }
1711
    }
Lines 1885-1896 static int worker_run(apr_pool_t *_pconf, apr_pool Link Here
1885
                    ? apr_proc_mutex_name(all_buckets[0].mutex)
1728
                    ? apr_proc_mutex_name(all_buckets[0].mutex)
1886
                    : "none",
1729
                    : "none",
1887
                apr_proc_mutex_defname());
1730
                apr_proc_mutex_defname());
1888
    mpm_state = AP_MPMQ_RUNNING;
1731
    retained->mpm->mpm_state = AP_MPMQ_RUNNING;
1889
1732
1890
    server_main_loop(remaining_children_to_start, num_buckets);
1733
    server_main_loop(remaining_children_to_start, num_buckets);
1891
    mpm_state = AP_MPMQ_STOPPING;
1734
    retained->mpm->mpm_state = AP_MPMQ_STOPPING;
1892
1735
1893
    if (shutdown_pending && !retained->is_graceful) {
1736
    if (retained->mpm->shutdown_pending && retained->mpm->is_ungraceful) {
1894
        /* Time to shut down:
1737
        /* Time to shut down:
1895
         * Kill child processes, tell them to call child_exit, etc...
1738
         * Kill child processes, tell them to call child_exit, etc...
1896
         */
1739
         */
Lines 1908-1914 static int worker_run(apr_pool_t *_pconf, apr_pool Link Here
1908
                         ap_server_conf, APLOGNO(00295) "caught SIGTERM, shutting down");
1751
                         ap_server_conf, APLOGNO(00295) "caught SIGTERM, shutting down");
1909
        }
1752
        }
1910
        return DONE;
1753
        return DONE;
1911
    } else if (shutdown_pending) {
1754
    } else if (retained->mpm->shutdown_pending) {
1912
        /* Time to gracefully shut down:
1755
        /* Time to gracefully shut down:
1913
         * Kill child processes, tell them to call child_exit, etc...
1756
         * Kill child processes, tell them to call child_exit, etc...
1914
         */
1757
         */
Lines 1939-1945 static int worker_run(apr_pool_t *_pconf, apr_pool Link Here
1939
        }
1782
        }
1940
1783
1941
        /* Don't really exit until each child has finished */
1784
        /* Don't really exit until each child has finished */
1942
        shutdown_pending = 0;
1785
        retained->mpm->shutdown_pending = 0;
1943
        do {
1786
        do {
1944
            /* Pause for a second */
1787
            /* Pause for a second */
1945
            apr_sleep(apr_time_from_sec(1));
1788
            apr_sleep(apr_time_from_sec(1));
Lines 1955-1961 static int worker_run(apr_pool_t *_pconf, apr_pool Link Here
1955
                    break;
1798
                    break;
1956
                }
1799
                }
1957
            }
1800
            }
1958
        } while (!shutdown_pending && active_children &&
1801
        } while (!retained->mpm->shutdown_pending && active_children &&
1959
                 (!ap_graceful_shutdown_timeout || apr_time_now() < cutoff));
1802
                 (!ap_graceful_shutdown_timeout || apr_time_now() < cutoff));
1960
1803
1961
        /* We might be here because we received SIGTERM, either
1804
        /* We might be here because we received SIGTERM, either
Lines 1983-1992 static int worker_run(apr_pool_t *_pconf, apr_pool Link Here
1983
    /* XXX: we really need to make sure this new generation number isn't in
1826
    /* XXX: we really need to make sure this new generation number isn't in
1984
     * use by any of the children.
1827
     * use by any of the children.
1985
     */
1828
     */
1986
    ++retained->my_generation;
1829
    ++retained->mpm->my_generation;
1987
    ap_scoreboard_image->global->running_generation = retained->my_generation;
1830
    ap_scoreboard_image->global->running_generation = retained->mpm->my_generation;
1988
1831
1989
    if (retained->is_graceful) {
1832
    if (!retained->mpm->is_ungraceful) {
1990
        ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00297)
1833
        ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00297)
1991
                     AP_SIG_GRACEFUL_STRING " received.  Doing graceful restart");
1834
                     AP_SIG_GRACEFUL_STRING " received.  Doing graceful restart");
1992
        /* wake up the children...time to die.  But we'll have more soon */
1835
        /* wake up the children...time to die.  But we'll have more soon */
Lines 2035-2041 static int worker_open_logs(apr_pool_t *p, apr_poo Link Here
2035
    pconf = p;
1878
    pconf = p;
2036
1879
2037
    /* the reverse of pre_config, we want this only the first time around */
1880
    /* the reverse of pre_config, we want this only the first time around */
2038
    if (retained->module_loads == 1) {
1881
    if (retained->mpm->module_loads == 1) {
2039
        startup = 1;
1882
        startup = 1;
2040
        level_flags |= APLOG_STARTUP;
1883
        level_flags |= APLOG_STARTUP;
2041
    }
1884
    }
Lines 2050-2058 static int worker_open_logs(apr_pool_t *p, apr_poo Link Here
2050
    if (one_process) {
1893
    if (one_process) {
2051
        num_buckets = 1;
1894
        num_buckets = 1;
2052
    }
1895
    }
2053
    else if (retained->is_graceful) {
1896
    else if (retained->mpm->was_graceful) {
2054
        /* Preserve the number of buckets on graceful restarts. */
1897
        /* Preserve the number of buckets on graceful restarts. */
2055
        num_buckets = retained->num_buckets;
1898
        num_buckets = retained->mpm->num_buckets;
2056
    }
1899
    }
2057
    if ((rv = ap_duplicate_listeners(pconf, ap_server_conf,
1900
    if ((rv = ap_duplicate_listeners(pconf, ap_server_conf,
2058
                                     &listen_buckets, &num_buckets))) {
1901
                                     &listen_buckets, &num_buckets))) {
Lines 2084-2108 static int worker_open_logs(apr_pool_t *p, apr_poo Link Here
2084
        all_buckets[i].listeners = listen_buckets[i];
1927
        all_buckets[i].listeners = listen_buckets[i];
2085
    }
1928
    }
2086
1929
2087
    if (retained->max_buckets < num_buckets) {
1930
    if (retained->mpm->max_buckets < num_buckets) {
2088
        int new_max, *new_ptr;
1931
        int new_max, *new_ptr;
2089
        new_max = retained->max_buckets * 2;
1932
        new_max = retained->mpm->max_buckets * 2;
2090
        if (new_max < num_buckets) {
1933
        if (new_max < num_buckets) {
2091
            new_max = num_buckets;
1934
            new_max = num_buckets;
2092
        }
1935
        }
2093
        new_ptr = (int *)apr_palloc(ap_pglobal, new_max * sizeof(int));
1936
        new_ptr = (int *)apr_palloc(ap_pglobal, new_max * sizeof(int));
2094
        memcpy(new_ptr, retained->idle_spawn_rate,
1937
        memcpy(new_ptr, retained->idle_spawn_rate,
2095
               retained->num_buckets * sizeof(int));
1938
               retained->mpm->num_buckets * sizeof(int));
2096
        retained->idle_spawn_rate = new_ptr;
1939
        retained->idle_spawn_rate = new_ptr;
2097
        retained->max_buckets = new_max;
1940
        retained->mpm->max_buckets = new_max;
2098
    }
1941
    }
2099
    if (retained->num_buckets < num_buckets) {
1942
    if (retained->mpm->num_buckets < num_buckets) {
2100
        int rate_max = 1;
1943
        int rate_max = 1;
2101
        /* If new buckets are added, set their idle spawn rate to
1944
        /* If new buckets are added, set their idle spawn rate to
2102
         * the highest so far, so that they get filled as quickly
1945
         * the highest so far, so that they get filled as quickly
2103
         * as the existing ones.
1946
         * as the existing ones.
2104
         */
1947
         */
2105
        for (i = 0; i < retained->num_buckets; i++) {
1948
        for (i = 0; i < retained->mpm->num_buckets; i++) {
2106
            if (rate_max < retained->idle_spawn_rate[i]) {
1949
            if (rate_max < retained->idle_spawn_rate[i]) {
2107
                rate_max = retained->idle_spawn_rate[i];
1950
                rate_max = retained->idle_spawn_rate[i];
2108
            }
1951
            }
Lines 2111-2117 static int worker_open_logs(apr_pool_t *p, apr_poo Link Here
2111
            retained->idle_spawn_rate[i] = rate_max;
1954
            retained->idle_spawn_rate[i] = rate_max;
2112
        }
1955
        }
2113
    }
1956
    }
2114
    retained->num_buckets = num_buckets;
1957
    retained->mpm->num_buckets = num_buckets;
2115
1958
2116
    return OK;
1959
    return OK;
2117
}
1960
}
Lines 2123-2130 static int worker_pre_config(apr_pool_t *pconf, ap Link Here
2123
    apr_status_t rv;
1966
    apr_status_t rv;
2124
    const char *userdata_key = "mpm_worker_module";
1967
    const char *userdata_key = "mpm_worker_module";
2125
1968
2126
    mpm_state = AP_MPMQ_STARTING;
2127
2128
    debug = ap_exists_config_define("DEBUG");
1969
    debug = ap_exists_config_define("DEBUG");
2129
1970
2130
    if (debug) {
1971
    if (debug) {
Lines 2139-2152 static int worker_pre_config(apr_pool_t *pconf, ap Link Here
2139
1980
2140
    ap_mutex_register(pconf, AP_ACCEPT_MUTEX_TYPE, NULL, APR_LOCK_DEFAULT, 0);
1981
    ap_mutex_register(pconf, AP_ACCEPT_MUTEX_TYPE, NULL, APR_LOCK_DEFAULT, 0);
2141
1982
2142
    /* sigh, want this only the second time around */
2143
    retained = ap_retained_data_get(userdata_key);
1983
    retained = ap_retained_data_get(userdata_key);
2144
    if (!retained) {
1984
    if (!retained) {
2145
        retained = ap_retained_data_create(userdata_key, sizeof(*retained));
1985
        retained = ap_retained_data_create(userdata_key, sizeof(*retained));
1986
        retained->mpm = ap_unixd_mpm_get_retained_data();
2146
        retained->max_daemons_limit = -1;
1987
        retained->max_daemons_limit = -1;
2147
    }
1988
    }
2148
    ++retained->module_loads;
1989
    if (retained->mpm->baton != retained) {
2149
    if (retained->module_loads == 2) {
1990
        retained->mpm->was_graceful = 0;
1991
        retained->mpm->baton = retained;
1992
    }
1993
    retained->mpm->mpm_state = AP_MPMQ_STARTING;
1994
    ++retained->mpm->module_loads;
1995
1996
    /* sigh, want this only the second time around */
1997
    if (retained->mpm->module_loads == 2) {
2150
        if (!one_process && !foreground) {
1998
        if (!one_process && !foreground) {
2151
            /* before we detach, setup crash handlers to log to errorlog */
1999
            /* before we detach, setup crash handlers to log to errorlog */
2152
            ap_fatal_signal_setup(ap_server_conf, pconf);
2000
            ap_fatal_signal_setup(ap_server_conf, pconf);
Lines 2183-2189 static int worker_check_config(apr_pool_t *p, apr_ Link Here
2183
    int startup = 0;
2031
    int startup = 0;
2184
2032
2185
    /* the reverse of pre_config, we want this only the first time around */
2033
    /* the reverse of pre_config, we want this only the first time around */
2186
    if (retained->module_loads == 1) {
2034
    if (retained->mpm->module_loads == 1) {
2187
        startup = 1;
2035
        startup = 1;
2188
    }
2036
    }
2189
2037

Return to bug 60487