|
From: Daniel J S. <dan...@ie...> - 2006-04-10 18:10:50
|
Dave Denholm wrote: > Daniel J Sebald <dan...@ie...> writes: > > >>Dave Denholm wrote: >> >> >>>Beware that the x protocol (and so xlib) is mostly >>>asynchronous. Errors are usually sent asynchronously, like events. >>>It is possible to handle errors, just a little messy. I forget the >>>details, but you can use XSync() to force a round-trip to the >>>server. This way, you can guarantee that all errors have been >>>delivered for requests up to the sync. > > >>I'm somewhat familiar with XSetErrorHandler. >> >>Not sure this is directly related to the problem though. Could be. >> > > > I was replying mainly to > > >>>Shouldn't you just get an error return from the call to XSelectInput? > > > Just pointing out that xlib fns don't usually return errors. The error > gets delivered later. I hear you. In thinking mode right now. > > > I've just had a look at the 4.0 X code (that's the latest source tree > I happen to have lying around) > > One thing that looks a bit odd : in DrawRotated, it has > > prevErrorHandler = XSetErrorHandler(DrawRotatedErrorHandler); > > ... > > XSetErrorHandler(prevErrorHandler); > > However, because errors are delivered asynchronously, but > XSetErrorHandler is synchronous, the chances are that you are going to > remove the error handler before the errors have been delivered. You > probably need to either leave the error handler plumbed in > permanently, and use sequence numbers to figure out what to do, or do > an XSync() before removing the error handler. But this may have > changed since 4.0 Got me on that one. I don't know where this use of XSetErrorHandler comes from. (Can't recall it from when I worked on that aspect of the system.) I was referring to the other use of ErrorHandler in the code, dealing with safe removal of a plot from the list. > > > I also disagree with the comments about > > /* NOTE: The removing of plots via the ErrorHandler routine is rather > tricky. The error events can happen at any time during execution of > the program, very similar to an interrupt. I think it is. I spent a lot of time on that code trying to dream up a safe way of maintaining the list. > > It's nowhere near as bad as that. The errors can only be delivered to > the program when xlib is actually reading from the socket. That can > only happen either when it is waiting for a reply to a round-trip > request, or when you are reading events. I'm not sure that implies the problem doesn't exist. The issue is the following. The ErrorHandler is called in response to the "close window" or "destroy window" (whatever it is called) that comes from the system by pressing that little box with an x in it at the top right corner. The core code of gplt_x11.c has pointers to elements in the linked list of plots. If ErrorHandler asynchronously removes a plot from the linked list and the core code uses its pointer to attempt drawing or whatnot, it's a seg fault. I tried many simpler solutions before the "queuing" approach, but seg faults were consistently happening on occasion. It's the maintaining of the list that is the tricky part. The bottom line, I think, is to make it so that the core code is the one to remove plots from the linked list. And even with that concept, it isn't simple to make sure things aren't lost or repeated in the queue. Dan |
|
From: Dave D. <dde...@es...> - 2006-04-11 11:01:00
|
Daniel J Sebald <dan...@ie...> writes: >> I also disagree with the comments about >> /* NOTE: The removing of plots via the ErrorHandler routine is >> rather >> tricky. The error events can happen at any time during execution of >> the program, very similar to an interrupt. > > I think it is. I spent a lot of time on that code trying to dream > up a safe way of maintaining the list. > >> It's nowhere near as bad as that. The errors can only be delivered to >> the program when xlib is actually reading from the socket. That can >> only happen either when it is waiting for a reply to a round-trip >> request, or when you are reading events. > > I'm not sure that implies the problem doesn't exist. The issue is > the following. The ErrorHandler is called in response to the "close > window" or "destroy window" (whatever it is called) that comes from > the system by pressing that little box with an x in it at the top > right corner. Well, that's true at a high level, but you have missed many important details. When you close the window, the window manager may send the app a request to close the window, or it may just delete the window. That will trigger some events to the app to tell you it has closed. (It depends on whether you add a property that tells the window manager that you want to handle the close yourself.) eg if I run xprop on my firefox window, I see WM_PROTOCOLS(ATOM): protocols WM_DELETE_WINDOW, WM_TAKE_FOCUS I think that's the one that tells the window manager I want to be told about closes. Ah - I see gnuplot sets the WM_DELETE_WINDOW hint too. So that means that the window shouldn't get closed abruptly by a compliant window manager. If the app ignores these events, and continues to send requests which mention this window (or if there were requests in transit, since the protocol is asynchronous), that will trigger errors to be sent to the application. But the error handler is not invoked until the application reads them from the socket (from a getnextevent call or similar). And that should only happen under the control of the app. if you put a breakpoint on the error handler, and look at the call stack when it is invoked, it should always be from a fn that reads the network. I guess the only time it could be asynchronous is if you are using a multi-threaded version of xlib. dd -- Dave Denholm <dde...@es...> http://www.esmertec.com |
|
From: Daniel J S. <dan...@ie...> - 2006-04-11 18:21:18
|
Dave Denholm wrote: > Daniel J Sebald <dan...@ie...> writes: > > >>>I also disagree with the comments about >>>/* NOTE: The removing of plots via the ErrorHandler routine is >>>rather >>> tricky. The error events can happen at any time during execution of >>> the program, very similar to an interrupt. >> >>I think it is. I spent a lot of time on that code trying to dream >>up a safe way of maintaining the list. >> >> >>>It's nowhere near as bad as that. The errors can only be delivered to >>>the program when xlib is actually reading from the socket. That can >>>only happen either when it is waiting for a reply to a round-trip >>>request, or when you are reading events. >> >>I'm not sure that implies the problem doesn't exist. The issue is >>the following. The ErrorHandler is called in response to the "close >>window" or "destroy window" (whatever it is called) that comes from >>the system by pressing that little box with an x in it at the top >>right corner. > > > Well, that's true at a high level, but you have missed many important > details. Dave, you obviously know much more about X than I. I mean, I looked at plenty of the documentation, fooled around with xprop, watched for messages, etc., but I think that unless a person really understands the concept of what the system core of X is doing, it's a case of addressing the problem with a programming solution as opposed to setting up the X communication appropriately. It sounds like you are thinking that the window could be configured to have that "close button" send the window an event like any other so that the core can just simply take care of it, as opposed to that notification coming back through ErrorHandler. If you want to look at this, go ahead. Things don't crash so watching communication shouldn't be too bad. (It's when it continually crashes that it is no fun.) I could help but it would have to be in the middle of this summer some time. Dan > > When you close the window, the window manager may send the app a > request to close the window, or it may just delete the window. That > will trigger some events to the app to tell you it has closed. (It > depends on whether you add a property that tells the window manager > that you want to handle the close yourself.) > > eg if I run xprop on my firefox window, I see > > WM_PROTOCOLS(ATOM): protocols WM_DELETE_WINDOW, WM_TAKE_FOCUS > > > I think that's the one that tells the window manager I want to be told > about closes. > > Ah - I see gnuplot sets the WM_DELETE_WINDOW hint too. So that means > that the window shouldn't get closed abruptly by a compliant window > manager. > > > If the app ignores these events, and continues to send requests which > mention this window (or if there were requests in transit, since the > protocol is asynchronous), that will trigger errors to be sent to the > application. > > But the error handler is not invoked until the application reads them > from the socket (from a getnextevent call or similar). And that should > only happen under the control of the app. > > if you put a breakpoint on the error handler, and look at the call > stack when it is invoked, it should always be from a fn that reads the > network. > > > I guess the only time it could be asynchronous is if you are using a > multi-threaded version of xlib. > > > dd |
|
From: Dave D. <dde...@es...> - 2006-04-11 19:03:21
|
Daniel J Sebald <dan...@ie...> writes:
> Dave Denholm wrote:
>> Daniel J Sebald <dan...@ie...> writes:
>>
>>>>I also disagree with the comments about
>>>>/* NOTE: The removing of plots via the ErrorHandler routine is
>>>>rather
>>>> tricky. The error events can happen at any time during execution of
>>>> the program, very similar to an interrupt.
>>>
>>>I think it is. I spent a lot of time on that code trying to dream
>>> up a safe way of maintaining the list.
>>>>It's nowhere near as bad as that. The errors can only be delivered to
>>>>the program when xlib is actually reading from the socket. That can
>>>>only happen either when it is waiting for a reply to a round-trip
>>>>request, or when you are reading events.
>>>
>>>I'm not sure that implies the problem doesn't exist. The issue is
>>>the following. The ErrorHandler is called in response to the "close
>>>window" or "destroy window" (whatever it is called) that comes from
>>>the system by pressing that little box with an x in it at the top
>>>right corner.
>> Well, that's true at a high level, but you have missed many important
>> details.
>
> Dave, you obviously know much more about X than I. I mean, I looked
> at plenty of the documentation, fooled around with xprop, watched
> for messages, etc., but I think that unless a person really
> understands the concept of what the system core of X is doing, it's
> a case of addressing the problem with a programming solution as
> opposed to setting up the X communication appropriately.
>
I used to do a lot of work at the x protocol level. (google for
ntrigue or wincenter if you are interested). We didn't have xlib, so
we were working directly at the packet level.
A really useful tool is "xmon" : comes in two parts, which you pipe
together :
xmonui | xmond
(slightly weird). Xmonui puts up a gui, and sends commands out on
stdout. xmond is the actual protocol monitor, reading config from
stdin. It tends to get confused by the many X extensions,
unfortunately. I think there is a newer protocol monitor available now.
So with
$ xmonui | xmond -port 1 -server eclipse:0
$ DISPLAY=localhost:1 gnuplot
I then have gnuplot connecting through xmond and forward onto the real
X server on eclipse:0
> It sounds like you are thinking that the window could be configured
> to have that "close button" send the window an event like any other
> so that the core can just simply take care of it, as opposed to that
> notification coming back through ErrorHandler.
>
As far as I can see, we already have that property set.
I do 'test' in gnuplot, to create the X window. Then close it with the
window manager. On xmond I get the following output
....SYNTHETIC EVENT: ClientMessage
............REQUEST: NoOperation
............REQUEST: DestroyWindow
............REQUEST: FreePixmap
............REQUEST: FreePixmap
............REQUEST: FreePixmap
............REQUEST: FreePixmap
............REQUEST: FreePixmap
............REQUEST: FreePixmap
............REQUEST: FreePixmap
............REQUEST: FreePixmap
............REQUEST: FreePixmap
............REQUEST: FreePixmap
............REQUEST: FreePixmap
............REQUEST: FreePixmap
............REQUEST: FreePixmap
............REQUEST: FreePixmap
..............EVENT: UnmapNotify
..............EVENT: DestroyNotify
............REQUEST: NoOperation
so the window manager sent a synthetic ClientMessage event to gnuplot,
reporting that I had attempted to close the window. In turn gnuplot
asked for the window to be destroyed. There were no errors generated
anywhere. (I'm using an old solaris CDE system, BTW).
It was presumably the code in gnuplot
case ClientMessage:
if (event->xclient.message_type == WM_PROTOCOLS &&
event->xclient.format == 32 && event->xclient.data.l[0] == WM_DELETE_WINDOW) {
Remove_Plot_From_Linked_List(event->xclient.window);
}
that deleted the window. And of course this definely happens synchronously.
However, that assumes an ICCCM-compliant window manager.
I tried using xprop to delete the WM_PROTOCOLS property from the
window. But then when I tried closing the window, the server dropped
the connection completely, rather than just closing the window. Window
manager probably did an XKillClient() which is what xkill does.
So I'm still not sure what errors you actually got. So I'd be
reluctant to change working code without being able to reproduce the
scenario you were seeing.
dd
--
Dave Denholm <dde...@es...> http://www.esmertec.com
|
|
From: Daniel J S. <dan...@ie...> - 2006-04-11 22:19:15
|
Dave Denholm wrote: > Daniel J Sebald <dan...@ie...> writes: > > >>Dave Denholm wrote: >> >>>Daniel J Sebald <dan...@ie...> writes: >>> >>> >>>>>I also disagree with the comments about >>>>>/* NOTE: The removing of plots via the ErrorHandler routine is >>>>>rather >>>>> tricky. The error events can happen at any time during execution of >>>>> the program, very similar to an interrupt. >>>> >>>>I think it is. I spent a lot of time on that code trying to dream >>>>up a safe way of maintaining the list. >>>> >>>>>It's nowhere near as bad as that. The errors can only be delivered to >>>>>the program when xlib is actually reading from the socket. That can >>>>>only happen either when it is waiting for a reply to a round-trip >>>>>request, or when you are reading events. >>>> >>>>I'm not sure that implies the problem doesn't exist. The issue is >>>>the following. The ErrorHandler is called in response to the "close >>>>window" or "destroy window" (whatever it is called) that comes from >>>>the system by pressing that little box with an x in it at the top >>>>right corner. >>> >>>Well, that's true at a high level, but you have missed many important >>>details. >> >>Dave, you obviously know much more about X than I. I mean, I looked >>at plenty of the documentation, fooled around with xprop, watched >>for messages, etc., but I think that unless a person really >>understands the concept of what the system core of X is doing, it's >>a case of addressing the problem with a programming solution as >>opposed to setting up the X communication appropriately. >> > > > I used to do a lot of work at the x protocol level. (google for > ntrigue or wincenter if you are interested). We didn't have xlib, so > we were working directly at the packet level. > > A really useful tool is "xmon" : comes in two parts, which you pipe > together : > > xmonui | xmond > > (slightly weird). Xmonui puts up a gui, and sends commands out on > stdout. xmond is the actual protocol monitor, reading config from > stdin. It tends to get confused by the many X extensions, > unfortunately. I think there is a newer protocol monitor available now. > > So with > > $ xmonui | xmond -port 1 -server eclipse:0 > > $ DISPLAY=localhost:1 gnuplot > > I then have gnuplot connecting through xmond and forward onto the real > X server on eclipse:0 You are way above my skill level on this. > So I'm still not sure what errors you actually got. So I'd be > reluctant to change working code without being able to reproduce the > scenario you were seeing. You are probably right on that. (In fact, you are. I've just searched back through emails and patches.) Maybe it wasn't the x-box that caused the error directly. I see there is another way to Remove_Plot_From_Linked_List(event->xkey.window) inside process events. I can't recall now the circumstance when the system issues an error. It seemed common, an I must have been doing it fairly easily in order to test things. Who knows, maybe when I first looked at it the "close" event option wasn't set up right so it may have been the scenario you suggested, i.e., X loopbacks an error because of the mishandled "close". Perhaps in the meantime it was fixed and I figured to just let the error handler stay as is. Ethan and I had some conversation about XKill, but that doesn't ring a bell. Can you think of any other way to close an Xwindow? Maybe this chunk of error handling code is no longer relevant. ... BTW, I see that this prevErrorHandler = XSetErrorHandler(DrawRotatedErrorHandler); [snip] XSetErrorHandler(prevErrorHandler); construct is probably to avoid queueing the plot for destruction in the case of an error generated by an X font problem. A better way of doing that would probably simply be to add a selective condition in the above ErrorHandler based upon error_event. Dan |
|
From: Dave D. <dde...@es...> - 2006-04-10 16:05:37
|
Daniel J Sebald <dan...@ie...> writes: > Ethan A Merritt wrote: >> On Sunday 09 April 2006 05:14 pm, Daniel J Sebald wrote: >> >>>For an X11 window there can't be two clients desiring the ButtonPress >>>event at the same times. >> >>> The external client that created the window may or may not have >>> requested ButtonPress via ButtonPressMask. >> That would clearly be a programming error. Why open a window for >> the purpose >> of displaying gnuplot output, and then fail to let gnuplot have access to the >> window events? > > Well, not necessarily. Maybe someone likes the cursor position > information but wants a button press to be interpreted by the parent > application to load some new data and replot. I don't know. It > boils down to what can accomplish. Can't defy X11 behavior. If > there were no documentation about this option, it would be likely > the programmer of the outside application might never understand the > problem even though it may be their "error". > I think another option is to create an InputOnly window over the output window. That will probably give you first dibs at any events. (Since it's a separate window, it can have different event flags.) However, if the user had a reason for denying you events, just forcibly taking them is probably not kosher. dd -- Dave Denholm <dde...@es...> http://www.esmertec.com |
|
From: Daniel J S. <dan...@ie...> - 2006-04-10 04:18:41
|
Ethan A Merritt wrote: > I thought of another issue with this patch that is worth > some discussion. > > What should happens if you type 'q' or 'ctrl-q' in the exterior > application window? As it stands now, this seems to close the > window or at least disconnect gnuplot from it. > But that is probably not such a great idea if it really is somebody > else's window, and gnuplot is just a guest. I am inclined to say > that when gnuplot_x11 is running in this guest mode, the 'quit' > hotkey should be disabled. Maybe some of the other hotkeys as well. Good point. It would be nice to get this all under one "mouse" category. After the next revision let's think if there is some better way to handle the de/activation of ButtonRelease. Dan |
|
From: Petr M. <mi...@ph...> - 2006-04-10 08:49:09
|
>> What should happens if you type 'q' or 'ctrl-q' in the exterior >> application window? As it stands now, this seems to close the >> window or at least disconnect gnuplot from it. >> But that is probably not such a great idea if it really is somebody >> else's window, and gnuplot is just a guest. I am inclined to say >> that when gnuplot_x11 is running in this guest mode, the 'quit' >> hotkey should be disabled. Maybe some of the other hotkeys as well. > > Good point. It would be nice to get this all under one "mouse" category. 'q' and 'ctrl-q' should be disabled during "pause mouse" (e.g. "pause mouse any" should return 'q' if you pressed 'q'). Any idea how to change x11's accordingly? --- PM |