You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Dean Gaudet <dg...@arctic.org> on 1998/05/25 09:25:06 UTC

layered i/o and coprocesses

Another thing which may have been obvious to others but only occured to me
recently... (hey I was doing a lot of hiking, lots of time to think).

It's not trivial to turn mod_include into a filter.  mod_include is
written by assuming that it is the only thread of control, it's written in
a serial programming model.  That's fine, it's way easier to understand
that way.  But when you try to turn it into a filter you realise that you
need some way to "block" waiting for the writer to feed it more data, and
some way to "block" waiting for the reader to empty its buffers... 

One way to do this is to implement a layer such as mod_include in another
thread and just flip back and forth between threads as needed.  This is
typically called "coprocessing" and can actually be done with a lot less
overhead... but we should probably just start off doing it as threads and
optimize it to coprocessing later. 

I did this stuff for a C preprocessor prototype at one point... we wanted
to write the preprocessor as if it were a single threaded process in a
pipeline, but we were working under DOS where multiprocessing pipelines
don't exist.  The compiler was also written as if it were the single
thread of control.  When the compiler's input routine emptied its buffer,
it would longjmp() into the preprocessor's "output" routine.  Then the
preprocessor would be in control, and eventually would fill its output
buffer, and longjmp() back to the compiler's input routine.  Neither of
them really knew the longjmp() was there, it was as if they were blocked
reading or writing a pipe.  It requires some creativity to get the first
setjmp()s done to initialize the "processes". 

Dean



Re: layered i/o and coprocesses

Posted by Ben Laurie <be...@algroup.co.uk>.
Dean Gaudet wrote:
> I did this stuff for a C preprocessor prototype at one point... we wanted
> to write the preprocessor as if it were a single threaded process in a
> pipeline, but we were working under DOS where multiprocessing pipelines
> don't exist.  The compiler was also written as if it were the single
> thread of control.  When the compiler's input routine emptied its buffer,
> it would longjmp() into the preprocessor's "output" routine.  Then the
> preprocessor would be in control, and eventually would fill its output
> buffer, and longjmp() back to the compiler's input routine.  Neither of
> them really knew the longjmp() was there, it was as if they were blocked
> reading or writing a pipe.  It requires some creativity to get the first
> setjmp()s done to initialize the "processes".

This is exactly what was under the hood of RST's threading. "Some
creativity" means, on some systems, actually hacking the jmp_buf - SCO,
for example, detects that you are trying to pull a fast one if you do it
the cunning way.

And yeah, when we were discussing all this a year or two ago, it was
precisely the nasty "inside-outness" of the simple model that I was
trying to avoid (i.e. one thread write()s and the other read()s as if
there were a pipe between them. This is not the most efficient model,
but it sure as hell opens it up to more programmers...). I'd suggest we
support both - I seem to remember it is possible to write the "threaded
pipe" as a layer/thread itself, which can be inserted into layered i/o
(sort of) when needed and left out if people can be bothered to write it
the hard way. Hmmm ... not sure I'm expressing myself very clearly here.
Let me know if this reads like Greek!

Cheers,

Ben.

-- 
Ben Laurie            |Phone: +44 (181) 735 0686|  Apache Group member
Freelance Consultant  |Fax:   +44 (181) 735 0689|http://www.apache.org
and Technical Director|Email: ben@algroup.co.uk |
A.L. Digital Ltd,     |Apache-SSL author    http://www.apache-ssl.org/
London, England.      |"Apache: TDG" http://www.ora.com/catalog/apache