Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 15 Nov 1996 17:22:27 -0700 (MST)
From:      Terry Lambert <terry@lambert.org>
To:        jgreco@brasil.moneng.mei.com (Joe Greco)
Cc:        terry@lambert.org, jgreco@brasil.moneng.mei.com, jdp@polstra.com, scrappy@ki.net, hackers@FreeBSD.org
Subject:   Re: Sockets question...
Message-ID:  <199611160022.RAA01874@phaeton.artisoft.com>
In-Reply-To: <199611152300.RAA29354@brasil.moneng.mei.com> from "Joe Greco" at Nov 15, 96 05:00:53 pm

next in thread | previous in thread | raw e-mail | index | archive | help
> > He uses a native aiowrite().
> 
> Which doesn't exist in a portable fashion.  ANYWHERE.

[ ... ]

> Which is fine IF you have a threads implementation.  Which is, again, not
> a given, and therefore, not portable.

Well, maybe he should be using send(2) instead of write(2).


> So?  Making things more complex is a small tradeoff if it makes it POSSIBLE
> to do something in the first place.
> 
> Tell me, how else do you do this on a system that does NOT support threads?

I port sigsched.

> You can select() on writability and send one byte at a time on a blocking
> socket until select() reports no further writability.  Poor solution.

Or you can use send(2), whose semantics aren't required to match those
of write(2).

> I am simply correcting a misconception that you are spreading that
> non-blocking sockets are a "stupid idea".

Maybe I should correct it to be "a stupid idea in conjunction with write(2)".

> I am not going to argue with the design and implementation of the Berkeley
> networking code, since it is widely considered to be the standard model
> for networking.  Most other folks have not found this to be a critical
> design flaw, and neither do I.  I can see several cases where a blocking
> read() call would be a substantial nuisance, and so I think that the
> behaviour as it exists makes a fair amount of sense.

So use recv(2), whose semantics are not required to match those of read(2).

> > If I wrote a library function which operated on a nonu user-opaque
> > object like a socket set up by the user, then it would function for
> > all potential valid states in which that object could be at the time
> > of the call.  For potential invalid states, I would trap the ones
> > which I could identify from subfunction returns, and state that the
> > behaviour for other invalid states was "undefined" in the documentation
> > which I published with the library (ie: optimise for the success case).
> 
> What do you define "potential valid states" to be?

Object (in this case, file descriptor) states which I claim to
support with the routine.

> I do not claim to cover all the bases all the time, but I do at least
> catch exceptional conditions I was not expecting.  In my case, I would
> try to write a socket-handling library function to handle both blocking 
> and non-blocking sockets if it was reasonably practical to do so.  If
> not, I would cause it to bomb if it detected something odd.
> 
> I think you are saying the same thing: that is good.

Yes, I'm saying the same thing.


> My UNIX kernel panicks when it hits a condition that it does not know how
> to handle.  It does not foolishly take your advice and "do not test for
> an error condition which you can not handle".  To do so would risk great
> havoc.  You ALWAYS test for error conditions, PARTICULARLY the ones which
> you can not handle - because they are the really scary ones.

This is a different issue than a user program.  A UNIX kernel can not
"fail gracefully to caller"; a program can.

A UNIX kernel should be engineered such that it is impossible to cause
a state transition into a failure state in the first place.  That's
my whole FS layering argument in a nutshell.  It applies equally well
to all other potential failure cases, with the sole exception of a
hardware failure (the only valid panic case outside a developement
environment, where panic is a runtime check for code that is being
tested).


As far as adulterating expected behaviour: if I read from a serial
port (which is at least as likely to have partial data available as
a socket), the read does not complete until the requested data has
been read or an error condition or external event (signal) intervenes.
If you want to adulterate this as a default, call your function recv
instead.


					Terry Lambert
					terry@lambert.org
---
Any opinions in this posting are my own and not those of my present
or previous employers.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199611160022.RAA01874>