From harry@atmos.washington.edu Fri Apr 26 10:54:28 1991
Received: from wet.atmos.washington.edu by unidata.ucar.edu (5.65+/1.34)
	id AA21251; Fri, 26 Apr 91 10:54:24 -0600
Received: by wet.atmos.washington.edu
	(5.64/UW-NDC Revision: 2.20 ) id AA17837; Fri, 26 Apr 91 09:54:17 -0700
From: Harry Edmon <harry@atmos.washington.edu>
Message-Id: <9104261654.AA17837@wet.atmos.washington.edu>
Subject: Proposed fix for my hanging X client problem
To: steve@unidata.ucar.edu
Date: Fri, 26 Apr 91 9:54:16 PDT
X-Mailer: ELM [version 2.3 PL11]
Status: R

Steve,

I now have an idea as to why my xgks clients hang when users log out
and how to fix it.

The problem occurs when the client has backing store is on, the client
is waiting for a gks input event (e.g. greqstring) and the X-server
dies.  The currnt code has the client waiting on a signal (SIGIO).
However, the X-server dying does not cause such a signal to occur.
Thus the client waits forever for a signal that cannot occur since the
server is no more.

The solution is to change the gks input codes to wait for an X event
instead of a signal.  When the server dies, the Xlib code waiting for
en event gets a system I/O error and kills the client.

This problem does not occur when backing store is off.  What is
probably happening there is that an exposure event occurs right before the
X-server dies, and thus the client is processing events when the the
server dies and thus sees it happen.

Here is a proposed patch that implements the fix described above:

*** lib/src/choice.c.dst	Mon Apr  1 10:07:06 1991
--- lib/src/choice.c	Fri Apr 26 09:23:35 1991
***************
*** 508,521 ****
      /* wait for trigger or break */
      idev->touched = False;
      idev->breakhit = False;
!     {
! 	sigset_t	mask;
! 
! 	for ((void) sigemptyset(&mask);
! 	     (idev->touched == False) && (idev->breakhit == False);
! 	     (void) sigsuspend(&mask))
! 	    ;					/* EMPTY */
!     }
  
      idev->active = False;
      if (idev->data.cho.initst.esw == GECHO)
--- 508,518 ----
      /* wait for trigger or break */
      idev->touched = False;
      idev->breakhit = False;
!     for (XgksSIGIO_OFF(ws->dpy);
! 	 (idev->touched == False) && (idev->breakhit == False);
! 	 (void) XgksAwaitEvent(ws))
! 	;					/* EMPTY */
!     XgksSIGIO_ON(ws->dpy);
  
      idev->active = False;
      if (idev->data.cho.initst.esw == GECHO)
*** lib/src/locator.c.dst	Mon Apr  1 10:07:57 1991
--- lib/src/locator.c	Fri Apr 26 09:24:23 1991
***************
*** 574,587 ****
      /* wait for trigger or break */
      idev->touched = False;
      idev->breakhit = False;
