[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference bulova::decw_jan-89_to_nov-90

Title:DECWINDOWS 26-JAN-89 to 29-NOV-90
Notice:See 1639.0 for VMS V5.3 kit; 2043.0 for 5.4 IFT kit
Moderator:STAR::VATNE
Created:Mon Oct 30 1989
Last Modified:Mon Dec 31 1990
Last Successful Update:Fri Jun 06 1997
Number of topics:3726
Total number of notes:19516

666.0. "XSelectAsyncInput on ULTRIX" by LDPMAX::gabriel (Thank You Very Little) Mon Apr 24 1989 20:01


Could somone please explain how XSelectAsyncInput is used
while running ULTRIX.  I know there are no such things as 
ASTs and I am wondering how this differs from XSelectInput..

I have a customer who has a program that uses this call and in
his AST callback routine he has his XNextEvent call.  He doesn't
have it in the conventional loop and he is claiming that
exposure events are causing the server to hang.

Is it 'legal' to call XNextEvent from an AST callback routine ???

Any help or pointers to other notes are wlecome.  I have read
all the notes on XSelectAsyncInput but they deal mostly with 
VMS.

Thanks,

-Joe-

T.RTitleUserPersonal
Name
DateLines
666.1FLUME::dikeTue Apr 25 1989 09:378
It is legal to use Xlib in the callback routine.  XSelectAsyncInput is strictly
an Xlib feature.  It causes no protocol to happen, which is why calling
XSelectAsyncInput without also calling XSelectInput for the same events is a
no-op.  I find it very difficult to believe that use of this call can hang the
server.  I would say it is impossible, but I have seen "impossible" things
happen before.
				Jeff

666.2uses SIGIOCRLVMS::HALBERTCRL, TrellisTue Apr 25 1989 10:554
    XSelectAsyncInput uses the SIGIO signal on Ultrix. If your customer is
    already using this for something use, bad things can (will?) happen.
    --Dan

666.3FLUME::dikeTue Apr 25 1989 14:118
If your client expects to use SIGIO, then make sure that it establishes its
signal handler before the first call to XSelectAsyncInput.  GKS had this problem
and I put a fix in to have Xlib remember any previous handler and call it
if the SIGIO didn't come from the server.  The symptoms are this sort of
collision would either be the async events not arriving at their handler or
the client's interrupt handler not being called.
				Jeff

666.4questionKOBAL::VANNOYJake VanNoyWed Apr 26 1989 10:1211
    Jeff, this question came up the other day and I didn't know the answer:
    
    on Ultrix, does the locking in the LockDisplay macro require that the
    call back into XLib is being done from within a SIGIO generated by
    XLib?
    
    There was an ISV that had set up a timer and was getting ACCVIOs
    (coredumps?) on Ultrix when calling XNextEvent from the timer signal.
    
    jake

666.5FLUME::dikeWed Apr 26 1989 14:009
The async notification code is independent of the toolkit timer code, I think.
I will have a look for unpleasant interactions to be sure.

The async code allows the user to use Xlib from inside the callback (it would
be pretty useless if you couldn't).

Was this ISV using asynchronous notification as well?
				Jeff

666.6Server hang because of the client not reading?DECWIN::FISHERBurns Fisher 381-1466, ZKO3-4/W23Wed Apr 26 1989 14:276
As to hanging the server, I suppose that if the customer is depending on
the async notification to do XNextEvent, and for some reason it is not
happening, eventually the server will hang.  (True for Ultrix?)

Burns

666.7FLUME::dikeWed Apr 26 1989 14:363
The server will not hang.  The server will drop the connection.
				Jeff

666.8it may hang, but only temporarilyPSW::WINALSKIPaul S. WinalskiWed Apr 26 1989 14:555
It may fill up its buffer queue and hang for a minute or two before it times out
the client and starts serving other things again.

--PSW

666.9FLUME::dikeWed Apr 26 1989 17:324
The Ultrix server doesn't have to wait for a timeout.  It gets told immediately
(the length of time for a round-trip between the two machines to happen).
				Jeff

666.10XNextEvent in AST callback for PMAX...LDP::GABRIELThank You Very LittleWed Apr 26 1989 21:5442
    
    
    RE: .*
    
    
    I have written a simple program that does use XNextEvent in the
    AST callback and it works fine.  I am having the ISV send me a copy
    of his code that doesn't appear to be working.
    
    I do have one call to XNextEvent to handle my first expose event
    when I create my first window.  I have also noticed that my program
    is always in the AST routine, ie it never leaves the AST routine
    to go back to the application code:
    
    	.
    	.
    	.
    	XSelectInput(...)
    	XSelectAsyncInput(...AST_routine..)
  	XNextEvent
    	forever {
    	printf(someting)
    	}
    	
    	AST_routine ()
	{
	    	XNextEvent
	    	switch(event.type) {
	    		.
	    		.
	    		.
	}
    
    	The print statement in the forever loop is NEVER being executed.
    	Is this expected behavior ??  The ISV says his application doesn't
    	exhibit do this.
    
    
    	-Joe
        
    

666.11PSW::WINALSKIPaul S. WinalskiWed Apr 26 1989 22:358
RE: .9

Ugh.  You mean if any application falls behind on processing events for even a
fraction of a second, it could get bounced by the Ultrix server?  All the more
reason to get decent flow control into the X protocol!

--PSW

666.12FLUME::dikeThu Apr 27 1989 09:298
.10: Can you post the actual code?  It's hard to tell if anything is wrong from
the skeleton that you posted.

.11: It takes a lot more than a fraction of a second to get bounced.  And being
bounced is certanily better than one misbehaving client hanging the server.
This has been the case since X10 days, and it has rarely been a problem.
				Jeff

666.132702::WINALSKIPaul S. WinalskiThu Apr 27 1989 15:5012
RE: .12

It's a problem whenever you're debugging an X application (on either OS), you
are stopped at a breakpoint, and you have to move the mouse across a window
belonging to the application being debugged, and that window has mouse movement
event reporting enabled.

How anybody could design a multi-client server such that it has these problems
is beyond me.

--PSW

666.14But did X10 do it right?IO::MCCARTNEYJames T. McCartney III - DTN 381-2244 ZK02-2/N24Fri Apr 28 1989 18:579
RE: .12 

And the symptom that Paul reports in .13 is very frequent and hangs the 
server until the server times out.

But lets not start this rathole again....

James

666.15FLUME::dikeSat Apr 29 1989 10:394
It must be the VMS server, because I've done my share of debugging DECwindows
programs, and I've never seen it.
				Jeff

666.16events.cLDP::GABRIELThank You Very LittleSun Apr 30 1989 16:16203
    RE: A coupla back...
    
    Here is the code I wrote.  It compiles and runs on the PMAX but
    like I said never gets to the printf in the forever loop.
    
    Is this supposed to happen ????
    
    -Joe
    
    
    
# include <X11/Xlib.h>
# include <X11/Xutil.h>
# include <X11/Xatom.h>
# include <stdio.h>

char hello[]	=	"Hello, World";
char hi[]	=	"Hi!";

void AST_event_handler ();
static	Pixmap		backing;	/* Pixmap for backing store */
static	GC		backing_GC;	/* GC for backing store */
static	Display		*mydisplay;	/* Display ID */
static	GC		mygc;		/* main window GC */
static	Window		mywindow;	/* Window ID */
static	XEvent		myevent;	/* Event Structure */
static	KeySym		mykey;		/* key returned from keypress event */
static	XSizeHints	myhint;		/* Set up window hints */
static	int		myscreen;	/* Screen ID */
static	unsigned long	myblack,mywhite;/* Black and White Pixel values */
static	int		i,done;
static	char		text[10];
static	int		depth;		/* Screen Depth */
static	XWMHints	hints;		/* Window Manager hints */
static  XSetWindowAttributes win_attribs;  
static int              x1, y1, x2, y2;
main (argc, argv)
int argc;
char **argv;
{
/****
     The following lines initialize the program, and set up some
     basic window parameters.
****/
	mydisplay = XOpenDisplay("");
	myscreen = DefaultScreen (mydisplay);
	mywhite = WhitePixel (mydisplay, myscreen);
	myblack = BlackPixel (mydisplay, myscreen);
	myhint.x = 200;
	myhint.y = 300;
	myhint.width = 350;
	myhint.height = 250;
	myhint.flags = PPosition|PSize;
        win_attribs.event_mask = ButtonPressMask | KeyPressMask | ExposureMask;


/****
    Create the Window
****/
	mywindow = XCreateSimpleWindow (mydisplay,
		DefaultRootWindow (mydisplay),
		myhint.x, myhint.y, myhint.width, myhint.height, 5,
		myblack,mywhite);
/****
    Find depth of Screen, to be used for creating the backing store
    pixmap.
****/
	depth = DefaultDepth(mydisplay, myscreen);

/**** 
    Set up backing store pixmap and GC.
	1) Create Pixmap.
	2) Create GC.
	3) Empty the pixmap and GC, by drawing an empty rectangle.
	4) Set the same background/foreground as main window.
****/
	backing = XCreatePixmap (mydisplay, mywindow, myhint.width, 
		myhint.height,depth);
	backing_GC = XCreateGC (mydisplay, backing, 0, 0);
	XFillRectangle(mydisplay, backing, backing_GC, 0,0,
	    myhint.width, myhint.height);
/****
    Set Window Properties.
****/

        XChangeWindowAttributes(mydisplay, mywindow, 
                                CWEventMask, &win_attribs);

	XSetStandardProperties (mydisplay, mywindow, hello, hello,
		None, argv, argc, &myhint);
/****
    Create GC for main window.
****/
	mygc = XCreateGC (mydisplay, mywindow, 0, 0);
/****
    Set background and foreground for both backing store GC and
    main window GC.
****/
	XSetBackground (mydisplay, mygc, mywhite);
	XSetForeground (mydisplay, mygc, myblack);
	XSetBackground (mydisplay, backing_GC, mywhite);
	XSetForeground (mydisplay, backing_GC, myblack);
/****
    Output text to both main window and pixmap.
****/
	XDrawImageString(mydisplay, mywindow, mygc,
	    50,50,hello, strlen(hello));
	XDrawImageString(mydisplay, backing, backing_GC,
	    50,50,hello, strlen(hello));
/****
    Wait for the following events.
****/

	XSelectInput (mydisplay, mywindow, 
		ButtonPressMask | KeyPressMask | ExposureMask);

	XSelectAsyncInput (mydisplay, mywindow, 
		ButtonPressMask | KeyPressMask | ExposureMask,
                AST_event_handler, 0);
/****
    Map Window.
****/
	XMapWindow (mydisplay, mywindow);

	done = 0;
        XNextEvent (mydisplay, &myevent);  

	while (done == 0)
	{
	for (i=0; i<500; i++)
         printf("In forever loop \n");   
        }
/****
    End the program.
****/
/*	XFreeGc(mydisplay,backing_GC);
	XFreeGc(mydisplay, mygc); */
	XDestroyWindow (mydisplay, mywindow);
	XCloseDisplay (mydisplay);
	exit (0);
}

void AST_event_handler ()
{


/* printf("In the AST event handler \n");
   printf("Event type is %d \n",myevent.type);  */
   XNextEvent (mydisplay, &myevent);  
   switch (myevent.type)
	{

		  case Expose:
			if (myevent.xexpose.count == 0)
			    XCopyArea (mydisplay, backing, mywindow,
			     backing_GC, 0,0,myhint.width,
			     myhint.height, 0,0);
		  break;


/****
    If mouse button is pressed, put the string "Hi!" in the location
    where the button was pressed.  Do this both in the window and
    the pixmap.
****/
		  case ButtonPress:
			XDrawImageString (mydisplay, mywindow, mygc,
			    myevent.xbutton.x+i+5, myevent.xbutton.y+i+5,
			    hi, strlen(hi));
			XDrawImageString (mydisplay, backing,backing_GC,
			    myevent.xbutton.x+i+5, myevent.xbutton.y+i+5,
			    hi, strlen(hi));  
		  break;

		  case MappingNotify:
			XRefreshKeyboardMapping (&myevent);
		  break;
/****
    Also if an 'i' is pressed, iconify the window.
    If a 'q' is pressed, quit from the application.
****/
		  case KeyPress:
			i = XLookupString(&myevent, text, 10, &mykey,
			    0);
			if (i==1 && text[0]=='i') 
			{
			    hints.flags = StateHint;
			    hints.initial_state = IconicState;
			    XSetWMHints (mydisplay, mywindow, &hints);
			}
			if (i==1 && text[0] == 'q') exit(0);    
                        
		  break;

                  default :

                  break;

        }  /* end switch  */

}

666.17Bad user on device?VEENA::thomasThe Code WarriorSun Apr 30 1989 17:268
Seems to me your is doing what it is supposed to do.

All the events will go to your "AST" handler and so none will ever
find their way to your mainline XNextEvent.  So your program 
blocks forever.

But I could be wrong...

666.18FLUME::dikeMon May 01 1989 09:475
Matt is correct.  The async notification is eating all the events, so none are
getting to the XNextEvent in main.  Getting rid of the synchronous NextEvent
will allow your loop to run.
				Jeff

666.19Commented out XNextEvent and...LDPMAX::gabrielThank You Very LittleMon May 01 1989 15:029
I commented out the first call to XNextEvent and the program  went into
my loop BUT my window never got created or mapped ???  Any ideas ??????


Thanks,

/Joe

666.20STAR::BRANDENBERGSi vis pacem para bellumMon May 01 1989 16:083
    
    Xflush() the display.

666.21LDPMAX::gabrielThank You Very LittleTue May 02 1989 19:0621
XFlush did the trick for me...Thanks you...

The customer was still curious as to Y X doesn't 'automatically'
perform this flushing when the output buffer becomes a certain
size.   Or in his own words....

 Why would not calling XFlush() cause things to hang? I can
understand why things wouldn't show up on the screen right away,
but one would think that as the buffer filled, X would flush it
to make more room for new requests. In that case, the output would
be displayed late, and in sudden starts and stops, but it would
continue to work...


Anyone have any ideas ???

Thanks....

-jg

666.22Nothing happens until the application causes the server to deliver the first event.IO::MCCARTNEYJames T. McCartney III - DTN 381-2244 ZK02-2/N24Tue May 02 1989 21:0010
It's quite possible that the command to map the window never actually got 
sent to the display. If this is indeed the case, then the server would never
create the window, never deliver any exposures and you would wait in the 
mainline loop at the fprintf until the world ends. 

The Xflush forces the map window command to be presented to the server. From
there everything becomes steady state and totally event driven.	

James

666.23It doesDECWIN::FISHERBurns Fisher 381-1466, ZKO3-4/W23Thu May 04 1989 15:4911
    Xlib DOES flush automatically when the buffer fills up.  It also
    flushes if you do an XNextEvent, which is considered the "normal" way
    to work with an X client.  However, XSelectAsyncEvent (or for that
    matter using Select in Unix) does not flush.  Select certainly can't.
    It is not an X routine.  XSelectAsyncEvent does not block, so it does
    not make much sense to make it flush.  In these kinds of cases, you
    have to use XFlush.
    
    Burns