Log Message: |
mpm_event: Fix queues' maintenance and linger timeouts on graceful restart/stop
* server/mpm/event/event.c (abort_socket_nonblocking): Renamed to
close_socket_nonblocking_() with close_socket_nonblocking() as a macro to
APLOG_TRACE8 the caller __FUNCTION__ and __LINE__. Do nothing if the socket
is closed already, e.g. from close_worker_sockets().
* server/mpm/event/event.c (close_worker_sockets): Let defer_linger_chain be
cleaned by the terminating workers.
* server/mpm/event/event.c (wakeup_listener): Add a trace8 of the call.
* server/mpm/event/event.c (decrement_connection_count): Add a trace8 of the
call, decrement lingering_count from CONN_STATE_LINGER too which may happen
from start_lingering_close_blocking() on ap_start_lingering_close() failure,
and when dying call ap_queue_interrupt_one() from there instead of
close_connection() so that we don't miss a worker_thread_should_exit_early()
case.
* server/mpm/event/event.c (start_lingering_close_blocking): Don't increment
lingering_count when it's already done by defer_lingering_close() (i.e.
cs->deferred_linger is set), set socket timeout to 2s (SECONDS_TO_LINGER)
before pre_close hooks and then after let socket timeout handling to
process_lingering_close().
* server/mpm/event/event.c (start_lingering_close_nonblocking): Rename to
defer_lingering_close(), add trace6 of the call, set CONN_STATE_LINGER so
that the connection is accounted for until handled by a worker, and let
start_lingering_close_blocking() know by setting cs->deferred_linger.
* server/mpm/event/event.c (stop_lingering_close): Rename to close_connection()
and log the call at trace6 level instead of trace4 (for consistency), and use
it everywhere apr_socket_close()+ap_queue_info_push_pool() is open coded.
* server/mpm/event/event.c (shutdown_connection): This helper can be called
anywhere where nonblocking is required to either initiate short lingering
close or directly close if the connection is lingering already. It's used
as a generic process_timeout_queue() callback to terminate expired entries
in any state.
* server/mpm/event/event.c (update_reqevents_from_sense): Allow to specify the
sense as argument where -1 means cs->pub.state as before, and call it from
everywhere before adding to the pollset such that APR_POLL* events are set
fully/appropritely regardless of the underlying pollset implementation.
* server/mpm/event/event.c (process_socket): Gracefuly stop the process on
pollset errors, and don't forcibly close the connection if listener_may_exit
when ap_run_input_pending() determines that the next request is already here.
* server/mpm/event/event.c (close_listeners): Add trace6 of the call, and
return whether it's the first close or not.
* server/mpm/event/event.c (push2worker): Call shutdown_connection() on failure
when cs is available so that pre_close hooks (h2 flush, ssl close notify) are
still called.
* server/mpm/event/event.c (process_lingering_close): Add trace6 of the call,
always set timeout to zero (hence nonblocking) before reading pending data,
and terminate the process gracefuly on pollset errors.
* server/mpm/event/event.c (listener_thread): Add some trace7 messages around
poll()ing for debug, round poll()ing timeout to the upper millisecond to work
around the rounding down done by some pollset implementations, and on the
first call to close_listeners() when listener_may_exit->dying let's force the
maintenance of the queues to kill keep alive connections and apply shorter
lingering close timeout to free worker threads faster for the next generation.
* server/mpm/event/event.c (join_workers): Rewrite the !dying loop to avoid
"listener has not stopped accepting yet" if sleeping 500ms once did it.
Github: #208
|