| 232 | } |
| 233 | |
| 234 | static void* APR_THREAD_FUNC slot_run(apr_thread_t *thread, void *wctx) |
| 235 | { |
| 236 | h2_slot *slot = wctx; |
| 237 | h2_workers *workers = slot->workers; |
| 238 | conn_rec *c; |
| 239 | apr_status_t rv; |
| 240 | |
| 241 | apr_thread_mutex_lock(workers->lock); |
| 242 | slot->state = H2_SLOT_RUN; |
| 243 | ++slot->activations; |
| 244 | APR_RING_ELEM_INIT(slot, link); |
| 245 | for(;;) { |
| 246 | if (APR_RING_NEXT(slot, link) != slot) { |
| 247 | /* slot is part of the idle ring from the last loop */ |
| 248 | APR_RING_REMOVE(slot, link); |
| 249 | --workers->idle_slots; |
| 250 | } |
| 251 | slot->is_idle = 0; |
| 252 | |
| 253 | if (!workers->aborted && !slot->should_shutdown) { |
| 254 | APR_RING_INSERT_TAIL(&workers->busy, slot, h2_slot, link); |
| 255 | do { |
| 256 | c = get_next(slot); |
| 257 | if (!c) { |
| 258 | break; |
| 259 | } |
| 260 | apr_thread_mutex_unlock(workers->lock); |
| 261 | /* See the discussion at <https://github.com/icing/mod_h2/issues/195> |
| 262 | * |
| 263 | * Each conn_rec->id is supposed to be unique at a point in time. Since |
| 264 | * some modules (and maybe external code) uses this id as an identifier |
| 265 | * for the request_rec they handle, it needs to be unique for secondary |
| 266 | * connections also. |
| 267 | * |
| 268 | * The MPM module assigns the connection ids and mod_unique_id is using |
| 269 | * that one to generate identifier for requests. While the implementation |
| 270 | * works for HTTP/1.x, the parallel execution of several requests per |
| 271 | * connection will generate duplicate identifiers on load. |
| 272 | * |
| 273 | * The original implementation for secondary connection identifiers used |
| 274 | * to shift the master connection id up and assign the stream id to the |
| 275 | * lower bits. This was cramped on 32 bit systems, but on 64bit there was |
| 276 | * enough space. |
| 277 | * |
| 278 | * As issue 195 showed, mod_unique_id only uses the lower 32 bit of the |
| 279 | * connection id, even on 64bit systems. Therefore collisions in request ids. |
| 280 | * |
| 281 | * The way master connection ids are generated, there is some space "at the |
| 282 | * top" of the lower 32 bits on allmost all systems. If you have a setup |
| 283 | * with 64k threads per child and 255 child processes, you live on the edge. |
| 284 | * |
| 285 | * The new implementation shifts 8 bits and XORs in the worker |
| 286 | * id. This will experience collisions with > 256 h2 workers and heavy |
| 287 | * load still. There seems to be no way to solve this in all possible |
| 288 | * configurations by mod_h2 alone. |
| 289 | */ |
| 290 | if (c->master) { |
| 291 | c->id = (c->master->id << 8)^slot->id; |
no test coverage detected