Hi Alex,

>> > Not necessarily. If we use the select() mechanism provided by '*Run'
>> > and 'task', you can make input operations like 'listen', 'accept',
>> > 'read', 'rd' etc. non-blocking.

select() does not make thinks non-blocking as far as I am aware.  It
just wakes up the process when something is going on.

I think that to be non-blocking, all I/O operations must be able to
say how much data to read/write without blocking.

> I posted some examples in my initial response to Konrad yesterday
>                (if (rd)                   # read them
>                   (out Sock (eval @))     # Do something with the data

I think these two lines are the problematic ones.

> I have this mechanism very often for communication between different
> systems. For communication with a browser you would better use (line)
> instead of (rd), and send HTML-data instead of (eval @).

Does not (line) try to read until eol or eof?  That could block if the
client is "naughty" or something happens (like delay while receiving
the line and being in the middle of it).  Also,
http://www.software-lab.de/refL.html#line says

   Note that a single carriage return may not work on network
   connections, because the character look-ahead to distinguish from
   return+linefeed can block the connection.

>> How would I know that 'read' does not have data available, or only
>> part of the data is available?
> For the above communication between my own machines, I can guarantee
> that no message received with the (rd) is longer than the system pipe
> buffer size (at least 4096 bytes, larger on most systems). In that case
> the (rd) will never block if select() said that data are available.

How can you guarantee that? Simply by sending little data or some
special protocol?

Also, that is a very special case.  I don't think you can make such
assumptions with HTTP server where you don't have the clients under

> If you receive data from a browser, they may be larger. But I think this
> will never make problems if you always read reasonable chunks (e.g.
> chunked transfers, or character by character to be absolutely sure) in a
> single step in the 'task' body. select() will either return immediately
> when more data are available, or will not call the 'task' body, so
> nothing will actually block.

How big is a reasonable chunk?  What if something happens (a delay)
with the client in the middle of sending the chunk?

Would not reading by character loose the magic of striving for
supercalifragilisticexpialidoucious server?;-)

Also, not blocking is only a part of the story, what about
schedulling?  If two people share a computer say with MS-DOS, one must
go for a coffee and wait until the other one finished.  If they use
UNIX, they can work simultaneously because the system splits the time
between them in tiny chunks which they don't notice.  The non-forking
server in picolisp is of the first kind.  Once the server is serving a
request, everything else (all the other requests) have to wait until
it is finished with the current task.



Reply via email to