mirror of
https://github.com/reactos/reactos.git
synced 2024-12-26 17:14:41 +00:00
Fix race condition when one thread changes the update region of a window
and another thread retrieves a paint message for that window. svn path=/trunk/; revision=8033
This commit is contained in:
parent
969bf0b926
commit
8fdb9cdcc1
3 changed files with 25 additions and 6 deletions
|
@ -59,6 +59,8 @@ typedef struct _WINDOW_OBJECT
|
||||||
/* Handle of region of the window to be updated. */
|
/* Handle of region of the window to be updated. */
|
||||||
HANDLE UpdateRegion;
|
HANDLE UpdateRegion;
|
||||||
HANDLE NCUpdateRegion;
|
HANDLE NCUpdateRegion;
|
||||||
|
/* Lock to be held when manipulating (NC)UpdateRegion */
|
||||||
|
FAST_MUTEX UpdateLock;
|
||||||
/* Pointer to the owning thread's message queue. */
|
/* Pointer to the owning thread's message queue. */
|
||||||
PUSER_MESSAGE_QUEUE MessageQueue;
|
PUSER_MESSAGE_QUEUE MessageQueue;
|
||||||
struct _WINDOW_OBJECT* FirstChild;
|
struct _WINDOW_OBJECT* FirstChild;
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*
|
*
|
||||||
* $Id: painting.c,v 1.66 2004/02/03 17:53:55 navaraf Exp $
|
* $Id: painting.c,v 1.67 2004/02/04 23:01:07 gvg Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -52,7 +52,7 @@
|
||||||
#include <include/intgdi.h>
|
#include <include/intgdi.h>
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <win32k/debug1.h>
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS **********************************************************/
|
/* PRIVATE FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
|
@ -68,6 +68,7 @@ IntValidateParent(PWINDOW_OBJECT Child, HRGN ValidRegion)
|
||||||
ParentWindow = IntGetWindowObject(Parent);
|
ParentWindow = IntGetWindowObject(Parent);
|
||||||
if (ParentWindow && !(ParentWindow->Style & WS_CLIPCHILDREN))
|
if (ParentWindow && !(ParentWindow->Style & WS_CLIPCHILDREN))
|
||||||
{
|
{
|
||||||
|
ExAcquireFastMutex(&ParentWindow->UpdateLock);
|
||||||
if (ParentWindow->UpdateRegion != 0)
|
if (ParentWindow->UpdateRegion != 0)
|
||||||
{
|
{
|
||||||
INT OffsetX, OffsetY;
|
INT OffsetX, OffsetY;
|
||||||
|
@ -84,6 +85,7 @@ IntValidateParent(PWINDOW_OBJECT Child, HRGN ValidRegion)
|
||||||
/* FIXME: If the resulting region is empty, remove fake posted paint message */
|
/* FIXME: If the resulting region is empty, remove fake posted paint message */
|
||||||
NtGdiOffsetRgn(ValidRegion, -OffsetX, -OffsetY);
|
NtGdiOffsetRgn(ValidRegion, -OffsetX, -OffsetY);
|
||||||
}
|
}
|
||||||
|
ExReleaseFastMutex(&ParentWindow->UpdateLock);
|
||||||
}
|
}
|
||||||
IntReleaseWindowObject(ParentWindow);
|
IntReleaseWindowObject(ParentWindow);
|
||||||
Parent = NtUserGetAncestor(Parent, GA_PARENT);
|
Parent = NtUserGetAncestor(Parent, GA_PARENT);
|
||||||
|
@ -104,12 +106,14 @@ IntValidateParent(PWINDOW_OBJECT Child, HRGN ValidRegion)
|
||||||
* as valid, clears the WINDOWOBJECT_NEED_NCPAINT flag.
|
* as valid, clears the WINDOWOBJECT_NEED_NCPAINT flag.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
HRGN FASTCALL
|
STATIC HRGN FASTCALL
|
||||||
IntGetNCUpdateRegion(PWINDOW_OBJECT Window)
|
IntGetNCUpdateRegion(PWINDOW_OBJECT Window)
|
||||||
{
|
{
|
||||||
HRGN WindowRgn;
|
HRGN WindowRgn;
|
||||||
HRGN NonclientRgn;
|
HRGN NonclientRgn;
|
||||||
|
|
||||||
|
ASSERT(! ExTryToAcquireFastMutex(&Window->UpdateLock));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generate the update region.
|
* Generate the update region.
|
||||||
*/
|
*/
|
||||||
|
@ -148,7 +152,7 @@ IntGetNCUpdateRegion(PWINDOW_OBJECT Window)
|
||||||
* Internal function used by IntRedrawWindow.
|
* Internal function used by IntRedrawWindow.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
VOID FASTCALL
|
STATIC VOID FASTCALL
|
||||||
IntPaintWindows(PWINDOW_OBJECT Window, ULONG Flags)
|
IntPaintWindows(PWINDOW_OBJECT Window, ULONG Flags)
|
||||||
{
|
{
|
||||||
HDC hDC;
|
HDC hDC;
|
||||||
|
@ -163,6 +167,7 @@ IntPaintWindows(PWINDOW_OBJECT Window, ULONG Flags)
|
||||||
{
|
{
|
||||||
if (Window->Flags & WINDOWOBJECT_NEED_NCPAINT)
|
if (Window->Flags & WINDOWOBJECT_NEED_NCPAINT)
|
||||||
{
|
{
|
||||||
|
ExAcquireFastMutex(&Window->UpdateLock);
|
||||||
if (Window->NCUpdateRegion)
|
if (Window->NCUpdateRegion)
|
||||||
{
|
{
|
||||||
IntValidateParent(Window, Window->NCUpdateRegion);
|
IntValidateParent(Window, Window->NCUpdateRegion);
|
||||||
|
@ -171,6 +176,7 @@ IntPaintWindows(PWINDOW_OBJECT Window, ULONG Flags)
|
||||||
Window->NCUpdateRegion = NULL;
|
Window->NCUpdateRegion = NULL;
|
||||||
Window->Flags &= ~WINDOWOBJECT_NEED_NCPAINT;
|
Window->Flags &= ~WINDOWOBJECT_NEED_NCPAINT;
|
||||||
MsqDecPaintCountQueue(Window->MessageQueue);
|
MsqDecPaintCountQueue(Window->MessageQueue);
|
||||||
|
ExReleaseFastMutex(&Window->UpdateLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Window->Flags & WINDOWOBJECT_NEED_ERASEBKGND)
|
if (Window->Flags & WINDOWOBJECT_NEED_ERASEBKGND)
|
||||||
|
@ -197,6 +203,7 @@ IntPaintWindows(PWINDOW_OBJECT Window, ULONG Flags)
|
||||||
Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT)
|
Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT)
|
||||||
{
|
{
|
||||||
IntSendMessage(hWnd, WM_PAINT, 0, 0);
|
IntSendMessage(hWnd, WM_PAINT, 0, 0);
|
||||||
|
ExAcquireFastMutex(&Window->UpdateLock);
|
||||||
if (Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT)
|
if (Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT)
|
||||||
{
|
{
|
||||||
Window->Flags &= ~WINDOWOBJECT_NEED_INTERNALPAINT;
|
Window->Flags &= ~WINDOWOBJECT_NEED_INTERNALPAINT;
|
||||||
|
@ -205,6 +212,7 @@ IntPaintWindows(PWINDOW_OBJECT Window, ULONG Flags)
|
||||||
MsqDecPaintCountQueue(Window->MessageQueue);
|
MsqDecPaintCountQueue(Window->MessageQueue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ExReleaseFastMutex(&Window->UpdateLock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -282,6 +290,7 @@ IntInvalidateWindows(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags)
|
||||||
* Save current state of pending updates
|
* Save current state of pending updates
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
ExAcquireFastMutex(&Window->UpdateLock);
|
||||||
HadPaintMessage = Window->UpdateRegion != NULL ||
|
HadPaintMessage = Window->UpdateRegion != NULL ||
|
||||||
Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT;
|
Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT;
|
||||||
HadNCPaintMessage = Window->Flags & WINDOWOBJECT_NEED_NCPAINT;
|
HadNCPaintMessage = Window->Flags & WINDOWOBJECT_NEED_NCPAINT;
|
||||||
|
@ -418,6 +427,8 @@ IntInvalidateWindows(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags)
|
||||||
else
|
else
|
||||||
MsqIncPaintCountQueue(Window->MessageQueue);
|
MsqIncPaintCountQueue(Window->MessageQueue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ExReleaseFastMutex(&Window->UpdateLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -614,15 +625,17 @@ IntGetPaintMessage(HWND hWnd, PW32THREAD Thread, MSG *Message,
|
||||||
#if 0
|
#if 0
|
||||||
DPRINT1("PAINTING BUG: Thread marked as containing dirty windows, but no dirty windows found!\n");
|
DPRINT1("PAINTING BUG: Thread marked as containing dirty windows, but no dirty windows found!\n");
|
||||||
#endif
|
#endif
|
||||||
/* FIXME: Lock the queue! */
|
ExAcquireFastMutex(&MessageQueue->Lock);
|
||||||
MessageQueue->PaintPosted = 0;
|
MessageQueue->PaintPosted = 0;
|
||||||
MessageQueue->PaintCount = 0;
|
MessageQueue->PaintCount = 0;
|
||||||
|
ExReleaseFastMutex(&MessageQueue->Lock);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Window = IntGetWindowObject(Message->hwnd);
|
Window = IntGetWindowObject(Message->hwnd);
|
||||||
if (Window != NULL)
|
if (Window != NULL)
|
||||||
{
|
{
|
||||||
|
ExAcquireFastMutex(&Window->UpdateLock);
|
||||||
if (Window->Flags & WINDOWOBJECT_NEED_NCPAINT)
|
if (Window->Flags & WINDOWOBJECT_NEED_NCPAINT)
|
||||||
{
|
{
|
||||||
Message->message = WM_NCPAINT;
|
Message->message = WM_NCPAINT;
|
||||||
|
@ -647,6 +660,7 @@ IntGetPaintMessage(HWND hWnd, PW32THREAD Thread, MSG *Message,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ExReleaseFastMutex(&Window->UpdateLock);
|
||||||
|
|
||||||
IntReleaseWindowObject(Window);
|
IntReleaseWindowObject(Window);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -724,6 +738,7 @@ NtUserBeginPaint(HWND hWnd, PAINTSTRUCT* lPs)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ExAcquireFastMutex(&Window->UpdateLock);
|
||||||
if (Window->UpdateRegion != NULL)
|
if (Window->UpdateRegion != NULL)
|
||||||
{
|
{
|
||||||
MsqDecPaintCountQueue(Window->MessageQueue);
|
MsqDecPaintCountQueue(Window->MessageQueue);
|
||||||
|
@ -739,6 +754,7 @@ NtUserBeginPaint(HWND hWnd, PAINTSTRUCT* lPs)
|
||||||
{
|
{
|
||||||
NtUserGetClientRect(Window, &lPs->rcPaint);
|
NtUserGetClientRect(Window, &lPs->rcPaint);
|
||||||
}
|
}
|
||||||
|
ExReleaseFastMutex(&Window->UpdateLock);
|
||||||
|
|
||||||
if (Window->Flags & WINDOWOBJECT_NEED_ERASEBKGND)
|
if (Window->Flags & WINDOWOBJECT_NEED_ERASEBKGND)
|
||||||
{
|
{
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: window.c,v 1.180 2004/02/04 01:10:25 rcampbell Exp $
|
/* $Id: window.c,v 1.181 2004/02/04 23:01:07 gvg Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -1251,6 +1251,7 @@ NtUserCreateWindowEx(DWORD dwExStyle,
|
||||||
InitializeListHead(&WindowObject->PropListHead);
|
InitializeListHead(&WindowObject->PropListHead);
|
||||||
ExInitializeFastMutex(&WindowObject->PropListLock);
|
ExInitializeFastMutex(&WindowObject->PropListLock);
|
||||||
ExInitializeFastMutex(&WindowObject->ChildrenListLock);
|
ExInitializeFastMutex(&WindowObject->ChildrenListLock);
|
||||||
|
ExInitializeFastMutex(&WindowObject->UpdateLock);
|
||||||
|
|
||||||
RtlInitUnicodeString(&WindowObject->WindowName, WindowName.Buffer);
|
RtlInitUnicodeString(&WindowObject->WindowName, WindowName.Buffer);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue