Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 8E7DE200C22 for ; Tue, 21 Feb 2017 10:07:50 +0100 (CET) Received: by cust-asf.ponee.io (Postfix) id 8D049160B74; Tue, 21 Feb 2017 09:07:50 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 669E6160B3E for ; Tue, 21 Feb 2017 10:07:49 +0100 (CET) Received: (qmail 85838 invoked by uid 500); 21 Feb 2017 09:07:43 -0000 Mailing-List: contact cvs-help@httpd.apache.org; run by ezmlm Precedence: bulk Reply-To: dev@httpd.apache.org list-help: list-unsubscribe: List-Post: List-Id: Delivered-To: mailing list cvs@httpd.apache.org Received: (qmail 85826 invoked by uid 99); 21 Feb 2017 09:07:43 -0000 Received: from Unknown (HELO svn01-us-west.apache.org) (209.188.14.144) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 21 Feb 2017 09:07:43 +0000 Received: from svn01-us-west.apache.org (localhost [127.0.0.1]) by svn01-us-west.apache.org (ASF Mail Server at svn01-us-west.apache.org) with ESMTP id C958D3A3B69 for ; Tue, 21 Feb 2017 09:07:42 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1783849 [2/2] - in /httpd/httpd/trunk: CHANGES os/unix/unixd.c os/unix/unixd.h server/mpm/event/event.c server/mpm/motorz/motorz.c server/mpm/motorz/motorz.h server/mpm/prefork/prefork.c server/mpm/worker/worker.c server/mpm_unix.c Date: Tue, 21 Feb 2017 09:07:42 -0000 To: cvs@httpd.apache.org From: ylavic@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20170221090742.C958D3A3B69@svn01-us-west.apache.org> archived-at: Tue, 21 Feb 2017 09:07:50 -0000 Modified: httpd/httpd/trunk/server/mpm/worker/worker.c URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/mpm/worker/worker.c?rev=1783849&r1=1783848&r2=1783849&view=diff ============================================================================== --- httpd/httpd/trunk/server/mpm/worker/worker.c (original) +++ httpd/httpd/trunk/server/mpm/worker/worker.c Tue Feb 21 09:07:42 2017 @@ -135,19 +135,17 @@ static int num_listensocks = 0; static int resource_shortage = 0; static fd_queue_t *worker_queue; static fd_queue_info_t *worker_queue_info; -static int mpm_state = AP_MPMQ_STARTING; /* data retained by worker across load/unload of the module * allocated on first call to pre-config hook; located on * subsequent calls to pre-config hook */ typedef struct worker_retained_data { + ap_unixd_mpm_retained_data *mpm; + int first_server_limit; int first_thread_limit; - int module_loads; int sick_child_detected; - ap_generation_t my_generation; - int volatile is_graceful; /* set from signal handler */ int maxclients_reported; int near_maxclients_reported; /* @@ -168,12 +166,6 @@ typedef struct worker_retained_data { #define MAX_SPAWN_RATE (32) #endif int hold_off_on_exponential_spawning; - /* - * Current number of listeners buckets and maximum reached across - * restarts (to size retained data according to dynamic num_buckets, - * eg. idle_spawn_rate). - */ - int num_buckets, max_buckets; } worker_retained_data; static worker_retained_data *retained; @@ -314,7 +306,7 @@ static void signal_threads(int mode) return; } terminate_mode = mode; - mpm_state = AP_MPMQ_STOPPING; + retained->mpm->mpm_state = AP_MPMQ_STOPPING; /* in case we weren't called from the listener thread, wake up the * listener thread @@ -373,10 +365,10 @@ static int worker_query(int query_code, *result = ap_daemons_limit; break; case AP_MPMQ_MPM_STATE: - *result = mpm_state; + *result = retained->mpm->mpm_state; break; case AP_MPMQ_GENERATION: - *result = retained->my_generation; + *result = retained->mpm->my_generation; break; default: *rv = APR_ENOTIMPL; @@ -404,7 +396,7 @@ static void worker_note_child_started(in ap_scoreboard_image->parent[slot].pid = pid; ap_run_child_status(ap_server_conf, ap_scoreboard_image->parent[slot].pid, - retained->my_generation, slot, MPM_CHILD_STARTED); + retained->mpm->my_generation, slot, MPM_CHILD_STARTED); } static void worker_note_child_lost_slot(int slot, pid_t newpid) @@ -437,7 +429,7 @@ static const char *worker_get_name(void) static void clean_child_exit(int code) __attribute__ ((noreturn)); static void clean_child_exit(int code) { - mpm_state = AP_MPMQ_STOPPING; + retained->mpm->mpm_state = AP_MPMQ_STOPPING; if (pchild) { apr_pool_destroy(pchild); } @@ -460,153 +452,6 @@ static void just_die(int sig) static int child_fatal; -/* volatile because they're updated from a signal handler */ -static int volatile shutdown_pending; -static int volatile restart_pending; - -/* - * ap_start_shutdown() and ap_start_restart(), below, are a first stab at - * functions to initiate shutdown or restart without relying on signals. - * Previously this was initiated in sig_term() and restart() signal handlers, - * but we want to be able to start a shutdown/restart from other sources -- - * e.g. on Win32, from the service manager. Now the service manager can - * call ap_start_shutdown() or ap_start_restart() as appropriate. Note that - * these functions can also be called by the child processes, since global - * variables are no longer used to pass on the required action to the parent. - * - * These should only be called from the parent process itself, since the - * parent process will use the shutdown_pending and restart_pending variables - * to determine whether to shutdown or restart. The child process should - * call signal_parent() directly to tell the parent to die -- this will - * cause neither of those variable to be set, which the parent will - * assume means something serious is wrong (which it will be, for the - * child to force an exit) and so do an exit anyway. - */ - -static void ap_start_shutdown(int graceful) -{ - mpm_state = AP_MPMQ_STOPPING; - if (shutdown_pending == 1) { - /* Um, is this _probably_ not an error, if the user has - * tried to do a shutdown twice quickly, so we won't - * worry about reporting it. - */ - return; - } - shutdown_pending = 1; - retained->is_graceful = graceful; -} - -/* do a graceful restart if graceful == 1 */ -static void ap_start_restart(int graceful) -{ - mpm_state = AP_MPMQ_STOPPING; - if (restart_pending == 1) { - /* Probably not an error - don't bother reporting it */ - return; - } - restart_pending = 1; - retained->is_graceful = graceful; -} - -static void sig_term(int sig) -{ - ap_start_shutdown(sig == AP_SIG_GRACEFUL_STOP); -} - -static void restart(int sig) -{ - ap_start_restart(sig == AP_SIG_GRACEFUL); -} - -static void set_signals(void) -{ -#ifndef NO_USE_SIGACTION - struct sigaction sa; -#endif - - if (!one_process) { - ap_fatal_signal_setup(ap_server_conf, pconf); - } - -#ifndef NO_USE_SIGACTION - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - - sa.sa_handler = sig_term; - if (sigaction(SIGTERM, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00264) - "sigaction(SIGTERM)"); -#ifdef AP_SIG_GRACEFUL_STOP - if (sigaction(AP_SIG_GRACEFUL_STOP, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00265) - "sigaction(" AP_SIG_GRACEFUL_STOP_STRING ")"); -#endif -#ifdef SIGINT - if (sigaction(SIGINT, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00266) - "sigaction(SIGINT)"); -#endif -#ifdef SIGXCPU - sa.sa_handler = SIG_DFL; - if (sigaction(SIGXCPU, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00267) - "sigaction(SIGXCPU)"); -#endif -#ifdef SIGXFSZ - /* For systems following the LFS standard, ignoring SIGXFSZ allows - * a write() beyond the 2GB limit to fail gracefully with E2BIG - * rather than terminate the process. */ - sa.sa_handler = SIG_IGN; - if (sigaction(SIGXFSZ, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00268) - "sigaction(SIGXFSZ)"); -#endif -#ifdef SIGPIPE - sa.sa_handler = SIG_IGN; - if (sigaction(SIGPIPE, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00269) - "sigaction(SIGPIPE)"); -#endif - - /* we want to ignore HUPs and AP_SIG_GRACEFUL while we're busy - * processing one */ - sigaddset(&sa.sa_mask, SIGHUP); - sigaddset(&sa.sa_mask, AP_SIG_GRACEFUL); - sa.sa_handler = restart; - if (sigaction(SIGHUP, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00270) - "sigaction(SIGHUP)"); - if (sigaction(AP_SIG_GRACEFUL, &sa, NULL) < 0) - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00271) - "sigaction(" AP_SIG_GRACEFUL_STRING ")"); -#else - if (!one_process) { -#ifdef SIGXCPU - apr_signal(SIGXCPU, SIG_DFL); -#endif /* SIGXCPU */ -#ifdef SIGXFSZ - apr_signal(SIGXFSZ, SIG_IGN); -#endif /* SIGXFSZ */ - } - - apr_signal(SIGTERM, sig_term); -#ifdef SIGHUP - apr_signal(SIGHUP, restart); -#endif /* SIGHUP */ -#ifdef AP_SIG_GRACEFUL - apr_signal(AP_SIG_GRACEFUL, restart); -#endif /* AP_SIG_GRACEFUL */ -#ifdef AP_SIG_GRACEFUL_STOP - apr_signal(AP_SIG_GRACEFUL_STOP, sig_term); -#endif /* AP_SIG_GRACEFUL_STOP */ -#ifdef SIGPIPE - apr_signal(SIGPIPE, SIG_IGN); -#endif /* SIGPIPE */ - -#endif -} - /***************************************************************** * Here follows a long bunch of generic server bookkeeping stuff... */ @@ -956,7 +801,7 @@ static void * APR_THREAD_FUNC worker_thr ap_scoreboard_image->servers[process_slot][thread_slot].pid = ap_my_pid; ap_scoreboard_image->servers[process_slot][thread_slot].tid = apr_os_thread_current(); - ap_scoreboard_image->servers[process_slot][thread_slot].generation = retained->my_generation; + ap_scoreboard_image->servers[process_slot][thread_slot].generation = retained->mpm->my_generation; ap_update_child_status_from_indexes(process_slot, thread_slot, SERVER_STARTING, NULL); @@ -1262,15 +1107,15 @@ static void child_main(int child_num_arg apr_thread_t *start_thread_id; int i; - mpm_state = AP_MPMQ_STARTING; /* for benefit of any hooks that run as this - * child initializes - */ + /* for benefit of any hooks that run as this child initializes */ + retained->mpm->mpm_state = AP_MPMQ_STARTING; + ap_my_pid = getpid(); ap_fatal_signal_child_setup(ap_server_conf); apr_pool_create(&pchild, pconf); /* close unused listeners and pods */ - for (i = 0; i < retained->num_buckets; i++) { + for (i = 0; i < retained->mpm->num_buckets; i++) { if (i != child_bucket) { ap_close_listeners_ex(all_buckets[i].listeners); ap_mpm_podx_close(all_buckets[i].pod); @@ -1353,7 +1198,7 @@ static void child_main(int child_num_arg clean_child_exit(APEXIT_CHILDSICK); } - mpm_state = AP_MPMQ_RUNNING; + retained->mpm->mpm_state = AP_MPMQ_RUNNING; /* If we are only running in one_process mode, we will want to * still handle signals. */ @@ -1439,7 +1284,6 @@ static int make_child(server_rec *s, int if (one_process) { my_bucket = &all_buckets[0]; - set_signals(); worker_note_child_started(slot, getpid()); child_main(slot, 0); /* NOTREACHED */ @@ -1510,7 +1354,7 @@ static void startup_children(int number_ if (ap_scoreboard_image->parent[i].pid != 0) { continue; } - if (make_child(ap_server_conf, i, i % retained->num_buckets) < 0) { + if (make_child(ap_server_conf, i, i % retained->mpm->num_buckets) < 0) { break; } --number_to_start; @@ -1576,7 +1420,7 @@ static void perform_idle_server_maintena loop if no pid? not much else matters */ if (status <= SERVER_READY && !ps->quiescing && - ps->generation == retained->my_generation && + ps->generation == retained->mpm->my_generation && ps->bucket == child_bucket) { ++idle_thread_count; } @@ -1630,7 +1474,7 @@ static void perform_idle_server_maintena else { /* looks like a basket case, as no child ever fully initialized; give up. */ - shutdown_pending = 1; + retained->mpm->shutdown_pending = 1; child_fatal = 1; ap_log_error(APLOG_MARK, APLOG_ALERT, 0, ap_server_conf, APLOGNO(02325) @@ -1726,7 +1570,7 @@ static void server_main_loop(int remaini apr_proc_t pid; int i; - while (!restart_pending && !shutdown_pending) { + while (!retained->mpm->restart_pending && !retained->mpm->shutdown_pending) { ap_wait_or_timeout(&exitwhy, &status, &pid, pconf, ap_server_conf); if (pid.pid != -1) { @@ -1740,8 +1584,8 @@ static void server_main_loop(int remaini */ if (child_slot < 0 || ap_get_scoreboard_process(child_slot)->generation - == retained->my_generation) { - shutdown_pending = 1; + == retained->mpm->my_generation) { + retained->mpm->shutdown_pending = 1; child_fatal = 1; return; } @@ -1787,7 +1631,7 @@ static void server_main_loop(int remaini worker_note_child_killed(-1, /* already out of the scoreboard */ pid.pid, old_gen); if (processed_status == APEXIT_CHILDSICK - && old_gen == retained->my_generation) { + && old_gen == retained->mpm->my_generation) { /* resource shortage, minimize the fork rate */ for (i = 0; i < num_buckets; i++) { retained->idle_spawn_rate[i] = 1; @@ -1800,7 +1644,7 @@ static void server_main_loop(int remaini /* handled */ #endif } - else if (retained->is_graceful) { + else if (retained->mpm->was_graceful) { /* Great, we've probably just lost a slot in the * scoreboard. Somehow we don't know about this child. */ @@ -1838,25 +1682,27 @@ static void server_main_loop(int remaini static int worker_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s) { - int num_buckets = retained->num_buckets; + int num_buckets = retained->mpm->num_buckets; int remaining_children_to_start; int i; ap_log_pid(pconf, ap_pid_fname); - if (!retained->is_graceful) { + if (!retained->mpm->was_graceful) { if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) { - mpm_state = AP_MPMQ_STOPPING; + retained->mpm->mpm_state = AP_MPMQ_STOPPING; return !OK; } /* fix the generation number in the global score; we just got a new, * cleared scoreboard */ - ap_scoreboard_image->global->running_generation = retained->my_generation; + ap_scoreboard_image->global->running_generation = retained->mpm->my_generation; } - restart_pending = shutdown_pending = 0; - set_signals(); + if (!one_process) { + ap_fatal_signal_setup(ap_server_conf, pconf); + } + ap_unixd_mpm_set_signals(pconf, one_process); /* Don't thrash since num_buckets depends on the * system and the number of online CPU cores... @@ -1889,7 +1735,7 @@ static int worker_run(apr_pool_t *_pconf if (remaining_children_to_start > ap_daemons_limit) { remaining_children_to_start = ap_daemons_limit; } - if (!retained->is_graceful) { + if (!retained->mpm->was_graceful) { startup_children(remaining_children_to_start); remaining_children_to_start = 0; } @@ -1912,12 +1758,12 @@ static int worker_run(apr_pool_t *_pconf ? apr_proc_mutex_name(all_buckets[0].mutex) : "none", apr_proc_mutex_defname()); - mpm_state = AP_MPMQ_RUNNING; + retained->mpm->mpm_state = AP_MPMQ_RUNNING; server_main_loop(remaining_children_to_start, num_buckets); - mpm_state = AP_MPMQ_STOPPING; + retained->mpm->mpm_state = AP_MPMQ_STOPPING; - if (shutdown_pending && !retained->is_graceful) { + if (retained->mpm->shutdown_pending && retained->mpm->is_ungraceful) { /* Time to shut down: * Kill child processes, tell them to call child_exit, etc... */ @@ -1935,7 +1781,9 @@ static int worker_run(apr_pool_t *_pconf ap_server_conf, APLOGNO(00295) "caught SIGTERM, shutting down"); } return DONE; - } else if (shutdown_pending) { + } + + if (retained->mpm->shutdown_pending) { /* Time to gracefully shut down: * Kill child processes, tell them to call child_exit, etc... */ @@ -1966,7 +1814,7 @@ static int worker_run(apr_pool_t *_pconf } /* Don't really exit until each child has finished */ - shutdown_pending = 0; + retained->mpm->shutdown_pending = 0; do { /* Pause for a second */ apr_sleep(apr_time_from_sec(1)); @@ -1982,7 +1830,7 @@ static int worker_run(apr_pool_t *_pconf break; } } - } while (!shutdown_pending && active_children && + } while (!retained->mpm->shutdown_pending && active_children && (!ap_graceful_shutdown_timeout || apr_time_now() < cutoff)); /* We might be here because we received SIGTERM, either @@ -1999,8 +1847,6 @@ static int worker_run(apr_pool_t *_pconf } /* we've been told to restart */ - apr_signal(SIGHUP, SIG_IGN); - if (one_process) { /* not worth thinking about */ return DONE; @@ -2010,10 +1856,10 @@ static int worker_run(apr_pool_t *_pconf /* XXX: we really need to make sure this new generation number isn't in * use by any of the children. */ - ++retained->my_generation; - ap_scoreboard_image->global->running_generation = retained->my_generation; + ++retained->mpm->my_generation; + ap_scoreboard_image->global->running_generation = retained->mpm->my_generation; - if (retained->is_graceful) { + if (!retained->mpm->is_ungraceful) { ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00297) AP_SIG_GRACEFUL_STRING " received. Doing graceful restart"); /* wake up the children...time to die. But we'll have more soon */ @@ -2062,7 +1908,7 @@ static int worker_open_logs(apr_pool_t * pconf = p; /* the reverse of pre_config, we want this only the first time around */ - if (retained->module_loads == 1) { + if (retained->mpm->module_loads == 1) { startup = 1; level_flags |= APLOG_STARTUP; } @@ -2077,9 +1923,9 @@ static int worker_open_logs(apr_pool_t * if (one_process) { num_buckets = 1; } - else if (retained->is_graceful) { + else if (retained->mpm->was_graceful) { /* Preserve the number of buckets on graceful restarts. */ - num_buckets = retained->num_buckets; + num_buckets = retained->mpm->num_buckets; } if ((rv = ap_duplicate_listeners(pconf, ap_server_conf, &listen_buckets, &num_buckets))) { @@ -2111,25 +1957,25 @@ static int worker_open_logs(apr_pool_t * all_buckets[i].listeners = listen_buckets[i]; } - if (retained->max_buckets < num_buckets) { + if (retained->mpm->max_buckets < num_buckets) { int new_max, *new_ptr; - new_max = retained->max_buckets * 2; + new_max = retained->mpm->max_buckets * 2; if (new_max < num_buckets) { new_max = num_buckets; } new_ptr = (int *)apr_palloc(ap_pglobal, new_max * sizeof(int)); memcpy(new_ptr, retained->idle_spawn_rate, - retained->num_buckets * sizeof(int)); + retained->mpm->num_buckets * sizeof(int)); retained->idle_spawn_rate = new_ptr; - retained->max_buckets = new_max; + retained->mpm->max_buckets = new_max; } - if (retained->num_buckets < num_buckets) { + if (retained->mpm->num_buckets < num_buckets) { int rate_max = 1; /* If new buckets are added, set their idle spawn rate to * the highest so far, so that they get filled as quickly * as the existing ones. */ - for (i = 0; i < retained->num_buckets; i++) { + for (i = 0; i < retained->mpm->num_buckets; i++) { if (rate_max < retained->idle_spawn_rate[i]) { rate_max = retained->idle_spawn_rate[i]; } @@ -2138,7 +1984,7 @@ static int worker_open_logs(apr_pool_t * retained->idle_spawn_rate[i] = rate_max; } } - retained->num_buckets = num_buckets; + retained->mpm->num_buckets = num_buckets; return OK; } @@ -2150,8 +1996,6 @@ static int worker_pre_config(apr_pool_t apr_status_t rv; const char *userdata_key = "mpm_worker_module"; - mpm_state = AP_MPMQ_STARTING; - debug = ap_exists_config_define("DEBUG"); if (debug) { @@ -2166,14 +2010,21 @@ static int worker_pre_config(apr_pool_t ap_mutex_register(pconf, AP_ACCEPT_MUTEX_TYPE, NULL, APR_LOCK_DEFAULT, 0); - /* sigh, want this only the second time around */ retained = ap_retained_data_get(userdata_key); if (!retained) { retained = ap_retained_data_create(userdata_key, sizeof(*retained)); + retained->mpm = ap_unixd_mpm_get_retained_data(); retained->max_daemons_limit = -1; } - ++retained->module_loads; - if (retained->module_loads == 2) { + retained->mpm->mpm_state = AP_MPMQ_STARTING; + if (retained->mpm->baton != retained) { + retained->mpm->was_graceful = 0; + retained->mpm->baton = retained; + } + ++retained->mpm->module_loads; + + /* sigh, want this only the second time around */ + if (retained->mpm->module_loads == 2) { if (!one_process && !foreground) { /* before we detach, setup crash handlers to log to errorlog */ ap_fatal_signal_setup(ap_server_conf, pconf); @@ -2210,7 +2061,7 @@ static int worker_check_config(apr_pool_ int startup = 0; /* the reverse of pre_config, we want this only the first time around */ - if (retained->module_loads == 1) { + if (retained->mpm->module_loads == 1) { startup = 1; } Modified: httpd/httpd/trunk/server/mpm_unix.c URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/mpm_unix.c?rev=1783849&r1=1783848&r2=1783849&view=diff ============================================================================== --- httpd/httpd/trunk/server/mpm_unix.c (original) +++ httpd/httpd/trunk/server/mpm_unix.c Tue Feb 21 09:07:42 2017 @@ -1015,14 +1015,13 @@ AP_DECLARE(apr_status_t) ap_fatal_signal #ifndef NO_USE_SIGACTION struct sigaction sa; + memset(&sa, 0, sizeof sa); sigemptyset(&sa.sa_mask); #if defined(SA_ONESHOT) sa.sa_flags = SA_ONESHOT; #elif defined(SA_RESETHAND) sa.sa_flags = SA_RESETHAND; -#else - sa.sa_flags = 0; #endif sa.sa_handler = sig_coredump;