XXX For ungraceful termination/restart, we definitely don't want to * wait for active connections to finish but we may want to wait * for idle workers to get out of the queue code and release mutexes, * since those mutexes are cleaned up pretty soon and some systems * may not react favorably (i.e., segfault) if operations are attempted * on cleaned-up mutexes. */
| 2155 | * on cleaned-up mutexes. |
| 2156 | */ |
| 2157 | static void *APR_THREAD_FUNC worker_thread(apr_thread_t * thd, void *dummy) |
| 2158 | { |
| 2159 | proc_info *ti = dummy; |
| 2160 | int process_slot = ti->pslot; |
| 2161 | int thread_slot = ti->tslot; |
| 2162 | apr_status_t rv; |
| 2163 | int is_idle = 0; |
| 2164 | |
| 2165 | free(ti); |
| 2166 | |
| 2167 | ap_scoreboard_image->servers[process_slot][thread_slot].pid = ap_my_pid; |
| 2168 | ap_scoreboard_image->servers[process_slot][thread_slot].tid = apr_os_thread_current(); |
| 2169 | ap_scoreboard_image->servers[process_slot][thread_slot].generation = retained->mpm->my_generation; |
| 2170 | ap_update_child_status_from_indexes(process_slot, thread_slot, |
| 2171 | SERVER_STARTING, NULL); |
| 2172 | |
| 2173 | for (;;) { |
| 2174 | apr_socket_t *csd = NULL; |
| 2175 | event_conn_state_t *cs; |
| 2176 | timer_event_t *te = NULL; |
| 2177 | apr_pool_t *ptrans; /* Pool for per-transaction stuff */ |
| 2178 | |
| 2179 | if (!is_idle) { |
| 2180 | rv = ap_queue_info_set_idle(worker_queue_info, NULL); |
| 2181 | if (rv != APR_SUCCESS) { |
| 2182 | ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, |
| 2183 | "ap_queue_info_set_idle failed. Attempting to " |
| 2184 | "shutdown process gracefully."); |
| 2185 | signal_threads(ST_GRACEFUL); |
| 2186 | break; |
| 2187 | } |
| 2188 | /* A new idler may have changed connections_above_limit(), |
| 2189 | * let the listener know and decide. |
| 2190 | */ |
| 2191 | if (listener_is_wakeable && should_enable_listensocks()) { |
| 2192 | apr_pollset_wakeup(event_pollset); |
| 2193 | } |
| 2194 | is_idle = 1; |
| 2195 | } |
| 2196 | |
| 2197 | ap_update_child_status_from_indexes(process_slot, thread_slot, |
| 2198 | dying ? SERVER_GRACEFUL |
| 2199 | : SERVER_READY, NULL); |
| 2200 | worker_pop: |
| 2201 | if (workers_may_exit) { |
| 2202 | break; |
| 2203 | } |
| 2204 | if (dying && worker_thread_should_exit_early()) { |
| 2205 | break; |
| 2206 | } |
| 2207 | |
| 2208 | rv = ap_queue_pop_something(worker_queue, &csd, (void **)&cs, |
| 2209 | &ptrans, &te); |
| 2210 | |
| 2211 | if (rv != APR_SUCCESS) { |
| 2212 | /* We get APR_EOF during a graceful shutdown once all the |
| 2213 | * connections accepted by this server process have been handled. |
| 2214 | */ |
nothing calls this directly
no test coverage detected