!     {
! 	sigset_t	mask;
! 
! 	for ((void) sigemptyset(&mask);
! 	     (idev->touched == False) && (idev->breakhit == False);
! 	     (void) sigsuspend(&mask))
! 	    ;					/* EMPTY */
!     }
  
  #ifdef LOCDEBUG
      (void) fprintf(stderr,
--- 574,584 ----
      /* wait for trigger or break */
      idev->touched = False;
      idev->breakhit = False;
!     for (XgksSIGIO_OFF(ws->dpy);
! 	 (idev->touched == False) && (idev->breakhit == False);
! 	 (void) XgksAwaitEvent(ws))
! 	;					/* EMPTY */
!     XgksSIGIO_ON(ws->dpy);
  
  #ifdef LOCDEBUG
      (void) fprintf(stderr,
*** lib/src/pick.c.dst	Mon Apr  1 10:08:05 1991
--- lib/src/pick.c	Fri Apr 26 09:24:44 1991
***************
*** 316,329 ****
      /* wait for trigger or break */
      idev->touched = FALSE;
      idev->breakhit = FALSE;
!     {
! 	sigset_t	mask;
! 
! 	for ((void) sigemptyset(&mask);
! 	     (idev->touched == FALSE) && (idev->breakhit == FALSE);
! 	     (void) sigsuspend(&mask))
! 	    ;					/* EMPTY */
!     }
  
      idev->active = FALSE;
  
--- 316,326 ----
      /* wait for trigger or break */
      idev->touched = FALSE;
      idev->breakhit = FALSE;
!     for (XgksSIGIO_OFF(ws->dpy);
! 	 (idev->touched == False) && (idev->breakhit == False);
! 	 (void) XgksAwaitEvent(ws))
! 	;					/* EMPTY */
!     XgksSIGIO_ON(ws->dpy);
  
      idev->active = FALSE;
  
*** lib/src/string.c.dst	Mon Apr  1 10:08:22 1991
--- lib/src/string.c	Fri Apr 26 09:23:46 1991
***************
*** 272,285 ****
      /* wait for trigger or break */
      idev->touched = False;
      idev->breakhit = False;
!     {
! 	sigset_t	mask;
! 
! 	for ((void) sigemptyset(&mask);
! 	     (idev->touched == False) && (idev->breakhit == False);
! 	     (void) sigsuspend(&mask))
! 	    ;					/* EMPTY */
!     }
  
      idev->active = False;
      if (idev->data.str.initst.esw == GECHO)
--- 272,282 ----
      /* wait for trigger or break */
      idev->touched = False;
      idev->breakhit = False;
!     for (XgksSIGIO_OFF(ws->dpy);
! 	 (idev->touched == False) && (idev->breakhit == False);
! 	 (void) XgksAwaitEvent(ws))
! 	;					/* EMPTY */
!     XgksSIGIO_ON(ws->dpy);
  
      idev->active = False;
      if (idev->data.str.initst.esw == GECHO)
*** lib/src/stroke.c.dst	Mon Apr  1 10:08:25 1991
--- lib/src/stroke.c	Fri Apr 26 09:25:42 1991
***************
*** 458,471 ****
      /* wait for trigger or break */
      idev->touched = False;
      idev->breakhit = False;
!     {
! 	sigset_t	mask;
! 
! 	for ((void) sigemptyset(&mask);
! 	     (idev->touched == False) && (idev->breakhit == False);
! 	     (void) sigsuspend(&mask))
! 	    ;					/* EMPTY */
!     }
  
      /* deactivate stroke device */
      idev->active = False;
--- 458,468 ----
      /* wait for trigger or break */
      idev->touched = False;
      idev->breakhit = False;
!     for (XgksSIGIO_OFF(ws->dpy);
! 	 (idev->touched == False) && (idev->breakhit == False);
! 	 (void) XgksAwaitEvent(ws))
! 	;					/* EMPTY */
!     XgksSIGIO_ON(ws->dpy);
  
      /* deactivate stroke device */
      idev->active = False;
*** lib/src/valuator.c.dst	Mon Apr  1 10:08:34 1991
--- lib/src/valuator.c	Fri Apr 26 09:26:08 1991
***************
*** 374,387 ****
      /* wait for trigger or break */
      idev->touched = FALSE;
      idev->breakhit = FALSE;
!     {
! 	sigset_t	mask;
! 
! 	for ((void) sigemptyset(&mask);
! 	     (idev->touched == FALSE) && (idev->breakhit == FALSE);
! 	     (void) sigsuspend(&mask))
! 	    ;					/* EMPTY */
!     }
  
      idev->active = FALSE;
  
--- 374,384 ----
      /* wait for trigger or break */
      idev->touched = FALSE;
      idev->breakhit = FALSE;
!     for (XgksSIGIO_OFF(ws->dpy);
! 	 (idev->touched == False) && (idev->breakhit == False);
! 	 (void) XgksAwaitEvent(ws))
! 	;					/* EMPTY */
!     XgksSIGIO_ON(ws->dpy);
  
      idev->active = FALSE;
  
*** lib/src/x/xevent.c.dst	Mon Apr  1 10:09:33 1991
--- lib/src/x/xevent.c	Thu Apr 25 16:07:28 1991
***************
*** 455,457 ****
--- 455,468 ----
      return 0;
  }
  #endif	/* EVENTDEBUG defined */
+ 
+ void
+ XgksAwaitEvent(ws)
+     WS_STATE_PTR ws;
+ {
+     Display *dpy = ws->dpy;
+     XEvent  report;
+ 
+     XPeekEvent(dpy, &report);
+     xProcessEvents();
+ }

-- 
Harry Edmon		INTERNET: harry@atmos.washington.edu
(206) 543-0547		UUCP:	  uw-beaver!atmos.washington.edu!harry
Dept of Atmospheric Sciences, AK-40
University of Washington

From ~/mail/xgks Tue Apr 30 08:09:01 1991
From devo@chaos.atms.purdue.edu Mon Apr 15 23:03:16 1991
Received: from chaos.atms.purdue.edu by unidata.ucar.edu (5.65+/1.34)
	id AA07988; Mon, 15 Apr 91 22:29:57 -0600
Received: by chaos.atms.purdue.edu (AIX  2.1 2/4.03)
          id AA07332; Mon, 15 Apr 91 23:23:27 EST
Date: Mon, 15 Apr 91 23:23:27 EST
From: devo@chaos.atms.purdue.edu (Daniel E Vietor)
Message-Id: <9104160423.AA07332@chaos.atms.purdue.edu>
To: xgks@unidata.atms.purdue.edu
Subject: XGKS on System V based UNIX
Cc: devo@chaos.atms.purdue.edu
Status: RO


Dear System V sufferers,

I have found out that several of you have been trying to compile
XGKS on System V UNIX and have found that the interactive part
of XGKS does not work.  This is due to the fact that XGKS uses
the SIGIO signal to trap whether an event has been passed back
from the server to the application (client) program.  This is
an exclusively BSD UNIX signal and not provided on System V
systems.  Therefore, no interaction in XGKS can be done with
the X server on System V systems unless you work around this
problem.

The key here is that XGKS traps the SIGIO signal and passes
program execution to the xProcessEvents function when that
signal is recieved.  In other words, whenever an event like
a keyboard hit, mouse movement or window expose or resize
occurs.  To cure this problem, you must be able to call
xProcessEvents somewhere in XGKS so that the events can be
processed without waiting for the SIGIO signal.  

I do this by making the following modifications:

************************************
xevent.c:

in XgksSIGIO_ON()
add a call to xProcessEvents

add a new function called XgksAwaitEvent()
which calls xProcessEvents

eliminate all sigpause, sigvec and signal calls.

************************************
string.c, stroke.c, pick.c, valuator.c, locator.c:

replace the sigpause calls with a call to XgksAwaitEvent


What this does is sets up XGKS to check for events whenever
XGKS pauses to receive input.  Also, XgksSIGIO_ON is called
frequently whenever major XGKS functions are called such
as all drawing primatives.  This also allows events to be 
checked whenever drawing is being done.

I have compiled XGKS on Silicon Graphics IRIS workstations 
and on AT&T 6386 UNIX workstations which are both strict
System V workstations and therefore do not have SIGIO
signals.

I hope this is a start for those System V problems.

Dan Vietor
devo@chaos.atms.purdue.edu

