| 106 | static void* APR_THREAD_FUNC slot_run(apr_thread_t *thread, void *wctx); |
| 107 | |
| 108 | static apr_status_t activate_slot(h2_workers *workers) |
| 109 | { |
| 110 | h2_slot *slot; |
| 111 | apr_pool_t *pool; |
| 112 | apr_status_t rv; |
| 113 | |
| 114 | if (APR_RING_EMPTY(&workers->free, h2_slot, link)) { |
| 115 | return APR_EAGAIN; |
| 116 | } |
| 117 | slot = APR_RING_FIRST(&workers->free); |
| 118 | ap_assert(slot->state == H2_SLOT_FREE); |
| 119 | APR_RING_REMOVE(slot, link); |
| 120 | |
| 121 | ap_log_error(APLOG_MARK, APLOG_TRACE3, 0, workers->s, |
| 122 | "h2_workers: activate slot %d", slot->id); |
| 123 | |
| 124 | slot->state = H2_SLOT_RUN; |
| 125 | slot->should_shutdown = 0; |
| 126 | slot->is_idle = 0; |
| 127 | slot->pool = NULL; |
| 128 | ++workers->active_slots; |
| 129 | rv = apr_pool_create(&pool, workers->pool); |
| 130 | if (APR_SUCCESS != rv) goto cleanup; |
| 131 | apr_pool_tag(pool, "h2_worker_slot"); |
| 132 | slot->pool = pool; |
| 133 | |
| 134 | #if defined(AP_HAS_THREAD_LOCAL) |
| 135 | rv = ap_thread_create(&slot->thread, workers->thread_attr, |
| 136 | slot_run, slot, slot->pool); |
| 137 | #else |
| 138 | rv = apr_thread_create(&slot->thread, workers->thread_attr, |
| 139 | slot_run, slot, slot->pool); |
| 140 | #endif |
| 141 | |
| 142 | cleanup: |
| 143 | if (rv != APR_SUCCESS) { |
| 144 | AP_DEBUG_ASSERT(0); |
| 145 | slot->state = H2_SLOT_FREE; |
| 146 | if (slot->pool) { |
| 147 | apr_pool_destroy(slot->pool); |
| 148 | slot->pool = NULL; |
| 149 | } |
| 150 | APR_RING_INSERT_TAIL(&workers->free, slot, h2_slot, link); |
| 151 | --workers->active_slots; |
| 152 | } |
| 153 | return rv; |
| 154 | } |
| 155 | |
| 156 | static void join_zombies(h2_workers *workers) |
| 157 | { |
no test coverage detected