problems with NDELAY

Alan Char alanchar at altos86.UUCP
Sat May 17 05:18:08 AEST 1986


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



More information about the Comp.unix.wizards mailing list