Hi Alex and John,

>> The comment is a bit misleading as it does not prevent blocking
>> really.  The data might be available but the 'read' function might
>> still block.
> Yes, all those comments regarding non-blocking (also in the way
> Konrad used it) mean that during normal operations (i.e. not hanging
> in an error condition) everything will go smoothly. It does not mean
> "non-blocking" in the technical sense. But for those "normal"
> operations, it goes surprisingly well when messages observe the
> PIPE_BUF limit. So the *application* is non-blocking, not the
> underlying protocol. Without *Run and (poll) the input would always
> block even on a single input channel.

I understand your interpretation.  However, there is a huge difference
in consequences:

1) If you have a server with separate processes for each request or
session, it is not such a big deal if one client hangs (and eventually

2) If you have a server with single process though (no threads),
anything that causes blocking makes the server completely useless.  In
this case, the only operation that is allowed and intended to block is
the select() syscall (task or *Run thingy in picolisp).

So, your interpretation is fine for the first case but I don't think
it is acceptable for the second case.

>> So the poll will still be useful in an nbio world.
> Yep.

No, poll is useful if your i/o operations block.  The you can use the

  : (and (poll *Fd) (in @ (read)))  # Prevent blocking

"trick" if you are aware of the consequences and are happy with them
for your particular application (the first case).

If you have "real" non-blocking i/o operations, then poll is kind of
"built in".  If you have a look at the example I sent, there is no
poll simply because the same functionality is provided directly by the
rdx and wrx functions.

>> If the socket is set not to block, then the socket will read as
>> much data as is available and the underlying read call will return
>> the number of bytes read, right?
> Yes, but in blocking mode it will also read only as many bytes as
> are available.
> So there is not really a fundamental difference between the
> capabilities of blocking and nonblocking sockets, when select() is
> used.
> But nonblocking mode has a few advantages in pathological
> situations.

I think the difference is much bigger than you admit.  It is actually
two different worlds, Venus and Mars;-) It is not a matter of setting
a block/no-block flag on a file descriptor, it is a matter of
switching to completely different kind of thinking and implementing
things.  That's why Alex's experiment did not turn out well.  See his
post: completely different flow required...or something like that.

It is not so much the low level read function but the control flow and
other higher level i/o functions.  For example the picolisp (read)
function which reads an arbitrary Lisp expression would have to be
completely rewriten to work in a single process/thread server.  The
same goes for (most of) the rest of picolisp.  It just was not
designed for that.

One of the reasons we have processes provided for us in operating
systems is that we can write nice, "simple" sequential programs.  The
ugly details or "event-driven/unnatural thinking" are abstracted away.
If you do not want to use processes, you have to switch to different
kind of thinking and write completely different code.

Also again, select() is not about blocking but about events.



Reply via email to