guy@auspex.UUCP (Guy Harris) (11/17/88)
>When you close the line (e.g., at exit from SIGHUP), the kernel >(correctly) waits for the output to drain. It *should* give up >after a `reasonable' timeout, on the assumption that output never >will drain. Define "reasonable". What if the line is going to a printer, and it runs out of paper? It could be a while before those last few characters get transmitted.... >A number of kernels get this wrong, various BSD implementations >included. Note, though, that `giving up' will put some terminals >into a confused state. The S5R3 streams code "gets it right" in the sense that it will time out eventually; unfortunately, in addition to flushing data queued for a streams module when it gets tired of waiting for that module to drain its queue, it also gets rid of the module - which means that unless the driver handles XON/XOFF, you lose flow control at some point, which will, indeed, put some terminals in a confused state. The line discipline-based S5 tty drivers don't time out, but they will un-stop XOFFed output when the line is closed; this will also put some terminals in a confused state.... Unfortunately, I'm not sure there's a single way of getting it right. Printers, plotters, etc. should be prepared to wait forever; terminals on which people are logged in, or dial-out lines, should perhaps give up eventually (although perhaps carrier going away could be the signal for this).
chris@mimsy.UUCP (Chris Torek) (11/18/88)
>In article <14526@mimsy.UUCP> I wrote: >>[The kernel] *should* give up after a `reasonable' timeout, on the >>assumption that output never will drain. In article <460@auspex.UUCP> guy@auspex.UUCP (Guy Harris) writes: >Define "reasonable". What if the line is going to a printer, and it >runs out of paper? It could be a while before those last few characters >get transmitted.... That is why I put the word in quotes. Perhaps the timeout should be configurable (say, `n' seconds, where 0 = wait forever, set by an ioctl). Even waiting forever for a printer or plotter may be wrong: if one uses XON/XOFF flow control, but is reset after an XOFF, it may never send an XON. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
peter@ficc.uu.net (Peter da Silva) (11/19/88)
The basic problem here is that a process is only ever waiting on one event at a time. This is so fundamental to UNIX that you don't ever think about it... but there's really no reason why it has to be that way. Changing this would require a major change in how the kernel works, but it'd be worth it in the long term. Realtime would become dead easy, for example... Here's an idea that would get you around this problem: when you send a signal to a process, force a wakeup on whatever that process is waiting on. That should make it pay attention to the signal and go on to die. -- Peter da Silva `-_-' Ferranti International Controls Corporation "Have you hugged U your wolf today?" uunet.uu.net!ficc!peter Disclaimer: My typos are my own damn business. peter@ficc.uu.net
chris@mimsy.UUCP (Chris Torek) (11/20/88)
In article <2269@ficc.uu.net> peter@ficc.uu.net (Peter da Silva) writes: >The basic problem here is that a process is only ever waiting on one >event at a time. This is so fundamental to UNIX that you don't ever >think about it... but there's really no reason why it has to be that >way. Select() and, in SVR?, poll(), wait on multiple events, although they do it somewhat by cheating. >Here's an idea that would get you around this problem: when you send a signal >to a process, force a wakeup on whatever that process is waiting on. That >should make it pay attention to the signal and go on to die. Not necessarily; indeed, the usual wait loop is something like while (resource->flag & LOCKED) { resource->flag |= WANTED; sleep((caddr_t)resource, priority); } resource->flag |= LOCKED; <critical section code> if (resource->flag & WANTED) wakeup((caddr_t)resource); resource->flag &= ~(LOCKED|WANTED); Since the locking code is a while loop, forcing a wakeup would have no effect. Fortunately, that is not how things work. If the `priority' argument to sleep() is greater than PZERO, a signal will force an exit by a non-local `goto' (longjmp()) out of sleep(). Long-term sleepers can and should sleep above PZERO, arranging to catch longjmp()s and clean up after themselves as necessary. (This is easier in newer Sun and SysV kernels; it seems likely that 4.4BSD's synchronisation mechanisms will have changed as well.) -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris