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 |
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.R | Title | User | Personal Name | Date | Lines |
---|---|---|---|---|---|
666.1 | FLUME::dike | Tue Apr 25 1989 09:37 | 8 | ||
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.2 | uses SIGIO | CRLVMS::HALBERT | CRL, Trellis | Tue Apr 25 1989 10:55 | 4 |
XSelectAsyncInput uses the SIGIO signal on Ultrix. If your customer is already using this for something use, bad things can (will?) happen. --Dan | |||||
666.3 | FLUME::dike | Tue Apr 25 1989 14:11 | 8 | ||
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.4 | question | KOBAL::VANNOY | Jake VanNoy | Wed Apr 26 1989 10:12 | 11 |
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.5 | FLUME::dike | Wed Apr 26 1989 14:00 | 9 | ||
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.6 | Server hang because of the client not reading? | DECWIN::FISHER | Burns Fisher 381-1466, ZKO3-4/W23 | Wed Apr 26 1989 14:27 | 6 |
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.7 | FLUME::dike | Wed Apr 26 1989 14:36 | 3 | ||
The server will not hang. The server will drop the connection. Jeff | |||||
666.8 | it may hang, but only temporarily | PSW::WINALSKI | Paul S. Winalski | Wed Apr 26 1989 14:55 | 5 |
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.9 | FLUME::dike | Wed Apr 26 1989 17:32 | 4 | ||
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.10 | XNextEvent in AST callback for PMAX... | LDP::GABRIEL | Thank You Very Little | Wed Apr 26 1989 21:54 | 42 |
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.11 | PSW::WINALSKI | Paul S. Winalski | Wed Apr 26 1989 22:35 | 8 | |
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.12 | FLUME::dike | Thu Apr 27 1989 09:29 | 8 | ||
.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.13 | 2702::WINALSKI | Paul S. Winalski | Thu Apr 27 1989 15:50 | 12 | |
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.14 | But did X10 do it right? | IO::MCCARTNEY | James T. McCartney III - DTN 381-2244 ZK02-2/N24 | Fri Apr 28 1989 18:57 | 9 |
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.15 | FLUME::dike | Sat Apr 29 1989 10:39 | 4 | ||
It must be the VMS server, because I've done my share of debugging DECwindows programs, and I've never seen it. Jeff | |||||
666.16 | events.c | LDP::GABRIEL | Thank You Very Little | Sun Apr 30 1989 16:16 | 203 |
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.17 | Bad user on device? | VEENA::thomas | The Code Warrior | Sun Apr 30 1989 17:26 | 8 |
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.18 | FLUME::dike | Mon May 01 1989 09:47 | 5 | ||
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.19 | Commented out XNextEvent and... | LDPMAX::gabriel | Thank You Very Little | Mon May 01 1989 15:02 | 9 |
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.20 | STAR::BRANDENBERG | Si vis pacem para bellum | Mon May 01 1989 16:08 | 3 | |
Xflush() the display. | |||||
666.21 | LDPMAX::gabriel | Thank You Very Little | Tue May 02 1989 19:06 | 21 | |
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.22 | Nothing happens until the application causes the server to deliver the first event. | IO::MCCARTNEY | James T. McCartney III - DTN 381-2244 ZK02-2/N24 | Tue May 02 1989 21:00 | 10 |
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.23 | It does | DECWIN::FISHER | Burns Fisher 381-1466, ZKO3-4/W23 | Thu May 04 1989 15:49 | 11 |
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 |