Loading CHANGES +4 −0 Original line number Diff line number Diff line Loading @@ -6,6 +6,10 @@ Changes with Apache 2.0.23 Changes with Apache 2.0.22 *) Fix a problem where the threaded MPM stalls after restarts or segfaults. Also prevent multiple active processes from using the same scoreboard slot. [Greg Ames] *) Apache/Win32 now fills in the service description with Apache's server version string, including loaded and advertised modules. [William Rowe] Loading include/scoreboard.h +3 −0 Original line number Diff line number Diff line Loading @@ -178,6 +178,9 @@ struct process_score{ pid_t pid; ap_generation_t generation; /* generation of this child */ ap_scoreboard_e sb_type; int quiescing; /* the process whose pid is stored above is * going down gracefully */ }; typedef struct { Loading server/mpm/threaded/threaded.c +23 −3 Original line number Diff line number Diff line Loading @@ -648,8 +648,15 @@ static void * worker_thread(apr_thread_t *thd, void * dummy) apr_pool_destroy(tpool); ap_update_child_status(process_slot, thread_slot, (dying) ? SERVER_DEAD : SERVER_GRACEFUL, (request_rec *) NULL); dying = 1; apr_lock_acquire(worker_thread_count_mutex); if (!dying) { /* this is the first thread to exit */ if (ap_my_pid == ap_scoreboard_image->parent[process_slot].pid) { /* tell the parent that it may use this scoreboard slot */ ap_scoreboard_image->parent[process_slot].quiescing = 1; } dying = 1; } worker_thread_count--; if (worker_thread_count == 0) { /* All the threads have exited, now finish the shutdown process Loading Loading @@ -900,6 +907,7 @@ static int make_child(server_rec *s, int slot) clean_child_exit(0); } /* else */ ap_scoreboard_image->parent[slot].quiescing = 0; ap_scoreboard_image->parent[slot].pid = pid; return 0; } Loading Loading @@ -961,6 +969,7 @@ static void perform_idle_server_maintenance(void) int i, j; int idle_thread_count; worker_score *ws; process_score *ps; int free_length; int free_slots[MAX_SPAWN_RATE]; int last_non_dead; Loading @@ -985,6 +994,7 @@ static void perform_idle_server_maintenance(void) if (i >= ap_max_daemons_limit && free_length == idle_spawn_rate) break; ps = &ap_scoreboard_image->parent[i]; for (j = 0; j < ap_threads_per_child; j++) { ws = &ap_scoreboard_image->servers[i][j]; status = ws->status; Loading @@ -998,11 +1008,19 @@ static void perform_idle_server_maintenance(void) * So we hopefully won't need to fork more if we count it. * This depends on the ordering of SERVER_READY and SERVER_STARTING. */ if (status <= SERVER_READY && status != SERVER_DEAD) { if (status <= SERVER_READY && status != SERVER_DEAD && ps->generation == ap_my_generation && /* XXX the following shouldn't be necessary if we clean up * properly after seg faults, but we're not yet GLA */ ps->pid != 0) { ++idle_thread_count; } } if (any_dead_threads && free_length < idle_spawn_rate) { /* XXX any_dead_threads may not be needed any more GLA */ if (any_dead_threads && free_length < idle_spawn_rate && (!ps->pid /* no process in the slot */ || ps->quiescing)) { /* or at least one is going away */ free_slots[free_length] = i; ++free_length; } Loading Loading @@ -1083,6 +1101,8 @@ static void server_main_loop(int remaining_children_to_start) for (i = 0; i < ap_threads_per_child; i++) ap_update_child_status(child_slot, i, SERVER_DEAD, (request_rec *) NULL); ap_scoreboard_image->parent[child_slot].pid = 0; ap_scoreboard_image->parent[child_slot].quiescing = 0; if (remaining_children_to_start && child_slot < ap_daemons_limit) { /* we're still doing a 1-for-1 replacement of dead Loading Loading
CHANGES +4 −0 Original line number Diff line number Diff line Loading @@ -6,6 +6,10 @@ Changes with Apache 2.0.23 Changes with Apache 2.0.22 *) Fix a problem where the threaded MPM stalls after restarts or segfaults. Also prevent multiple active processes from using the same scoreboard slot. [Greg Ames] *) Apache/Win32 now fills in the service description with Apache's server version string, including loaded and advertised modules. [William Rowe] Loading
include/scoreboard.h +3 −0 Original line number Diff line number Diff line Loading @@ -178,6 +178,9 @@ struct process_score{ pid_t pid; ap_generation_t generation; /* generation of this child */ ap_scoreboard_e sb_type; int quiescing; /* the process whose pid is stored above is * going down gracefully */ }; typedef struct { Loading
server/mpm/threaded/threaded.c +23 −3 Original line number Diff line number Diff line Loading @@ -648,8 +648,15 @@ static void * worker_thread(apr_thread_t *thd, void * dummy) apr_pool_destroy(tpool); ap_update_child_status(process_slot, thread_slot, (dying) ? SERVER_DEAD : SERVER_GRACEFUL, (request_rec *) NULL); dying = 1; apr_lock_acquire(worker_thread_count_mutex); if (!dying) { /* this is the first thread to exit */ if (ap_my_pid == ap_scoreboard_image->parent[process_slot].pid) { /* tell the parent that it may use this scoreboard slot */ ap_scoreboard_image->parent[process_slot].quiescing = 1; } dying = 1; } worker_thread_count--; if (worker_thread_count == 0) { /* All the threads have exited, now finish the shutdown process Loading Loading @@ -900,6 +907,7 @@ static int make_child(server_rec *s, int slot) clean_child_exit(0); } /* else */ ap_scoreboard_image->parent[slot].quiescing = 0; ap_scoreboard_image->parent[slot].pid = pid; return 0; } Loading Loading @@ -961,6 +969,7 @@ static void perform_idle_server_maintenance(void) int i, j; int idle_thread_count; worker_score *ws; process_score *ps; int free_length; int free_slots[MAX_SPAWN_RATE]; int last_non_dead; Loading @@ -985,6 +994,7 @@ static void perform_idle_server_maintenance(void) if (i >= ap_max_daemons_limit && free_length == idle_spawn_rate) break; ps = &ap_scoreboard_image->parent[i]; for (j = 0; j < ap_threads_per_child; j++) { ws = &ap_scoreboard_image->servers[i][j]; status = ws->status; Loading @@ -998,11 +1008,19 @@ static void perform_idle_server_maintenance(void) * So we hopefully won't need to fork more if we count it. * This depends on the ordering of SERVER_READY and SERVER_STARTING. */ if (status <= SERVER_READY && status != SERVER_DEAD) { if (status <= SERVER_READY && status != SERVER_DEAD && ps->generation == ap_my_generation && /* XXX the following shouldn't be necessary if we clean up * properly after seg faults, but we're not yet GLA */ ps->pid != 0) { ++idle_thread_count; } } if (any_dead_threads && free_length < idle_spawn_rate) { /* XXX any_dead_threads may not be needed any more GLA */ if (any_dead_threads && free_length < idle_spawn_rate && (!ps->pid /* no process in the slot */ || ps->quiescing)) { /* or at least one is going away */ free_slots[free_length] = i; ++free_length; } Loading Loading @@ -1083,6 +1101,8 @@ static void server_main_loop(int remaining_children_to_start) for (i = 0; i < ap_threads_per_child; i++) ap_update_child_status(child_slot, i, SERVER_DEAD, (request_rec *) NULL); ap_scoreboard_image->parent[child_slot].pid = 0; ap_scoreboard_image->parent[child_slot].quiescing = 0; if (remaining_children_to_start && child_slot < ap_daemons_limit) { /* we're still doing a 1-for-1 replacement of dead Loading