OSDN Git Service

PATCH: [ 1889907 ] Patch for BUG: [ 1865131 ] Potential lockup in DirScan_Compa
authorTakashi Sawanaka <sdottaka@users.sourceforge.net>
Sun, 10 Feb 2008 13:23:21 +0000 (13:23 +0000)
committerTakashi Sawanaka <sdottaka@users.sourceforge.net>
Sun, 10 Feb 2008 13:23:21 +0000 (13:23 +0000)
Docs/Users/ChangeLog.txt
Src/DiffContext.cpp
Src/DiffContext.h
Src/DiffThread.cpp
Src/DirScan.cpp

index 6b01c9a..c0c85b7 100644 (file)
@@ -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)
index dde6276..d3b5a5f 100644 (file)
@@ -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);
index fc9a3d5..7fb0a3c 100644 (file)
@@ -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<DIFFITEM,DIFFITEM&> *m_pList; /**< Pointer to list, used to access list */
index 5bf59bc..21db364 100644 (file)
@@ -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;
 }
 
index ddd36cc..5d25798 100644 (file)
@@ -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);
                }
        }