| 1398 | } |
| 1399 | |
| 1400 | static void perform_idle_server_maintenance(int child_bucket) |
| 1401 | { |
| 1402 | int num_buckets = retained->mpm->num_buckets; |
| 1403 | int idle_thread_count; |
| 1404 | process_score *ps; |
| 1405 | int free_length; |
| 1406 | int totally_free_length = 0; |
| 1407 | int free_slots[MAX_SPAWN_RATE]; |
| 1408 | int last_non_dead; |
| 1409 | int total_non_dead; |
| 1410 | int active_thread_count = 0; |
| 1411 | int i, j; |
| 1412 | |
| 1413 | /* initialize the free_list */ |
| 1414 | free_length = 0; |
| 1415 | |
| 1416 | idle_thread_count = 0; |
| 1417 | last_non_dead = -1; |
| 1418 | total_non_dead = 0; |
| 1419 | |
| 1420 | for (i = 0; i < ap_daemons_limit; ++i) { |
| 1421 | /* Initialization to satisfy the compiler. It doesn't know |
| 1422 | * that threads_per_child is always > 0 */ |
| 1423 | int any_dying_threads = 0; |
| 1424 | int any_dead_threads = 0; |
| 1425 | int all_dead_threads = 1; |
| 1426 | int child_threads_active = 0; |
| 1427 | |
| 1428 | if (num_buckets > 1 && (i % num_buckets) != child_bucket) { |
| 1429 | /* We only care about child_bucket in this call */ |
| 1430 | continue; |
| 1431 | } |
| 1432 | if (i >= retained->max_daemons_limit && |
| 1433 | totally_free_length == retained->idle_spawn_rate[child_bucket]) { |
| 1434 | /* short cut if all active processes have been examined and |
| 1435 | * enough empty scoreboard slots have been found |
| 1436 | */ |
| 1437 | break; |
| 1438 | } |
| 1439 | ps = &ap_scoreboard_image->parent[i]; |
| 1440 | for (j = 0; j < threads_per_child; j++) { |
| 1441 | int status = ap_scoreboard_image->servers[i][j].status; |
| 1442 | |
| 1443 | /* XXX any_dying_threads is probably no longer needed GLA */ |
| 1444 | any_dying_threads = any_dying_threads || |
| 1445 | (status == SERVER_GRACEFUL); |
| 1446 | any_dead_threads = any_dead_threads || (status == SERVER_DEAD); |
| 1447 | all_dead_threads = all_dead_threads && |
| 1448 | (status == SERVER_DEAD || |
| 1449 | status == SERVER_GRACEFUL); |
| 1450 | |
| 1451 | /* We consider a starting server as idle because we started it |
| 1452 | * at least a cycle ago, and if it still hasn't finished starting |
| 1453 | * then we're just going to swamp things worse by forking more. |
| 1454 | * So we hopefully won't need to fork more if we count it. |
| 1455 | * This depends on the ordering of SERVER_READY and SERVER_STARTING. |
| 1456 | */ |
| 1457 | if (ps->pid != 0) { /* XXX just set all_dead_threads in outer for |
no test coverage detected