[comp.windows.x] Xt Problem [XtDispatchEvent

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