[comp.windows.x] Design problem with XSetIOErrorHandler

klute@tommy.informatik.uni-dortmund.de (Rainer Klute) (01/23/91)

May I cite from the Xlib MIT X Consortium Standard on XSetIOErrorHandler:

	"The XSetIOErrorHandler sets the fatal I/O error handler.
	Xlib calls the program's supplied error handler if any sort
	of system call error occurs (for example, the connection to
	the server was lost). This is assumed to be a fatal condition,
	and the called routine should not return. If the I/O error
	handler does return, the client process exits."

I wonder why the Standard considers I/O errors "fatal" and the why the X
client has no other chance than to quit execution.

The application I am writing wants to deal with I/O errors itself - and in
quite another way than exiting. Especially the example quoted from the
Standard (connection to server lost) is the problem I want to handle. My
application opens connections to several servers, and if one of them breaks
the program is still able to operate. So why should it exit?

Any comments?

-- 
  Dipl.-Inform. Rainer Klute      klute@irb.informatik.uni-dortmund.de
  Univ. Dortmund, IRB             klute@unido.uucp, klute@unido.bitnet
  Postfach 500500         |)|/    Tel.: +49 231 755-4663
D-4600 Dortmund 50        |\|\    Fax : +49 231 755-2386

stripes@eng.umd.edu (Joshua Osborne) (01/24/91)

In article <2959@laura.UUCP>, klute@tommy.informatik.uni-dortmund.de (Rainer Klute) writes:
> May I cite from the Xlib MIT X Consortium Standard on XSetIOErrorHandler:
> 
> 	"The XSetIOErrorHandler sets the fatal I/O error handler.
> 	Xlib calls the program's supplied error handler if any sort
> 	of system call error occurs (for example, the connection to
> 	the server was lost). This is assumed to be a fatal condition,
> 	and the called routine should not return. If the I/O error
> 	handler does return, the client process exits."
> 
> I wonder why the Standard considers I/O errors "fatal" and the why the X
> client has no other chance than to quit execution.
> 
> The application I am writing wants to deal with I/O errors itself - and in
> quite another way than exiting. Especially the example quoted from the
> Standard (connection to server lost) is the problem I want to handle. My
> application opens connections to several servers, and if one of them breaks
> the program is still able to operate. So why should it exit?

I had this problem in a multi-player game (xtrek, havn't fixed xtank yet) under
X11R3.  Using longjmp() worked Ok.  I checked all the displays, when I found the
one that had closed I re-opened a connection and displayed a message ("Please
don't kill xtrek, just Self Destruct").  It was kind of a pain & using WM_DELETE
is much nicer, I'm glad the ICCCM gave a thought to it...
-- 
           stripes@eng.umd.edu          "Security for Unix is like
      Josh_Osborne@Real_World,The          Multitasking for MS-DOS"
      "The dyslexic porgramer"                  - Kevin Lockwood
"CNN is the only nuclear capable news network..."
    - lbruck@eng.umd.edu (Lewis Bruck)

grw@cam-orl.UUCP (Geoff Wiginton) (01/24/91)

I have encountered the same problem when connecting to several displays. The 
solution I adopted was a bit of a hack, but does allow you to return from the
IOErrorHandler. This involves the use of setjmp and longjmp and means you have 
to know where the problem is likely to occur within your code. The best
 explanation is an example.......



#include <stdio.h> 
#include <setjmp.h>

static Display      *display;
static int           IO_error_type;
static jmp_buf       Popup_error_env;
static jmp_buf       Destroy_error_env, Popdown_error_env;

       int           NewIOErrorHandler();




main()
{
     .........
     XSetIOErrorHandler( NewIOErrorHandler );
     .........
}


ProcedureA(........)
{
	IO_error_type = EXIT;

	if ( setjmp( ProcA_error_env ) == 0)
	  {
	   ..........
	   Code using X display that may not exist anymore.
	   .........
	   }
	else
	   {
	   ...........
	   This code will be executed if the attempt to use the display fails.
	   ...........
	   }
}



int NewIOErrorHandler( display )
   Display     *display;
{
  switch (IO_error_type)
    {
        case EXIT:    {  longjmp( ProcA_error_env, 1); break; }

        case POPUP:   {  longjmp( Popup_error_env, 1);   break; }

	case POPDOWN: {  longjmp( Popdown_error_env, 1); break; }

	default:      {  printf("Fatal X IO error. Sorry.\n"); Die(0,0,NULL,NULL); }
	}
}



 Essentially, longjmp returns to the setjmp that set up the environment
(in this case ProcA_error_env) with a non-zero value. All other times
the setjmp will return a 0 value. This allows you to check if an error
has occurred in a part of the code and to handle it accordingly. The
crucial part is that the error handler is never returned from and so
the application does not exit.



Fcc: Default
Subject: 


-------------------------------------------------------------------------------

Geoff Wiginton, Olivetti Research Lab             grw@uk.co.cam-orl
Old Adennbrookes Site, Cambridge                  (0223) 343398