<li>REMOVES: accept, lockfile, lock_mech, set_scoreboard (locking uses the new ap_mutex API)</li>
<li>NEW API to drop privileges (delegates this platform-dependent
function to modules)</li>
- <li>NEW Hooks: mpm_query, mpm_note_child_killed, timed_callback, and get_name</li>
+ <li>NEW Hooks: mpm_query, timed_callback, and get_name</li>
+ <li>CHANGED interfaces: monitor hook,
+ ap_reclaim_child_processes, ap_relieve_child_processes</li>
</ul>
</section>
* proxy and cache interfaces.
* Change ap_configfile_t/ap_cfg_getline()/
* ap_cfg_getc() API, add ap_pcfg_strerror()
+ * Axe mpm_note_child_killed hook, change
+ * ap_reclaim_child_process and ap_recover_child_process
+ * interfaces.
*/
#define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */
/* Signal used to gracefully stop (as a quoted string) */
#define AP_SIG_GRACEFUL_STOP_STRING "SIGWINCH"
+/**
+ * Callback function used for ap_reclaim_child_processes() and
+ * ap_relieve_child_processes(). The callback function will be
+ * called for each terminated child process.
+ */
+typedef void ap_reclaim_callback_fn_t(int childnum);
+
/**
* Make sure all child processes that have been spawned by the parent process
* have died. This includes process registered as "other_children".
* @param terminate Either 1 or 0. If 1, send the child processes SIGTERM
* each time through the loop. If 0, give the process time to die
* on its own before signalling it.
- * @note This function requires that a hook is implemented by the MPM: <pre>
- * mpm_note_child_killed -- Note the child died in the scoreboard
- * </pre>
*
* @note The MPM child processes which are reclaimed are those listed
* in the scoreboard as well as those currently registered via
* ap_register_extra_mpm_process().
*/
-void ap_reclaim_child_processes(int terminate);
+void ap_reclaim_child_processes(int terminate,
+ ap_reclaim_callback_fn_t *mpm_callback);
/**
* Catch any child processes that have been spawned by the parent process
* which have exited. This includes processes registered as "other_children".
*
- * @note This function requires that a hook is implemented by the MPM: <pre>
- * mpm_note_child_killed -- Note the child died in the scoreboard
- * </pre>
- *
* @note The MPM child processes which are relieved are those listed
* in the scoreboard as well as those currently registered via
* ap_register_extra_mpm_process().
*/
-void ap_relieve_child_processes(void);
+void ap_relieve_child_processes(ap_reclaim_callback_fn_t *mpm_callback);
/**
* Tell ap_reclaim_child_processes() and ap_relieve_child_processes() about
*/
AP_DECLARE_HOOK(int, mpm_query, (int query_code, int *result, apr_status_t *rv))
-/* child specified by index has been killed; MPMs which use
- * ap_reclaim_child_processes() or ap_relieve_child_processes() must
- * implement this in order to update the scoreboard and handle any
- * MPM-specific actions
- */
-AP_DECLARE_HOOK(apr_status_t, mpm_note_child_killed, (int childnum))
-
/* register the specified callback */
AP_DECLARE_HOOK(apr_status_t, mpm_register_timed_callback,
(apr_time_t t, ap_mpm_callback_fn_t *cbfn, void *baton))
return OK;
}
-static apr_status_t event_note_child_killed(int childnum)
+static void event_note_child_killed(int childnum)
{
ap_scoreboard_image->parent[childnum].pid = 0;
- return APR_SUCCESS;
}
static const char *event_get_name(void)
* Kill child processes, tell them to call child_exit, etc...
*/
ap_event_pod_killpg(pod, ap_daemons_limit, FALSE);
- ap_reclaim_child_processes(1); /* Start with SIGTERM */
+ ap_reclaim_child_processes(1, /* Start with SIGTERM */
+ event_note_child_killed);
if (!child_fatal) {
/* cleanup pid file on normal shutdown */
/* Close our listeners, and then ask our children to do same */
ap_close_listeners();
ap_event_pod_killpg(pod, ap_daemons_limit, TRUE);
- ap_relieve_child_processes();
+ ap_relieve_child_processes(event_note_child_killed);
if (!child_fatal) {
/* cleanup pid file on normal shutdown */
apr_sleep(apr_time_from_sec(1));
/* Relieve any children which have now exited */
- ap_relieve_child_processes();
+ ap_relieve_child_processes(event_note_child_killed);
active_children = 0;
for (index = 0; index < ap_daemons_limit; ++index) {
* really dead.
*/
ap_event_pod_killpg(pod, ap_daemons_limit, FALSE);
- ap_reclaim_child_processes(1);
+ ap_reclaim_child_processes(1, event_note_child_killed);
return DONE;
}
*/
ap_event_pod_killpg(pod, ap_daemons_limit, FALSE);
- ap_reclaim_child_processes(1); /* Start with SIGTERM */
+ ap_reclaim_child_processes(1, /* Start with SIGTERM */
+ event_note_child_killed);
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,
"SIGHUP received. Attempting to restart");
}
ap_hook_check_config(event_check_config, NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_mpm(event_run, NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_mpm_query(event_query, NULL, NULL, APR_HOOK_MIDDLE);
- ap_hook_mpm_note_child_killed(event_note_child_killed, NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_mpm_register_timed_callback(event_register_timed_callback, NULL, NULL,
APR_HOOK_MIDDLE);
ap_hook_mpm_get_name(event_get_name, NULL, NULL, APR_HOOK_MIDDLE);
return OK;
}
-static apr_status_t prefork_note_child_killed(int childnum)
+static void prefork_note_child_killed(int childnum)
{
ap_scoreboard_image->parent[childnum].pid = 0;
- return APR_SUCCESS;
}
static const char *prefork_get_name(void)
if (ap_unixd_killpg(getpgrp(), SIGTERM) < 0) {
ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "killpg SIGTERM");
}
- ap_reclaim_child_processes(1); /* Start with SIGTERM */
+ ap_reclaim_child_processes(1, /* Start with SIGTERM */
+ prefork_note_child_killed);
/* cleanup pid file on normal shutdown */
ap_remove_pid(pconf, ap_pid_fname);
}
/* Allow each child which actually finished to exit */
- ap_relieve_child_processes();
+ ap_relieve_child_processes(prefork_note_child_killed);
/* cleanup pid file */
ap_remove_pid(pconf, ap_pid_fname);
sleep(1);
/* Relieve any children which have now exited */
- ap_relieve_child_processes();
+ ap_relieve_child_processes(prefork_note_child_killed);
active_children = 0;
for (index = 0; index < ap_daemons_limit; ++index) {
if (ap_unixd_killpg(getpgrp(), SIGHUP) < 0) {
ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "killpg SIGHUP");
}
- ap_reclaim_child_processes(0); /* Not when just starting up */
+ ap_reclaim_child_processes(0, /* Not when just starting up */
+ prefork_note_child_killed);
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,
"SIGHUP received. Attempting to restart");
}
ap_hook_check_config(prefork_check_config, NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_mpm(prefork_run, NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_mpm_query(prefork_query, NULL, NULL, APR_HOOK_MIDDLE);
- ap_hook_mpm_note_child_killed(prefork_note_child_killed, NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_mpm_get_name(prefork_get_name, NULL, NULL, APR_HOOK_MIDDLE);
}
return OK;
}
-static apr_status_t worker_note_child_killed(int childnum)
+static void worker_note_child_killed(int childnum)
{
ap_scoreboard_image->parent[childnum].pid = 0;
- return APR_SUCCESS;
}
static const char *worker_get_name(void)
* Kill child processes, tell them to call child_exit, etc...
*/
ap_worker_pod_killpg(pod, ap_daemons_limit, FALSE);
- ap_reclaim_child_processes(1); /* Start with SIGTERM */
+ ap_reclaim_child_processes(1, /* Start with SIGTERM */
+ worker_note_child_killed);
if (!child_fatal) {
/* cleanup pid file on normal shutdown */
/* Close our listeners, and then ask our children to do same */
ap_close_listeners();
ap_worker_pod_killpg(pod, ap_daemons_limit, TRUE);
- ap_relieve_child_processes();
+ ap_relieve_child_processes(worker_note_child_killed);
if (!child_fatal) {
/* cleanup pid file on normal shutdown */
apr_sleep(apr_time_from_sec(1));
/* Relieve any children which have now exited */
- ap_relieve_child_processes();
+ ap_relieve_child_processes(worker_note_child_killed);
active_children = 0;
for (index = 0; index < ap_daemons_limit; ++index) {
* really dead.
*/
ap_worker_pod_killpg(pod, ap_daemons_limit, FALSE);
- ap_reclaim_child_processes(1);
+ ap_reclaim_child_processes(1, worker_note_child_killed);
return DONE;
}
*/
ap_worker_pod_killpg(pod, ap_daemons_limit, FALSE);
- ap_reclaim_child_processes(1); /* Start with SIGTERM */
+ ap_reclaim_child_processes(1, /* Start with SIGTERM */
+ worker_note_child_killed);
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,
"SIGHUP received. Attempting to restart");
}
ap_hook_check_config(worker_check_config, NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_mpm(worker_run, NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_mpm_query(worker_query, NULL, NULL, APR_HOOK_MIDDLE);
- ap_hook_mpm_note_child_killed(worker_note_child_killed, NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_mpm_get_name(worker_get_name, NULL, NULL, APR_HOOK_MIDDLE);
}
APR_HOOK_LINK(drop_privileges)
APR_HOOK_LINK(mpm)
APR_HOOK_LINK(mpm_query)
- APR_HOOK_LINK(mpm_note_child_killed)
APR_HOOK_LINK(mpm_register_timed_callback)
APR_HOOK_LINK(mpm_get_name)
)
APR_HOOK_LINK(drop_privileges)
APR_HOOK_LINK(mpm)
APR_HOOK_LINK(mpm_query)
- APR_HOOK_LINK(mpm_note_child_killed)
APR_HOOK_LINK(mpm_register_timed_callback)
APR_HOOK_LINK(mpm_get_name)
)
AP_IMPLEMENT_HOOK_RUN_FIRST(int, mpm_query,
(int query_code, int *result, apr_status_t *_rv),
(query_code, result, _rv), DECLINED)
-AP_IMPLEMENT_HOOK_RUN_FIRST(apr_status_t, mpm_note_child_killed,
- (int childnum),
- (childnum), APR_ENOTIMPL)
AP_IMPLEMENT_HOOK_RUN_FIRST(apr_status_t, mpm_register_timed_callback,
(apr_time_t t, ap_mpm_callback_fn_t *cbfn, void *baton),
(t, cbfn, baton), APR_ENOTIMPL)
return 0;
}
-void ap_reclaim_child_processes(int terminate)
+void ap_reclaim_child_processes(int terminate,
+ ap_reclaim_callback_fn_t *mpm_callback)
{
apr_time_t waittime = 1024 * 16;
int i;
}
if (reclaim_one_pid(pid, action_table[cur_action].action)) {
- ap_run_mpm_note_child_killed(i);
+ mpm_callback(i);
}
else {
++not_dead_yet;
action_table[cur_action].action != GIVEUP);
}
-void ap_relieve_child_processes(void)
+void ap_relieve_child_processes(ap_reclaim_callback_fn_t *mpm_callback)
{
int i;
extra_process_t *cur_extra;
}
if (reclaim_one_pid(pid, DO_NOTHING)) {
- ap_run_mpm_note_child_killed(i);
+ mpm_callback(i);
}
}