| 1605 | } |
| 1606 | |
| 1607 | static void server_main_loop(int remaining_children_to_start) |
| 1608 | { |
| 1609 | int num_buckets = retained->mpm->num_buckets; |
| 1610 | int successive_kills = 0; |
| 1611 | ap_generation_t old_gen; |
| 1612 | int child_slot; |
| 1613 | apr_exit_why_e exitwhy; |
| 1614 | int status, processed_status; |
| 1615 | apr_proc_t pid; |
| 1616 | int i; |
| 1617 | |
| 1618 | while (!retained->mpm->restart_pending && !retained->mpm->shutdown_pending) { |
| 1619 | ap_wait_or_timeout(&exitwhy, &status, &pid, pconf, ap_server_conf); |
| 1620 | |
| 1621 | if (pid.pid != -1) { |
| 1622 | processed_status = ap_process_child_status(&pid, exitwhy, status); |
| 1623 | child_slot = ap_find_child_by_pid(&pid); |
| 1624 | if (processed_status == APEXIT_CHILDFATAL) { |
| 1625 | /* fix race condition found in PR 39311 |
| 1626 | * A child created at the same time as a graceful happens |
| 1627 | * can find the lock missing and create a fatal error. |
| 1628 | * It is not fatal for the last generation to be in this state. |
| 1629 | */ |
| 1630 | if (child_slot < 0 |
| 1631 | || ap_get_scoreboard_process(child_slot)->generation |
| 1632 | == retained->mpm->my_generation) { |
| 1633 | retained->mpm->shutdown_pending = 1; |
| 1634 | child_fatal = 1; |
| 1635 | return; |
| 1636 | } |
| 1637 | else { |
| 1638 | ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ap_server_conf, APLOGNO(00290) |
| 1639 | "Ignoring fatal error in child of previous " |
| 1640 | "generation (pid %ld).", |
| 1641 | (long)pid.pid); |
| 1642 | retained->sick_child_detected = 1; |
| 1643 | } |
| 1644 | } |
| 1645 | else if (processed_status == APEXIT_CHILDSICK) { |
| 1646 | /* tell perform_idle_server_maintenance to check into this |
| 1647 | * on the next timer pop |
| 1648 | */ |
| 1649 | retained->sick_child_detected = 1; |
| 1650 | } |
| 1651 | /* non-fatal death... note that it's gone in the scoreboard. */ |
| 1652 | if (child_slot >= 0) { |
| 1653 | process_score *ps; |
| 1654 | |
| 1655 | for (i = 0; i < threads_per_child; i++) |
| 1656 | ap_update_child_status_from_indexes(child_slot, i, |
| 1657 | SERVER_DEAD, NULL); |
| 1658 | |
| 1659 | worker_note_child_killed(child_slot, 0, 0); |
| 1660 | ps = &ap_scoreboard_image->parent[child_slot]; |
| 1661 | ps->quiescing = 0; |
| 1662 | if (processed_status == APEXIT_CHILDSICK) { |
| 1663 | /* resource shortage, minimize the fork rate */ |
| 1664 | retained->idle_spawn_rate[child_slot % num_buckets] = 1; |
no test coverage detected