klee@daisy.UUCP (Ken Lee) (02/14/89)
In article <8902131528.AA02626@tub.UUCP> net@TUB.BITNET (Oliver Laumann) writes: > XtDispatchEvent() is not re-entrant. According to Paul Asente, XtDispatchEvent is fully reentrant in X11R3. Ken Lee -- klee@daisy.uucp Daisy Systems Corp., Interactive Graphics Tools Dept.
net@TUB.BITNET (Oliver Laumann) (02/16/89)
> > XtDispatchEvent() is not re-entrant. > > According to Paul Asente, XtDispatchEvent is fully reentrant in X11R3. But it isn't. XtDispatchEvent() sets a global variable to point to a local variable in the line reading _XtDestroyList = &destroyList; (destroyList is a local variable of XtDispatchEvent()). The value of _XtDestroyList is restored at the end of XtDispatchEvent(). When XtDispatchEvent() is left via a non-local goto (e.g. by calling longjmp() from within a callback), the value of _XtDestroyList becomes meaningless. This can cause a subsequent call to XtDestroyWidget() to produce a segmentation fault or bus error. Am I missing something? Oh, by the way, the line preceding the one quoted above in Event.c is a comment reading "This is pretty gross.". Regards, -- Oliver Laumann net@TUB.BITNET net@tub.UUCP
asente@decwrl.dec.com (Paul Asente) (02/17/89)
In article <8902161223.AA01554@tub.UUCP> net@TUB.BITNET (Oliver Laumann) writes: >> > XtDispatchEvent() is not re-entrant. >> >> According to Paul Asente, XtDispatchEvent is fully reentrant in X11R3. > >But it isn't. Well, sort of. I the R2 intrinsics, XtDispatchEvent wasn't at all reentrant. This meant that if you were in the middle of some event handler or action procedure and you decided to go into recursive event handling, you were completely hosed. The R3 intrinsics fixed this, so you could call XtDispatchEvent recursively. But there's still the problem of the destroy list. The intrinsics do a two-phase destroy process so your widgets don't vanish out from under you at inconvenient times, making it much easier to call XtDestroyWidget from almost anywhere. This entails keeping a list somewhere of the widgets that need to be destroyed, and it has to be global. Also, in earlier versions of the intrinsics, the second phase of destroy wasn't invoked until the beginning of the next check for X events. This meant that sometimes the destroyed widgets hung around for a very long time before actually going away. We decided it needed to be moved to the end of the dispatch procedure. But this presented a problem. If you were in a recursive dispatch, and just deleted everything on the destroy list at the end of XtDispatchEvent, you might destroy some things from earlier dispatches that weren't yet safe to destroy. So XtDispatchEvent creates a stack of destroy lists and just destroys those widgets for the current event dispatch. The easiest way to do this was to use local variables and the call stack. If you can provide us with a version of XtDispatchEvent which still provides this functionality and is more reentrant, I'm sure we'd be glad to take it. >Oh, by the way, the line preceding the one quoted above in Event.c >is a comment reading "This is pretty gross.". Now you know why... -paul asente asente@decwrl.dec.com decwrl!asente
sundar@WHEATIES.AI.MIT.EDU (Sundar Narasimhan) (02/19/89)
Thanks for that explanation. I've always wondered why my recursive calls to XtDispatchEvent were so slow sometimes. (I am still annoyed by the unpredictability of the time it takes -- there should be a faster way to do this if I can guarantee that I wont have any calls that destroy widgets in my recursive call to DispatchEvent, no?) -Sundar
asente@decwrl.dec.com (Paul Asente) (02/20/89)
In article <8902182246.AA08494@special-k.ai.mit.edu> sundar@WHEATIES.AI.MIT.EDU (Sundar Narasimhan) writes: >Thanks for that explanation. I've always wondered why my recursive calls to >XtDispatchEvent were so slow sometimes. (I am still annoyed by >the unpredictability of the time it takes -- there should be a faster >way to do this if I can guarantee that I wont have any calls that >destroy widgets in my recursive call to DispatchEvent, no?) > >-Sundar Well, if you don't have any destroys to execute, all that's happening is a few assignments and a check if the destroy list is NULL. If your dispatches are taking longer sometimes, and you aren't destroying anything, it's coming from someplace else -- possibly large translation tables, or the keyboard focus mechanism's cache failing (keyboard events usually come in for the same widget they just came in for, so the intrinsics can cache the focus widget and use that unless the set of keyboard focus directives has changed or the event comes in for a different widget). Hope this helps... -paul asente asente@decwrl.dec.com decwrl!asente