| 154 | } |
| 155 | |
| 156 | static void join_zombies(h2_workers *workers) |
| 157 | { |
| 158 | h2_slot *slot; |
| 159 | apr_status_t status; |
| 160 | |
| 161 | while (!APR_RING_EMPTY(&workers->zombie, h2_slot, link)) { |
| 162 | slot = APR_RING_FIRST(&workers->zombie); |
| 163 | APR_RING_REMOVE(slot, link); |
| 164 | ap_assert(slot->state == H2_SLOT_ZOMBIE); |
| 165 | ap_assert(slot->thread != NULL); |
| 166 | |
| 167 | apr_thread_mutex_unlock(workers->lock); |
| 168 | apr_thread_join(&status, slot->thread); |
| 169 | apr_thread_mutex_lock(workers->lock); |
| 170 | |
| 171 | slot->thread = NULL; |
| 172 | slot->state = H2_SLOT_FREE; |
| 173 | if (slot->pool) { |
| 174 | apr_pool_destroy(slot->pool); |
| 175 | slot->pool = NULL; |
| 176 | } |
| 177 | APR_RING_INSERT_TAIL(&workers->free, slot, h2_slot, link); |
| 178 | } |
| 179 | } |
| 180 | |
| 181 | static void wake_idle_worker(h2_workers *workers, ap_conn_producer_t *prod) |
| 182 | { |
no outgoing calls
no test coverage detected