From owner-freebsd-hackers Fri Nov 15 16:36:23 1996 Return-Path: owner-hackers Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id QAA29840 for hackers-outgoing; Fri, 15 Nov 1996 16:36:23 -0800 (PST) Received: from phaeton.artisoft.com (phaeton.Artisoft.COM [198.17.250.211]) by freefall.freebsd.org (8.7.5/8.7.3) with SMTP id QAA29835 for ; Fri, 15 Nov 1996 16:36:21 -0800 (PST) Received: (from terry@localhost) by phaeton.artisoft.com (8.6.11/8.6.9) id RAA01874; Fri, 15 Nov 1996 17:22:27 -0700 From: Terry Lambert Message-Id: <199611160022.RAA01874@phaeton.artisoft.com> Subject: Re: Sockets question... To: jgreco@brasil.moneng.mei.com (Joe Greco) Date: Fri, 15 Nov 1996 17:22:27 -0700 (MST) Cc: terry@lambert.org, jgreco@brasil.moneng.mei.com, jdp@polstra.com, scrappy@ki.net, hackers@FreeBSD.org In-Reply-To: <199611152300.RAA29354@brasil.moneng.mei.com> from "Joe Greco" at Nov 15, 96 05:00:53 pm X-Mailer: ELM [version 2.4 PL24] MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: owner-hackers@FreeBSD.org X-Loop: FreeBSD.org Precedence: bulk > > 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.