* During graceful shutdown, if there are more running worker threads than * open connections, exit one worker thread. * * return 1 if thread should exit, 0 if it should continue running. */
| 2126 | * return 1 if thread should exit, 0 if it should continue running. |
| 2127 | */ |
| 2128 | static int worker_thread_should_exit_early(void) |
| 2129 | { |
| 2130 | for (;;) { |
| 2131 | apr_uint32_t conns = apr_atomic_read32(&connection_count); |
| 2132 | apr_uint32_t dead = apr_atomic_read32(&threads_shutdown); |
| 2133 | apr_uint32_t newdead; |
| 2134 | |
| 2135 | AP_DEBUG_ASSERT(dead <= threads_per_child); |
| 2136 | if (conns >= threads_per_child - dead) |
| 2137 | return 0; |
| 2138 | |
| 2139 | newdead = dead + 1; |
| 2140 | if (apr_atomic_cas32(&threads_shutdown, newdead, dead) == dead) { |
| 2141 | /* |
| 2142 | * No other thread has exited in the mean time, safe to exit |
| 2143 | * this one. |
| 2144 | */ |
| 2145 | return 1; |
| 2146 | } |
| 2147 | } |
| 2148 | } |
| 2149 | |
| 2150 | /* XXX For ungraceful termination/restart, we definitely don't want to |
| 2151 | * wait for active connections to finish but we may want to wait |