From d2c6ebe13b386fe1b9eb9be92698eb916c04105d Mon Sep 17 00:00:00 2001 From: Takashi Sawanaka Date: Sun, 10 Feb 2008 13:23:21 +0000 Subject: [PATCH] PATCH: [ 1889907 ] Patch for BUG: [ 1865131 ] Potential lockup in DirScan_Compa --- Docs/Users/ChangeLog.txt | 1 + Src/DiffContext.cpp | 2 -- Src/DiffContext.h | 1 - Src/DiffThread.cpp | 10 +++++++--- Src/DirScan.cpp | 49 ++++++------------------------------------------ 5 files changed, 14 insertions(+), 49 deletions(-) diff --git a/Docs/Users/ChangeLog.txt b/Docs/Users/ChangeLog.txt index 6b01c9a81..c0c85b780 100644 --- a/Docs/Users/ChangeLog.txt +++ b/Docs/Users/ChangeLog.txt @@ -4,6 +4,7 @@ to Subversion revision numbers (rXXXXX). WinMerge 2.7.7.5 Cleaning up Help-menu (#1875111) + BugFix: Potential lockup in folder compare (#1865131, #1889907) WinMerge 2.7.7.4 - 2008-02-07 (r5011) Detect (and read/write) UTF-8 files without BOM (#1879271) diff --git a/Src/DiffContext.cpp b/Src/DiffContext.cpp index dde6276e4..d3b5a5f41 100644 --- a/Src/DiffContext.cpp +++ b/Src/DiffContext.cpp @@ -69,7 +69,6 @@ CDiffContext::CDiffContext(LPCTSTR pszLeft /*=NULL*/, LPCTSTR pszRight /*=NULL*/ , m_piAbortable(NULL) , m_bStopAfterFirstDiff(FALSE) , m_pFilterList(NULL) -, m_bCollectReady(FALSE) , m_pCompareOptions(NULL) , m_pOptions(NULL) { @@ -101,7 +100,6 @@ CDiffContext::CDiffContext(LPCTSTR pszLeft, LPCTSTR pszRight, CDiffContext& src) m_bIgnoreSmallTimeDiff = src.m_bIgnoreSmallTimeDiff; m_bStopAfterFirstDiff = src.m_bStopAfterFirstDiff; m_pFilterList = src.m_pFilterList; - m_bCollectReady = src.m_bCollectReady; EnterCriticalSection(&src.m_criticalSect); InitializeCriticalSection(&m_criticalSect); diff --git a/Src/DiffContext.h b/Src/DiffContext.h index fc9a3d52c..7fb0a3ce7 100644 --- a/Src/DiffContext.h +++ b/Src/DiffContext.h @@ -105,7 +105,6 @@ public: int m_nQuickCompareLimit; /**< Bigger files are always compared with quick compare */ FilterList * m_pFilterList; /**< Filter list for line filters */ CRITICAL_SECTION m_criticalSect; /**< Critical section protecting list access. */ - BOOL m_bCollectReady; /**< Tells collection phase is done. */ private: CList *m_pList; /**< Pointer to list, used to access list */ diff --git a/Src/DiffThread.cpp b/Src/DiffThread.cpp index 5bf59bcab..21db36494 100644 --- a/Src/DiffThread.cpp +++ b/Src/DiffThread.cpp @@ -229,7 +229,6 @@ UINT DiffThreadCollect(LPVOID lpParam) DiffFuncStruct *myStruct = (DiffFuncStruct *) lpParam; UINT msgID = myStruct->msgUIUpdate; bool bOnlyRequested = myStruct->bOnlyRequested; - myStruct->context->m_bCollectReady = FALSE; // Stash abortable interface into context myStruct->context->SetAbortable(myStruct->m_pAbortgate); @@ -277,8 +276,13 @@ UINT DiffThreadCollect(LPVOID lpParam) #endif } - // Signal that collect phase is ready - myStruct->context->m_bCollectReady = TRUE; + // Add sentinel to ItemList + EnterCriticalSection(&myStruct->context->m_criticalSect); + DIFFITEM di; + di = di.MakeEmptyDiffItem(); + myStruct->pItemList->AddDiff(di); + LeaveCriticalSection(&myStruct->context->m_criticalSect); + return 1; } diff --git a/Src/DirScan.cpp b/Src/DirScan.cpp index ddd36cc26..5d25798ab 100644 --- a/Src/DirScan.cpp +++ b/Src/DirScan.cpp @@ -250,8 +250,6 @@ int DirScan_CompareItems(DiffItemList * list, CDiffContext * pCtxt) EnterCriticalSection(&pCtxt->m_criticalSect); pos = list->GetFirstDiffPosition(); LeaveCriticalSection(&pCtxt->m_criticalSect); - if (pCtxt->m_bCollectReady == TRUE) - break; } // Compare whole list @@ -267,56 +265,21 @@ int DirScan_CompareItems(DiffItemList * list, CDiffContext * pCtxt) EnterCriticalSection(&pCtxt->m_criticalSect); DIFFITEM di = list->GetNextDiffPosition(pos); LeaveCriticalSection(&pCtxt->m_criticalSect); + if (di.empty) + break; // found sentinel CompareDiffItem(di, pCtxt); // Some compare methdods can be faster than collecting, // so we can reach the end of list while collect is running. // In this case we must wait for a while for new items to be // added to the list. - if (pos == NULL && pCtxt->m_bCollectReady == FALSE) - { - do - { - pos = prevPos; - Sleep(200); - EnterCriticalSection(&pCtxt->m_criticalSect); - list->GetNextDiffPosition(pos); - LeaveCriticalSection(&pCtxt->m_criticalSect); - } while (pos == NULL); - } - } - - // Loop above may not catch all items yet, consider this case: - // - we get latest item at the moment (pos is returned as NULL) - // - compare takes a while (big file / slow media) and new item - // is added to the list while comparing - // - m_bCollectReady is set to TRUE - // Now we would end the loop, while there are still items in the list. - // So to be sure, lets try again with "last" item, if there are more - // items! - - // Check that we have items in the list (maybe it was empty folder?) - if (list->GetFirstDiffPosition()) - { - EnterCriticalSection(&pCtxt->m_criticalSect); - list->GetNextDiffPosition(prevPos); - LeaveCriticalSection(&pCtxt->m_criticalSect); - } - - if (prevPos != NULL) - { - pos = prevPos; - while (pos != NULL) + while (pos == NULL) { - if (pCtxt->ShouldAbort()) - { - res = -1; - break; - } + pos = prevPos; + Sleep(200); EnterCriticalSection(&pCtxt->m_criticalSect); - DIFFITEM di = list->GetNextDiffPosition(pos); + list->GetNextDiffPosition(pos); LeaveCriticalSection(&pCtxt->m_criticalSect); - CompareDiffItem(di, pCtxt); } } -- 2.11.0