alanchar@altos86.UUCP (Alan Char) (05/16/86)
We have a problem with opening terminal devices with the NDELAY bit set. In the low-level driver, there is a test that looks like this: /* If delay on open is set wait unit carrier is on */ if(!(flag&FNDELAY) && !(tp->t_state&CARR_ON)) while(!(tp->t_state&CARR_ON)) { tp->t_state |= WOPEN; /* waiting for open to complete */ sleep((caddr_t)&tp->t_canq, TTIPRI); } (This is from ppc.c in the 3B2 kernel, UNIX 5.2.1, but other drivers have this loop as well. We use our own drivers but essentially do the same thing.) When it receives a modem interrupt, it executes the following to wake up the process: case AC_CON: sysinfo.mdmint++; tp->t_state |= CARR_ON; if(tp->t_state&WOPEN) { tp->t_state &= ~WOPEN; wakeup((caddr_t)&tp->t_canq); } The problem is that if a process is waiting for carrier (NDELAY not set), and ANOTHER process opens the same terminal with NDELAY set, then it goes ahead and calls ttopen() which clears the WOPEN bit. Thus, the first process never gets waked up. Is there some other way that this case is handled or is this just a bug? If the bit is cleared in the modem interrupt routine, why is it also cleared in ttopen()? (Especially since it is not set by any of the tt*() routines.) Suggested solutions from this site are: 1) Take the line out of ttopen() that clears the WOPEN bit. (My choice) 2) Don't check the WOPEN bit when you get the modem interrupt, always do the wakeup. 3) Do a wakeup after you call ttopen(), forcing the first process to re-check carrier and reset the WOPEN bit. Any comments on this problem or the various "solutions"? Thanks. Alan Char Altos Computer Systems 2641 Orchard Park Way San Jose, CA 95134