Checkout Tools
  • last updated 1 hour ago
Constraints: committers
Constraints: files
Constraints: dates
Follow up to r1879449: yet better MPM poll callback API.

Let pass a const pfds to the MPM, for it to make a copy on the given pool

as needed.

  1. … 6 more files in changeset.
mpm_common: add pool argument to mpm_register_poll_callback[_timeout] hooks.

This is cleaner API than using pfds->pool implicitely.

MAJOR bump but reusing the existing hooks (with an API/ABI breakage) because

it's trunk material only.

  1. … 6 more files in changeset.
mpm_common: remove ap_mpm_unregister_poll_callback().

It's now called automatically by mpm_event and anyway can't be called safely

outside the MPM code without racing.

MAJOR bump.

  1. … 5 more files in changeset.
mpm_event: poll callbacks fixes and improvements.


Rename "remove" field to "pfds" in timer_event_t.



New helper to update pfd->reqevents according to the given cs->sense

for CONN_STATE_WRITE_COMPLETION, reusable in process_socket() and



Process lingering close if given cs->state = CONN_STATE_LINGER.

Call notify_suspend() before entering CONN_STATE_WRITE_COMPLETION.


Don't poll pfds with reqevents == 0.


Run event_cleanup_poll_callback to both remove the registered pfds

and leave pfds->pool in a consistent state.

Process users callabacks after all PT_USER batons have been collected

in the result pfds loop, otherwise we might race with the callbacks

within the loop if multiple events/sockets concern the same baton, and

crash if pfds->pool is cleared.

  1. … 1 more file in changeset.
mpm_event: reset listener_is_wakeable on reload.
* server/mpm/prefork/prefork.c (prefork_pre_config): Use pconf as

passed to the hook with ap_fatal_signal_child_setup, since

prefork.c's pconf "global" is not set until the (later) open_logs

hook, and if built as a DSO it may be reset inbetween.

* server/mpm/motorz/motorz.c (motorz_pre_config): Likewise.

[event and worker do not appear to have the same issue]

Add missing pool tags to help debugging.
  1. … 38 more files in changeset.
malloc -> ap_malloc

bz #63967

mpm_event: avoid possible KeepAlveTimeout off by -100 ms.

Use TIMEOUT_FUDGE_FACTOR to limit wakeups from queues_next_expiry, yet consider

the current/unfudged timestamp to process/cleanup the queues (once woken up).

  1. … 1 more file in changeset.
convert malloc(3) into ap_malloc

bz 64049

  1. … 4 more files in changeset.
Follow up to r1874055: fix typo.

Avoid UBSan exception calling memcpy(,NULL,0) at startup.

Follow-up to r1874011 which did the same for the event MPM.

* server/mpm/event/event.c (event_open_logs): Avoid UBSan exception

calling memcpy(,NULL,0) at startup. Thanks to rpluem.

Fix spelling errors found by codespell. [skip ci]

  1. … 92 more files in changeset.
In winnt_accept() (server/mpm/winnt/child.c), there's a call to PostQueuedCompletionStatus() with a buffer (BytesRead) for the number of bytes read.

When compiling the code with Visual Studio 2019 (v 16.3.10), we get a warning than BytesRead is not initialized. When using /RTCu (run-time checks for uninitialzed variables), the program crashes on this line with an exception.

If we initialize the variable to 0, the problem is solved.

PR 63965

Synch 2.4 and trunk.

Remove an empty line that must have been missed in a backport.

*) mod_http2/mpm_event: Fixes the behaviour when a HTTP/2 connection has nothing

more to write with streams ongoing (flow control block). The timeout waiting

for the client to send WINODW_UPDATE was incorrectly KeepAliveTimeout and not

Timeout as it should be. Fixes PR 63534. [Yann Ylavic, Stefan Eissing]

  1. … 3 more files in changeset.
MPMs unix: bind the bucket number of each child to its slot number

We need not remember each child's bucket number in SHM for restarts, for the

lifetime of the httpd main process the bucket number can be bound to the slot

number such that: bucket = slot % num_buckets.

This both simplifies the logic and helps children maintenance per bucket in

threaded MPMs, where previously perform_idle_server_maintenance() could create

or kill children processes for the buckets it was not in charge of.

  1. … 2 more files in changeset.
mpm_event: avoid AH00484 with idle threads

mpm_event: Stop issuing AH00484 "server reached MaxRequestWorkers..." when

there are still idle threads available. When there are less idle threads than

MinSpareThreads, issue new one-time message AH10159. Matches worker MPM.

  1. … 2 more files in changeset.
MPMs: early initialize scoreboard's child generation number.

Since [mpm]_note_child_killed uses the scoreboard's generation number for

child_status hook (MPM_CHILD_EXITED), we must initialize it early (i.e. in

[mpm]_note_child_started where MPM_CHILD_STARTED is set) to avoid race

conditions on restart (e.g. storm/loop of restarts) leading to AH00546.

PR 62658.

Axe some redundant conditions. PR 62549.

  1. … 5 more files in changeset.
