[prev in list] [next in list] [prev in thread] [next in thread] 

List:       wine-devel
Subject:    RE: EventExpose race condition problem
From:       "Stephane Lussier" <stephane () macadamian ! com>
Date:       2000-06-28 13:16:18
[Download RAW message or body]



Gerard wrote:
> That's a problem I was hoping to  tackle some time (lot of more urgent
> problems in the stack); my first idea was rather to flag the
> windows to be 'in painting',
> test the flag in the event code and just pass on the redrawwindow
> call; what do you
> think of this approach ? (I did not even think to begin a
> preliminary trial
> version so maybe there is an obvious fatal flaw...)
>

I'm not sure, I correctly understand your idea. Where do you plan to set
your 'in painting' flag? In BeginPaint?

When the service thread process the expose event, it is possible the
application hasn't started to repaint the window, and you'll do the
RedrawWindow() call and you still have chance to end out with the window
being erased.

The problem is the application thread and the service thread are both trying
to paint on the window without any synchronization. Let me describe again
the order of events:

1. Service thread process an Expose event
2. Service thread call ReDrawWindow
2a.       Service thread invalidate the window
2b.       Service thread send a message to the application thread to erase
the background.

2b is inter-thread send-message, so the message won't be process until the
application do a GetMessage/PeekMessage.

3. Application thread is now running, and eventually could decide to repaint
the window, which will validate the window.
4. Application thread do a GetMessage()
5. Pending inter-thread SendMessage is executed, and the background is
erased.


I think a better approach to avoid the extra repaint (and possibly remove
some flickers) will be to use WM_SYNCPAINT message.

On an ExposeEvent:
a. Service thread invalidate the expose event.
b. Send a WM_SYNCPAINT message to the application. lParam is pointing on the
expose rectangle.

On reception of an WM_SYNCPAINT in def window proc:
a. Check if the rectangle pointed by lParam is still part of the invalid
region (or update region)
b. If so, erase the background (WM_ERASEBKGND) and repaint the non client
area (WM_NCPAINT)

With this solution, the WM_ERASEBKGND and WM_NCPAINT, will always be sent by
the application thread, and we should avoid the race condition.

I must admit, because of the lack of documentation on WM_SYNCPAINT, I'm not
quite sure it's exactly the way this message should be used. Probably one
day, I'll implement this, if nobody tries to do it before, but I'm like you,
I've got more urgent problem to deal with. For now I think it's better to
repaint twice (in very few occasions) that having a blank window.

	Stephane Lussier
	Macadamian Technologies

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic