From af760d90249232b9f33bd36e85ab87445bb61fe4 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Sat, 22 Dec 2012 22:22:06 +0000 Subject: [PATCH] [WIN32K] Fix a bug in the GDI pool code that could lead to list corruption and a failed ASSERT, when an app allocated a large number of DCs or brushes, like AbiWord with more than 1 document open. Also add a few more ASSERTs. svn path=/trunk/; revision=57973 --- reactos/win32ss/gdi/ntgdi/gdipool.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/reactos/win32ss/gdi/ntgdi/gdipool.c b/reactos/win32ss/gdi/ntgdi/gdipool.c index 57305d7eeda..5fac66511be 100644 --- a/reactos/win32ss/gdi/ntgdi/gdipool.c +++ b/reactos/win32ss/gdi/ntgdi/gdipool.c @@ -155,6 +155,8 @@ GdiPoolAllocate( /* Yes, remove it from the empty list */ ple = RemoveHeadList(&pPool->leEmptyList); pSection = CONTAINING_RECORD(ple, GDI_POOL_SECTION, leInUseLink); + pPool->cEmptySections--; + ASSERT(pSection->cAllocCount == 0); } else { @@ -166,13 +168,11 @@ GdiPoolAllocate( pvAlloc = NULL; goto done; } - - /* Insert it into the ready list */ - InsertHeadList(&pPool->leReadyList, &pSection->leReadyLink); } - /* Insert it into the in-use list */ + /* Insert it into the in-use and ready list */ InsertHeadList(&pPool->leInUseList, &pSection->leInUseLink); + InsertHeadList(&pPool->leReadyList, &pSection->leReadyLink); } /* Find and set a single bit */ @@ -203,6 +203,7 @@ GdiPoolAllocate( /* Increase alloc count */ pSection->cAllocCount++; + ASSERT(RtlNumberOfSetBits(&pSection->bitmap) == pSection->cAllocCount); DBG_LOGEVENT(&pPool->slhLog, EVENT_ALLOCATE, pvAlloc); /* Check if section is now busy */ @@ -260,6 +261,7 @@ GdiPoolFree( /* Decrease allocation count */ pSection->cAllocCount--; + ASSERT(RtlNumberOfSetBits(&pSection->bitmap) == pSection->cAllocCount); DBG_LOGEVENT(&pPool->slhLog, EVENT_FREE, pvAlloc); /* Check if the section got valid now */ @@ -275,7 +277,7 @@ GdiPoolFree( RemoveEntryList(&pSection->leInUseLink); RemoveEntryList(&pSection->leReadyLink); - if (pPool->cEmptySections > 1) + if (pPool->cEmptySections >= 1) { /* Delete the section */ GdiPoolDeleteSection(pPool, pSection);