mod_http2: Fix workers synchronization on pchild cleanup.
When the MPM child exits and pre-workers_pool_cleanup() is called, all the
workers are are necessarily in their idle critical section, thus aborting slots
in the ->idle list only may leave worker threads alive, later blocked in the
idle critical section with no one to wake them.
Instead of the per-slot ->aborted flag, workers_pool_cleanup() will now set
workers->aborted "globally" such that slot_run() does not wait to be woken up
from idle in this case, and all workers really exit.
Also, for workers_pool_cleanup() to wait for all the workers to reach the
->zombies list before returning, a new ->all_done condition variable is armed
when the last thread exits. Since this depends on the atomic ->worker_count to
reach zero, for accuracy the increment in activate_slot() is moved before the
thread startup.
* modules/http2/h2_workers.h (struct h2_workers): volatilize ->aborted and
add the ->all_done condition variable.
* modules/http2/h2_workers.c (push_slot, pop_slot): volatilize the h2_slot*
being cas-ed.
* modules/http2/h2_workers.c (cleanup_zombies): rename to join_zombies(), and
move ->worker_count atomic inc to slot_done().
* modules/http2/h2_workers.c (get_next): when workers->aborted, leave and don't
wait for ->not_idle. Return an int/bool since it's gotten / not gotten.
* modules/http2/h2_workers.c (slot_done): signal ->all_done when the last
worker and the MPM child are exiting.
* modules/http2/h2_workers.c (slot_run): rework the loops now that get_next()
is the stop signal.
* modules/http2/h2_workers.c (workers_pool_cleanup): wait for ->all_done when
needed, and remove the !workers->aborted condition since the cleanup will
only be called once.
* modules/http2/h2_workers.c (activate_slot): move ->worker_count atomic inc
before the thread creation and handle failure rollback.
github: closes #169
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@
1886255 13f79535-47bb-0310-9956-
ffa450edef68