event, worker: follow up to r1835845, r1837354: pruntime is global now.

event, worker: initialize the objects used by signal_threads() first.

Follow up to r1835845.

If a signal is received early when the MPM children start, signal_threads() may

be called concurrently with start_streads() thus before the latter (or its

underlying threads like the listener_thread) had a chance to create and init

the queues, mutexes, pollset and sockets array used by the former.

So move those initializations to a new setup_threads_runtime() function called

before start_threads(), where the pruntime pool is also created.

core: axe data_in_in/output_filter from conn_rec.

They were superseded by ap_filter_should_yield() and ap_run_in/output_pending()

in r1706669 and had poor semantics since then (we can't maintain pending

semantics both by filter and for the whole connection).

Register ap_filter_input_pending() as the default input_pending hook (which

seems to have been forgotten in the first place).

On the MPM event side, we don't need to flush pending output data when the

connection has just been processed, ap_filter_should_yield() is lightweight and

enough to determine whether we should really enter write completion state or go

straight to reading. ap_run_output_pending() is used only when write completion

is in place and needs to be completed before more processing.

  1. … 6 more files in changeset.
core: integrate data_in_{in,out}put_filter to ap_filter_{in,out}put_pending().

Straightforward for ap_filter_input_pending() since c->data_in_input_filter is

always checked wherever ap_run_input_pending(c) is.

For ap_filter_output_pending(), this allows to set c->data_in_output_filter in

ap_process_request_after_handler() and avoid an useless flush from mpm_event.

  1. … 3 more files in changeset.
event: follow up to r1835845.

Always favor APR_POLLSET_WAKEABLE over method/implementation.

Probably more about correctness than a real issue since systems are

unlikely to implement more than one/their method...

This also makes use of pruntime for event_pollset (an oversight from r1835845).

event, worker: runtime pool.

MPMs event and worker both need a dedicated pool to handle the creation of

the threads (listener, workers) and synchronization objects (queues, pollset,

mutexes...) in the start_threads() thread, with at least the lifetime of

the connections they handle, and thus survive pchild destruction (notably

in ONE_PROCCESS mode, but SIG_UNGRACEFUL is concerned too).

For instance, without this fix, the below backtrace can happen in ONE_PROCCESS

mode and a signal/^C is received (with active connections):

Thread 1 "httpd" received signal SIGSEGV, Segmentation fault.

(gdb) bt

#0 <BOOM>

#1 0x00007ffff7c7e016 in apr_file_write (thefile=0x0, ...)

^ NULL (cleared)

at file_io/unix/readwrite.c:230

#2 0x00007ffff7c7e4a7 in apr_file_putc (ch=1 '\001', thefile=0x0)

^ NULL (cleared)

at file_io/unix/readwrite.c:377

#3 0x00007ffff7c8da4a in apr_pollset_wakeup (pollset=0x55555568b870)

^ already destroyed by pchild

at poll/unix/pollset.c:224

#4 0x00007ffff7fc16c7 in decrement_connection_count (cs_=0x7fff08000ea0)

at event.c:811

#5 0x00007ffff7c83e15 in run_cleanups (cref=0x7fffe4002b78)

at memory/unix/apr_pools.c:2672

#6 0x00007ffff7c82c2f in apr_pool_destroy (pool=0x7fffe4002b58)

^ master_conn

at memory/unix/apr_pools.c:1007

#7 0x00007ffff7c82c12 in apr_pool_destroy (pool=0x7fff08000c28)

^ ptrans

at memory/unix/apr_pools.c:1004

#8 0x00007ffff7c82c12 in apr_pool_destroy (pool=0x555555638698)

^ pconf

at memory/unix/apr_pools.c:1004

#9 0x00007ffff7c82c12 in apr_pool_destroy (pool=0x555555636688)

^ pglobal

at memory/unix/apr_pools.c:1004

#10 0x00005555555f4709 in ap_terminate ()

at unixd.c:522

#11 0x00007ffff6dbc8f1 in __run_exit_handlers (...)

at exit.c:108

#12 0x00007ffff6dbc9ea in __GI_exit (status=<optimized out>)

at exit.c:139

#13 0x00007ffff7fc1616 in clean_child_exit (code=0)

at event.c:774

^ pchild already destroyed here

#14 0x00007ffff7fc5ae4 in child_main (child_num_arg=0, child_bucket=0)

at event.c:2869


While at it, add comments about the lifetimes of MPMs pools and their objects,

and give each pool a tag (e.g. "pchild" accordingly to other MPMs).

(follow up for event_pollset in r1835846).

mpm_event: follow up to r1823047 and r1824862.

Revert (broken) functional change from r1824862.

mpm_event: follow up to r1823047 and r1824464.

MMN bump for CONN_STATE_NUM, plus don't consider CONN_STATE_LINGER_* as valid

states returned process_connection (never have been).

  1. … 1 more file in changeset.
mpm_event: follow up to r1823047: complete state validation after processing.

  1. … 1 more file in changeset.