get_worker: * If *have_idle_worker_p == 0, reserve a worker thread, and set * *have_idle_worker_p = 1. * If *have_idle_worker_p is already 1, will do nothing. * If blocking == 1, block if all workers are currently busy. * If no worker was available immediately, will set *all_busy to 1. * XXX: If there are no workers, we should not block immediately but * XXX: clo
| 1411 | * XXX: close all keep-alive connections first. |
| 1412 | */ |
| 1413 | static void get_worker(int *have_idle_worker_p, int blocking, int *all_busy) |
| 1414 | { |
| 1415 | apr_status_t rc; |
| 1416 | |
| 1417 | if (*have_idle_worker_p) { |
| 1418 | /* already reserved a worker thread - must have hit a |
| 1419 | * transient error on a previous pass |
| 1420 | */ |
| 1421 | return; |
| 1422 | } |
| 1423 | |
| 1424 | if (blocking) |
| 1425 | rc = ap_queue_info_wait_for_idler(worker_queue_info, all_busy); |
| 1426 | else |
| 1427 | rc = ap_queue_info_try_get_idler(worker_queue_info); |
| 1428 | |
| 1429 | if (rc == APR_SUCCESS || APR_STATUS_IS_EOF(rc)) { |
| 1430 | *have_idle_worker_p = 1; |
| 1431 | } |
| 1432 | else if (!blocking && rc == APR_EAGAIN) { |
| 1433 | *all_busy = 1; |
| 1434 | } |
| 1435 | else { |
| 1436 | ap_log_error(APLOG_MARK, APLOG_ERR, rc, ap_server_conf, APLOGNO(00472) |
| 1437 | "ap_queue_info_wait_for_idler failed. " |
| 1438 | "Attempting to shutdown process gracefully"); |
| 1439 | signal_threads(ST_GRACEFUL); |
| 1440 | } |
| 1441 | } |
| 1442 | |
| 1443 | /* Structures to reuse */ |
| 1444 | static timer_event_t timer_free_ring; |
no test coverage detected