interrupt mechanism reworked, make SIGCHLD interrupt also
authorEdward Wang <edward@ucbvax.Berkeley.EDU>
Mon, 8 Jun 1987 17:28:13 +0000 (09:28 -0800)
committerEdward Wang <edward@ucbvax.Berkeley.EDU>
Mon, 8 Jun 1987 17:28:13 +0000 (09:28 -0800)
SCCS-vsn: usr.bin/window/wwchild.c 3.7
SCCS-vsn: usr.bin/window/ww.h 3.40
SCCS-vsn: usr.bin/window/wwrint.c 3.5
SCCS-vsn: usr.bin/window/wwiomux.c 3.16

usr/src/usr.bin/window/ww.h
usr/src/usr.bin/window/wwchild.c
usr/src/usr.bin/window/wwiomux.c
usr/src/usr.bin/window/wwrint.c

index 98c011f..b6ffbdb 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * @(#)ww.h    3.39 %G%        
+ * @(#)ww.h    3.40 %G%        
  */
 
 /*
  */
 
 /*
@@ -207,8 +207,6 @@ int wwnselect, wwnselecte, wwnselectz;
        /* things for handling input */
 int wwrint();          /* interrupt handler */
 struct ww *wwcurwin;   /* window to copy input into */
        /* things for handling input */
 int wwrint();          /* interrupt handler */
 struct ww *wwcurwin;   /* window to copy input into */
-char wwsetjmp;         /* want a longjmp() from wwrint() */
-jmp_buf wwjmpbuf;      /* jmpbuf for above */
 char *wwib;            /* input (keyboard) buffer */
 char *wwibe;           /* wwib + sizeof buffer */
 char *wwibp;           /* current read position in buffer */
 char *wwib;            /* input (keyboard) buffer */
 char *wwibe;           /* wwib + sizeof buffer */
 char *wwibp;           /* current read position in buffer */
@@ -216,7 +214,14 @@ char *wwibq;               /* current write position in buffer */
 #define wwgetc()       (wwibp < wwibq ? *wwibp++ & 0x7f : -1)
 #define wwpeekc()      (wwibp < wwibq ? *wwibp & 0x7f : -1)
 #define wwungetc(c)    (wwibp > wwib ? *--wwibp = (c) : -1)
 #define wwgetc()       (wwibp < wwibq ? *wwibp++ & 0x7f : -1)
 #define wwpeekc()      (wwibp < wwibq ? *wwibp & 0x7f : -1)
 #define wwungetc(c)    (wwibp > wwib ? *--wwibp = (c) : -1)
-#define wwinterrupt()  (wwibp < wwibq)
+
+       /* things for short circuiting wwiomux() */
+char wwintr;           /* interrupting */
+char wwsetjmp;         /* want a longjmp() from wwrint() and wwchild() */
+jmp_buf wwjmpbuf;      /* jmpbuf for above */
+#define wwinterrupt()  wwintr
+#define wwsetintr()    (wwintr = 1, wwsetjmp ? longjmp(wwjmpbuf, 1) : 0)
+#define wwclrintr()    (wwintr = 0)
 
        /* the window virtual terminal */
 #define WWT_TERM       "TERM=window"
 
        /* the window virtual terminal */
 #define WWT_TERM       "TERM=window"
index d83c442..2971166 100644 (file)
@@ -1,5 +1,5 @@
 #ifndef lint
 #ifndef lint
-static char sccsid[] = "@(#)wwchild.c  3.6 %G%";
+static char sccsid[] = "@(#)wwchild.c  3.7 %G%";
 #endif
 
 /*
 #endif
 
 /*
@@ -19,6 +19,7 @@ wwchild()
        register struct ww **wp;
        union wait w;
        int pid;
        register struct ww **wp;
        union wait w;
        int pid;
+       char collected = 0;
 
        olderrno = errno;
        while ((pid = wait3(&w, WNOHANG|WUNTRACED, (struct rusage *)0)) > 0) {
 
        olderrno = errno;
        while ((pid = wait3(&w, WNOHANG|WUNTRACED, (struct rusage *)0)) > 0) {
@@ -26,9 +27,13 @@ wwchild()
                        if (*wp && (*wp)->ww_state == WWS_HASPROC
                            && (*wp)->ww_pid == pid) {
                                (*wp)->ww_state = WWS_DEAD;
                        if (*wp && (*wp)->ww_state == WWS_HASPROC
                            && (*wp)->ww_pid == pid) {
                                (*wp)->ww_state = WWS_DEAD;
+                               collected = 1;
                                break;
                        }
                }
        }
        errno = olderrno;
                                break;
                        }
                }
        }
        errno = olderrno;
+       /* jump out of wwiomux when somebody dies */
+       if (collected)
+               wwsetintr();
 }
 }
index f8948f2..8c730e7 100644 (file)
@@ -1,5 +1,5 @@
 #ifndef lint
 #ifndef lint
