#endif
/**
- * Tell ap_reclaim_child_processes() about an MPM child process which has no
- * entry in the scoreboard.
+ * Catch any child processes that have been spawned by the parent process
+ * which have exited. This includes processes registered as "other_children".
+ * @warning This is only defined if the MPM defines
+ * AP_MPM_WANT_RECLAIM_CHILD_PROCESSES
+ * @tip This function requires that some macros are defined by the MPM: <pre>
+ * MPM_CHILD_PID -- Get the pid from the specified spot in the scoreboard
+ * MPM_NOTE_CHILD_KILLED -- Note the child died in the scoreboard
+ * </pre>
+ * @tip 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().
+ */
+#ifdef AP_MPM_WANT_RECLAIM_CHILD_PROCESSES
+void ap_relieve_child_processes(void);
+#endif
+
+/**
+ * Tell ap_reclaim_child_processes() and ap_relieve_child_processes() about
+ * an MPM child process which has no entry in the scoreboard.
* @warning This is only defined if the MPM defines
* AP_MPM_WANT_RECLAIM_CHILD_PROCESSES
* @param pid The process id of an MPM child process which should be
} while (not_dead_yet > 0 &&
action_table[cur_action].action != GIVEUP);
}
+
+void ap_relieve_child_processes(void)
+{
+ int i;
+ extra_process_t *cur_extra;
+ int max_daemons;
+
+ ap_mpm_query(AP_MPMQ_MAX_DAEMON_USED, &max_daemons);
+
+ /* now see who is done */
+ for (i = 0; i < max_daemons; ++i) {
+ pid_t pid = MPM_CHILD_PID(i);
+
+ if (pid == 0) {
+ continue; /* not every scoreboard entry is in use */
+ }
+
+ if (reclaim_one_pid(pid, DO_NOTHING)) {
+ MPM_NOTE_CHILD_KILLED(i);
+ }
+ }
+
+ cur_extra = extras;
+ while (cur_extra) {
+ extra_process_t *next = cur_extra->next;
+
+ if (reclaim_one_pid(cur_extra->pid, DO_NOTHING)) {
+ AP_DEBUG_ASSERT(1 == ap_unregister_extra_mpm_process(cur_extra->pid));
+ }
+ cur_extra = next;
+ }
+}
#endif /* AP_MPM_WANT_RECLAIM_CHILD_PROCESSES */
#ifdef AP_MPM_WANT_WAIT_OR_TIMEOUT