[GRASS5] hunting KDE/Xdriver redraw problem

Glynn Clements glynn.clements at virgin.net
Tue May 15 23:59:35 EDT 2001


Eric G. Miller wrote:

> > currently Glynn and me are hunting a KDE/Xdriver problem related to the new
> > auto-redraw feature of Xdriver. Perhaps someone here has a hint for us...
> > 
> > If displaying a raster map and one or more vector maps, now resize the GRASS
> > monitor with a mouse, sometimes the vector maps disappear (so auto-redraw
> > doesn't work properly). The raster map is mostly there. This only appears on
> > KDE while Xdriver runs well on GNOME windows manager.
> > Difference between KDE and GNOME:
> >  - KDE immediately redraws window contents when resizing
> >  - GNOME waits until the mouse button is released (only shows
> >    a moving frame without contents, then redraws contents after
> >    window got settled)
> > 
> > The KDE way leads to problems. Adding a sleep(1) before redrawing helps
> > a bit but isn't perfect. Any other ideas? Could we catch the 
> > mouse-button-release event and then redraw?
> > 
> > And: The problem only seems to appear, when resizing, while the redraw
> > is ongoing (means: two resizes quickly following each other). Perhaps
> > the redraw order is confused: vector first, then raster which would make
> > the vectors invisible?
> 
> I don't remember if I committed some changes I was working on regarding
> processing Xevents, but the scenario is like:
> 
> If the window manager uses a rubber-band box for moving/resizing
> windows, then it only generates one Expose event.  If the window manager
> uses opaque moving/resizing it is likely to queue up a whole bunch of
> Expose events.  Ahh, I see that should be handled... 

Do you mean ConfigureNotify?

> Now, on the pad thing, what I see is at the end of handleResizeEvent()
> there are two forks() and one waitpid().  Inside the inner fork is a
> loop that shells out the items from PAD.  So, if I'm understanding
> correctly, the second fork() returns in the parent which then does
> exit(0) whereby the waitpid() returns and the function finishes.

Actually, it's the short-lived child of the first fork() that is
reaped by waitpid; the parent process has to get back to event
processing otherwise you get deadlock.

> The
> inner forked process is meanwhile trying to shell out the PAD items, but
> if another resize event comes in while the shelled commands are pending,
> then a second go around of this occurs.  However in the second go
> around, some pad items never get redrawn (and hence added to the PAD
> again).  If you add a third resize while the second is running, you
> really start to lose pad items.  I just tested this and indeed I lose
> the vector if I do three resizes (where there's one large raster and one
> vector originally).  So we have a race going on (go speed racer!).

I'm pretty sure that this is it; resize events won't be handled while
a client is connected, but they will be handled between clients.

> I don't see any easy solution.  Maybe that's why someone way back when
> decided a resize event would clear the screen and the pad contents...
> 
> Hmm, what if there was a way to handle the resize without deleting the
> pad contents?  I don't know if this would work (probably not):  In
> theory, when a drawing command is shelled out on the resize, a new pad
> item should be added that is identical to the old pad item.  So, what if
> adding a pad item first checked if it matched an existing item.  If so,
> it just increments a counter for that item.  Periodically (say, in
> do_events()) we look at the pad list to see if all of the counts are the
> same.  If they aren't, then some commands were lost and need to be
> recreated.  Hmm, no I guess you'd never lose commands in that
> scenario.  They'd just end up drawn all weird and the server would never
> know.
> 
> Hmm, maybe having a "saved" pad and a "current" pad? I'll stop now ;)

I think that XDRIVER will have to do proper process management. The
existing code is really just proof-of-concept.

The first draft only did a single fork(), which left the child
processes as zombies. The double-fork was a quick hack to get around
this (now, by the time the grandchild dies, its parent is long gone,
so it will get reaped by init).

This is the "fire-and-forget" approach, but it clearly isn't going to
work. The main process needs to keep track of the processes which are
spawned for redraw, and not spawn a new process while a previous
process is still active.

Also, it would ideally only accept connections from the redraw
commands whilst a redraw operation was in progress. However, this
would require the platform to support getsockopt(SO_PEERCRED). 
Otherwise, there would be problems if a user resized the window whilst
running a script containing GRASS display commands.

-- 
Glynn Clements <glynn.clements at virgin.net>

---------------------------------------- 
If you want to unsubscribe from GRASS Development Team mailing list write to:
minordomo at geog.uni-hannover.de with
subject 'unsubscribe grass5'



More information about the grass-dev mailing list