-static char sccsid[] = "@(#)wwiomux.c  3.15 %G%";
+static char sccsid[] = "@(#)wwiomux.c  3.16 %G%";
 #endif
 
 /*
 #endif
 
 /*
@@ -17,7 +17,8 @@ static char sccsid[] = "@(#)wwiomux.c 3.15 %G%";
  * The idea is to copy window outputs to the terminal, via the
  * display package.  We try to give the top most window highest
  * priority.  The only return condition is when there is keyboard
  * The idea is to copy window outputs to the terminal, via the
  * display package.  We try to give the top most window highest
  * priority.  The only return condition is when there is keyboard
- * input, which is serviced asynchronously by wwrint().
+ * input or when a child process dies which are serviced by signal
+ * catchers (wwrint() and wwchild()).
  * When there's nothing to do, we sleep in a select().
  * This can be done better with interrupt driven io.  But that's
  * not supported on ptys, yet.
  * When there's nothing to do, we sleep in a select().
  * This can be done better with interrupt driven io.  But that's
  * not supported on ptys, yet.
@@ -33,97 +34,105 @@ wwiomux()
        static struct timeval tv = { 0, 0 };
        char noblock;
 
        static struct timeval tv = { 0, 0 };
        char noblock;
 
-loop:
-       if (wwinterrupt())
-               return;
-
-       FD_ZERO(&imask);
-       noblock = 0;
-       for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw) {
-               if (w->ww_pty < 0)
-                       continue;
-               if (w->ww_obq < w->ww_obe)
-                       FD_SET(w->ww_pty, &imask);
-               if (w->ww_obq > w->ww_obp && !w->ww_stopped)
-                       noblock = 1;
-       }
-
-       if (!noblock) {
-               if (wwcurwin != 0)
-                       wwcurtowin(wwcurwin);
-               wwupdate();
-               wwflush();
-               if (setjmp(wwjmpbuf))
-                       return;
-               wwsetjmp = 1;
+       for (;;) {
                if (wwinterrupt()) {
                if (wwinterrupt()) {
-                       wwsetjmp = 0;
+                       wwclrintr();
                        return;
                }
                        return;
                }
-       }
-       wwnselect++;
-       n = select(wwdtablesize, &imask, (fd_set *)0, (fd_set *)0,
-               noblock ? &tv : (struct timeval *)0);
-       wwsetjmp = 0;
 
 
-       if (n < 0)
-               wwnselecte++;
-       else if (n == 0)
-               wwnselectz++;
-       else
+               FD_ZERO(&imask);
+               noblock = 0;
                for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw) {
                for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw) {
-                       if (w->ww_pty < 0 || !FD_ISSET(w->ww_pty, &imask))
+                       if (w->ww_pty < 0)
                                continue;
                                continue;
-                       wwnwread++;
-                       p = w->ww_obq;
-                       if (w->ww_ispty) {
-                               if (p == w->ww_ob) {
-                                       w->ww_obp++;
-                                       w->ww_obq++;
-                               } else
-                                       p--;
-                               c = *p;
+                       if (w->ww_obq < w->ww_obe)
+                               FD_SET(w->ww_pty, &imask);
+                       if (w->ww_obq > w->ww_obp && !w->ww_stopped)
+                               noblock = 1;
+               }
+
+               if (!noblock) {
+                       if (wwcurwin != 0)
+                               wwcurtowin(wwcurwin);
+                       wwupdate();
+                       wwflush();
+                       setjmp(wwjmpbuf);
+                       wwsetjmp = 1;
+                       if (wwinterrupt()) {
+                               wwsetjmp = 0;
+                               wwclrintr();
+                               return;
                        }
                        }
-                       n = read(w->ww_pty, p, w->ww_obe - p);
-                       if (n < 0) {
-                               wwnwreade++;
-                               (void) close(w->ww_pty);
-                               w->ww_pty = -1;
-                       } else if (n == 0) {
-                               wwnwreadz++;
-                               (void) close(w->ww_pty);
-                               w->ww_pty = -1;
-                       } else if (!w->ww_ispty) {
-                               wwnwreadd++;
-                               wwnwreadc += n;
-                               w->ww_obq += n;
-                       } else if (*p == TIOCPKT_DATA) {
-                               n--;
-                               wwnwreadd++;
-                               wwnwreadc += n;
-                               w->ww_obq += n;
-                       } else {
-                               wwnwreadp++;
-                               if (*p & TIOCPKT_STOP)
-                                       w->ww_stopped = 1;
-                               if (*p & TIOCPKT_START)
-                                       w->ww_stopped = 0;
-                               if (*p & TIOCPKT_FLUSHWRITE) {
-                                       w->ww_stopped = 0;
+               }
+               wwnselect++;
+               n = select(wwdtablesize, &imask, (fd_set *)0, (fd_set *)0,
+                       noblock ? &tv : (struct timeval *)0);
+               wwsetjmp = 0;
+
+               if (n < 0)
+                       wwnselecte++;
+               else if (n == 0)
+                       wwnselectz++;
+               else
+                       for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw) {
+                               if (w->ww_pty < 0 ||
+                                   !FD_ISSET(w->ww_pty, &imask))
+                                       continue;
+                               wwnwread++;
+                               p = w->ww_obq;
+                               if (w->ww_ispty) {
+                                       if (p == w->ww_ob) {
+                                               w->ww_obp++;
+                                               w->ww_obq++;
+                                       } else
+                                               p--;
+                                       c = *p;
+                               }
+                               n = read(w->ww_pty, p, w->ww_obe - p);
+                               if (n < 0) {
+                                       wwnwreade++;
+                                       (void) close(w->ww_pty);
+                                       w->ww_pty = -1;
+                               } else if (n == 0) {
+                                       wwnwreadz++;
+                                       (void) close(w->ww_pty);
+                                       w->ww_pty = -1;
+                               } else if (!w->ww_ispty) {
+                                       wwnwreadd++;
+                                       wwnwreadc += n;
+                                       w->ww_obq += n;
+                               } else if (*p == TIOCPKT_DATA) {
+                                       n--;
+                                       wwnwreadd++;
+                                       wwnwreadc += n;
+                                       w->ww_obq += n;
+                               } else {
+                                       wwnwreadp++;
+                                       if (*p & TIOCPKT_STOP)
+                                               w->ww_stopped = 1;
+                                       if (*p & TIOCPKT_START)
+                                               w->ww_stopped = 0;
+                                       if (*p & TIOCPKT_FLUSHWRITE) {
+                                               w->ww_stopped = 0;
+                                               w->ww_obq = w->ww_obp =
+                                                       w->ww_ob;
+                                       }
+                               }
+                               if (w->ww_ispty)
+                                       *p = c;
+                       }
+               for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw)
+                       if (w->ww_pty >= 0 && w->ww_obq > w->ww_obp &&
+                           !w->ww_stopped) {
+                               n = wwwrite(w, w->ww_obp,
+                                       w->ww_obq - w->ww_obp);
+                               if ((w->ww_obp += n) == w->ww_obq)
                                        w->ww_obq = w->ww_obp = w->ww_ob;
                                        w->ww_obq = w->ww_obp = w->ww_ob;
+                               if (wwinterrupt()) {
+                                       wwclrintr();
+                                       return;
                                }
                                }
+                               break;
                        }
                        }
-                       if (w->ww_ispty)
-                               *p = c;
-               }
-       for (w = wwhead.ww_forw; w != &wwhead; w = w->ww_forw)
-               if (w->ww_pty >= 0 && w->ww_obq > w->ww_obp && !w->ww_stopped) {
-                       n = wwwrite(w, w->ww_obp, w->ww_obq - w->ww_obp);
-                       if ((w->ww_obp += n) == w->ww_obq)
-                               w->ww_obq = w->ww_obp = w->ww_ob;
-                       if (wwinterrupt())
-                               return;
-                       break;
-               }
-       goto loop;
+       }
 }
 }
index a98cf87..61854ed 100644 (file)
@@ -1,5 +1,5 @@
 #ifndef lint
 #ifndef lint
-static char sccsid[] = "@(#)wwrint.c   3.4 %G%";
+static char sccsid[] = "@(#)wwrint.c   3.5 %G%";
 #endif
 
 /*
 #endif
 
 /*
@@ -15,8 +15,7 @@ static char sccsid[] = "@(#)wwrint.c  3.4 %G%";
 /*
  * Tty input interrupt handler.
  * (1) Read input into buffer (wwib*).
 /*
  * Tty input interrupt handler.
  * (1) Read input into buffer (wwib*).
- * (2) If the flag wwsetjmp is true, do longjmp(wwjmpbuf) for asyncronous
- *     actions, and to avoid race conditions, clear wwsetjmp.
+ * (2) Set the interrupt flag if anything is read.
  * Currently, the last is used to get out of the blocking
  * select() in wwiomux().
  * To avoid race conditions, we only modify wwibq in here, except
  * Currently, the last is used to get out of the blocking
  * select() in wwiomux().
  * To avoid race conditions, we only modify wwibq in here, except
@@ -36,13 +35,9 @@ wwrint()
        if (n > 0) {
                wwibq += n;
                wwnreadc += n;
        if (n > 0) {
                wwibq += n;
                wwnreadc += n;
+               wwsetintr();
        } else if (n == 0)
                wwnreadz++;
        else
                wwnreade++;
        } else if (n == 0)
                wwnreadz++;
        else
                wwnreade++;
-       if (wwinterrupt() && wwsetjmp) {
-               wwsetjmp = 0;
-               (void) sigsetmask(sigblock(0) & ~sigmask(SIGIO));
-               longjmp(wwjmpbuf, 1);
-       }
 }
 }