signal handling in 4.2: Is this - (nf)

rpw3 at fortune.UUCP rpw3 at fortune.UUCP
Sun Dec 18 02:05:50 AEST 1983


#R:hou3c:-13500:fortune:11600030:000:3510
fortune!rpw3    Dec 17 03:25:00 1983

[Although it may sound like it, the following is not a flame, but a
serious technical challenge to the community to get their noses
up out of the alligator swamp for just a minute.]

The REAL problem is that everybody keeps trying to use UNIX signals
as if they are "software interrupts" as known by other operating
systems (like TOPS-10). UNIX signals are not "software interrupts",
they are "aborts" which you can (sometimes) catch. Just looking at
the kernel code for signals is scary! There are longjmps all the
way up from device drivers back to the system call handlers, for
crissake! How the hell is a programmer supposed to guarantee
that any kind of higher-level assertion is maintained across a
Hoare-style Monitor when 'sleep()' will longjmp on you and never
give you a chance to do a (dare I use the word "transaction"?) unwind?
(System V gives you the choice, but then you MUST do the longjmp
yourself.)

The various Berkl's have danced all around the problem, but no one has
addressed it directly. I will give you a big hint -- all this talk
about re-starting a tty read or any other read is BOGUS, a holdover
from our past. I put it to you, ladies and gentlemen, that the
following sketchy code fragment is what you really wish you could
write. It is what you CAN write on any system that truly has "software
interrupts" and "non-blocking I/O"! I would also claim that it could
be added to UNIX without breaking anything.

Let us start a discussion!

Rob Warnock

UUCP:	{sri-unix,amd70,hpda,harpo,ihnp4,allegra}!fortune!rpw3
DDD:	(415)595-8444
USPS:	Fortune Systems Corp, 101 Twin Dolphins Drive, Redwood City, CA 94065

------------------------
	#include <pi.h>

	int readhandler();	/* forward ref */
	int writehandler();	/* forward ref */

	char * devnames[NTTY] = ( "/dev/tty00",
				  "/dev/tty01",
				  ...
				  "/dev/ttynn" );

	INTVEC vecs[NVECS];	/* interrupt vectors */
	int	fd[NTTY];	/* file descr. */
	int	stat[NTTY];	/* termination status */

	main(){ int i;

		for(i = 0, i < NTTY, i++){
		    /* open the terminals */
		    fd[i] = open(devnames[i], O_RDWR | O_ASYNC);

		    /* set the interrupt vectors */
		    vecs[i].handler = readhandler;
		    vecs[i + NTTY].handler = writehandler;
		    vecs[i + 2*NTTY].handler = signalhandler;

		    /* connect the events to the vectors */
		    pi_enab(fd[i],i,IO_RD_DONE);
		    pi_enab(fd[i],i+NTTY,IO_WT_DONE);
		    pi_enab(fd[i],i + 2*NTTY,IO_ANY_SIG);

		    /* start up all the I/O */
		    stat[i] = read(fd[i], bufaddr[i], BUFSIZ);
		    stat[i+NTTY] = write(fd[i], "Banner msg\n", 11);
		    }
		pi_config(vecs,NVECS);

		notdone = TRUE;
		pi_on();	/* go! */
		while(notdone)
		    pi_wait();	/* all i/o handled in the interrupt handlers */
		exit(0);	/* alternatively, the exit could be done
				   in a handler */
	}

	readhandler(vec,fd,aux_info){
		/* here when any read completes */
		"check stat[fd]"
		   "process data"
			...
			pi_off();
			...  /* critical section */
			pi_on();
			...
		stat[i] = read(fd[i], bufaddr[i], BUFSIZ);
		pi_rte();	/* dismiss interrupt */
	}

	writehandler(vec,fd,aux_info){
		/* here when any write completes */
		"check stat[fd]"
		"process data"
		stat[i+NTTY] = write(fd[i], <next data>, 11);
		pi_rte();	/* dismiss interrupt */
	}

	signalhandler(vec,fd,aux_info){
		/* here when a device-oriented UNIX signal occurs */
		if (fd = MASTERJOB && aux_info == SIGQUIT)
			notdone = FALSE;	/* quit */
		else "other signals"
		pi_rte();
	}
----------end of code fragment--------------



More information about the Comp.unix.wizards mailing list