> Am 20.09.2021 um 11:17 schrieb ste...@eissing.org:
>
>
>
>> Am 14.09.2021 um 13:43 schrieb Ruediger Pluem <rpl...@apache.org>:
>>
>> When looking at this again while researching something I couldn't answer
>> myself the questions below
>> and as event mpm and mod_http2 are sometimes pretty complex I thought I ask
>> :-)
>>
>> On 7/3/19 3:46 PM, ic...@apache.org wrote:
>>> Author: icing
>>> Date: Wed Jul 3 13:46:31 2019
>>> New Revision: 1862475
>>>
>>> URL: http://svn.apache.org/viewvc?rev=1862475&view=rev
>>> Log:
>>> *) 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]
>>>
>>>
>>> Modified:
>>> httpd/httpd/trunk/CHANGES
>>> httpd/httpd/trunk/modules/http2/h2_conn.c
>>> httpd/httpd/trunk/modules/http2/h2_version.h
>>> httpd/httpd/trunk/server/mpm/event/event.c
>>>
>>
>>> Modified: httpd/httpd/trunk/modules/http2/h2_conn.c
>>> URL:
>>> http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_conn.c?rev=1862475&r1=1862474&r2=1862475&view=diff
>>> ==============================================================================
>>> --- httpd/httpd/trunk/modules/http2/h2_conn.c (original)
>>> +++ httpd/httpd/trunk/modules/http2/h2_conn.c Wed Jul 3 13:46:31 2019
>>> @@ -231,6 +231,13 @@ apr_status_t h2_conn_run(conn_rec *c)
>>> case H2_SESSION_ST_BUSY:
>>> case H2_SESSION_ST_WAIT:
>>> c->cs->state = CONN_STATE_WRITE_COMPLETION;
>>> + if (c->cs && (session->open_streams ||
>>> !session->remote.emitted_count)) {
>>> + /* let the MPM know that we are not done and want
>>> + * the Timeout behaviour instead of a KeepAliveTimeout
>>> + * See PR 63534.
>>> + */
>>> + c->cs->sense = CONN_SENSE_WANT_READ;
>>
>> Can we get here with session->open_streams > 0 and all the open streams are
>> only producing output and none of them is waiting for
>> something from the client?
>
> Yes, but only when the HTTP/2 flow control blocks any progress. New data has
> to arrive from the client before the server is able to send more. So, we are
> waiting for new data from the client in the form of window updates.
>
>>> + }
>>> break;
>>> case H2_SESSION_ST_CLEANUP:
>>> case H2_SESSION_ST_DONE:
>>>
>>
>>> Modified: httpd/httpd/trunk/server/mpm/event/event.c
>>> URL:
>>> http://svn.apache.org/viewvc/httpd/httpd/trunk/server/mpm/event/event.c?rev=1862475&r1=1862474&r2=1862475&view=diff
>>> ==============================================================================
>>> --- httpd/httpd/trunk/server/mpm/event/event.c (original)
>>> +++ httpd/httpd/trunk/server/mpm/event/event.c Wed Jul 3 13:46:31 2019
>>> @@ -1153,10 +1153,11 @@ read_request:
>>> else if (ap_filter_should_yield(c->output_filters)) {
>>> pending = OK;
>>> }
>>> - if (pending == OK) {
>>> + if (pending == OK || (pending == DECLINED &&
>>> + cs->pub.sense == CONN_SENSE_WANT_READ)) {
>>> /* Still in WRITE_COMPLETION_STATE:
>>> - * Set a write timeout for this connection, and let the
>>> - * event thread poll for writeability.
>>> + * Set a read/write timeout for this connection, and let the
>>> + * event thread poll for read/writeability.
>>> */
>>> cs->queue_timestamp = apr_time_now();
>>> notify_suspend(cs);
>>
>> Hm. Showing following code lines from trunk for my next question:
>>
>>
>> update_reqevents_from_sense(cs, -1);
>>
>> if cs->pub.sense == CONN_SENSE_WANT_READ we subscribe on to POLLIN only on
>> the pfd
>>
>>
>> apr_thread_mutex_lock(timeout_mutex);
>> TO_QUEUE_APPEND(cs->sc->wc_q, cs);
>> rv = apr_pollset_add(event_pollset, &cs->pfd);
>>
>> If the read event triggers we will get back to the
>>
>> if (cs->pub.state == CONN_STATE_WRITE_COMPLETION) {
>> int pending = DECLINED;
>>
>> above. This means we try flush the output queue if it is not empty and if it
>> is empty after this we would fall through to
>> set cs->pub.state = CONN_STATE_CHECK_REQUEST_LINE_READABLE; and then add the
>> pfd to the pollset again and poll again. This should
>> trigger the read event again and we would process the input. But if I see
>> this correctly we would need to poll twice for getting
>> the read data processed.
>> OTOH if we do not manage to clear the output queue above we would add the
>> pfd to the pollset again but this time for writing and
>> only once all output has been processed we would take care of the reading.
>> Maybe we should take care of both?
>
> Hmm, but can it? In my understanding CONN_STATE_WRITE_COMPLETION is intended
> to flush the out buffers before putting in new work.
>
> Since conn_rec's are limited to be processes in one thread-at-a-time only,
> POLLIN would call process_connection and that alone would block any
*processed
> more processing of the connection's output. Or?
>
> Cheers, Stefan