On 12 Mar 2016, at 6:26 PM, Eric Covener <cove...@gmail.com> wrote:

> Very cool stuff. Only looked on the surface so far, but one thing it
> reminded me of in the async case is that the MPM knows the "suspended"
> count but we never gave an API to really "unsuspend" when using a
> timed or socket callback.  Longer term we really need to find a way to
> share that raw forwarding code as it's now probably in three modules.

I am slowly working through this, teasing out each problem that prevents async 
behaviour.

A key part of mod_tcp is the “switch ladder”, which allows 
tcp_process_connection() to exit at any time and be called again, at which 
point it will continue where it left off. We need corresponding ladders deeper 
into the core to make each layer down able to continue where it left off if it 
got EAGAIN. We also need to fix some of the function signatures - 
ap_process_request() is void, and so cannot signal to us elegantly that it 
wants to be called again, or whether it is done and we can move on.

Another problem that has become apparent is that the MPMs are too limiting with 
respect to the events the core is willing to wait on. Right now the only event 
the core will handle for us is to wait for the underlying socket to be 
readable/writable. What I have in mind is a more general mechanism, where 
instead of “one socket” we have “a stack of sockets/pipes/files[1]”, and the 
event we wait for is the socket/pipe/file on the top of the stack. This gives 
us AND behaviour. If browser socket is writable AND backend socket is readable 
then [do stuff].

To state it another way, we wait for the browser socket to be writable, this 
triggers the normal pattern of events until we need to block on something else, 
for example we might block waiting for the backend proxy socket to be readable. 
That socket is added to the stack and the MPM now waits for that event. When 
that event triggers the top of the stack is popped off and we’re back to 
waiting on the underlying event (the socket).

I just need to find an elegant way to trigger all of this. It would be really 
nice if we had SOCKET, PIPE, FILE (etc) buckets that pushed themselves onto 
this stack as soon as they returned EAGAIN via some kind of callback.

I need to think this through to work out how to incorporate OR into this. 
Perhaps a list of stacks. This would allow a set of read events to run 
concurrently with write events. Then the sense of the connection has to be 
worked into it too so mod_ssl works non blocking.

[1] files are typically not pollable, but we shouldn't restrict our API. It’s 
pipes we want to block on and in our world that’s apr_file_t.

Regards,
Graham
—

Reply via email to