1 // SPDX-License-Identifier: GPL-2.0-or-later
5 * @brief Code for DiffThread class
9 #include "DiffThread.h"
12 #include <Poco/Thread.h>
13 #include <Poco/Semaphore.h>
14 #include "UnicodeString.h"
15 #include "CompareStats.h"
16 #include "IAbortable.h"
18 #include "MergeAppCOMClass.h"
22 using Poco::Semaphore;
25 static void DiffThreadCollect(void *lpParam);
26 static void DiffThreadCompare(void *lpParam);
28 /** @brief abort handler for CDiffThread -- just a gateway to CDiffThread */
29 class DiffThreadAbortable : public IAbortable
31 // Implement DirScan's IAbortable
33 virtual bool ShouldAbort() const override { return m_diffthread->ShouldAbort(); }
35 // All this object does is forward ShouldAbort calls to its containing CDiffThread
37 explicit DiffThreadAbortable(CDiffThread * diffthread) : m_diffthread(diffthread) { }
38 CDiffThread * m_diffthread;
42 * @brief Default constructor.
44 CDiffThread::CDiffThread()
45 : m_pDiffContext(nullptr)
48 , m_pDiffParm(new DiffFuncStruct)
49 , m_pAbortgate(new DiffThreadAbortable(this))
54 * @brief Destructor, release resources.
56 CDiffThread::~CDiffThread()
58 delete m_pDiffParm->pSemaphore;
62 * @brief runtime interface for child thread, called on child thread
64 bool CDiffThread::ShouldAbort() const
66 while (m_bPaused && !m_bAborting)
67 Poco::Thread::sleep(100);
72 * @brief Start and run directory compare thread.
73 * @return Success (1) or error for thread. Currently always 1.
75 unsigned CDiffThread::CompareDirectories()
77 assert(m_pDiffParm->nThreadState != THREAD_COMPARING && m_pDiffParm->nCollectThreadState != THREAD_COMPARING);
79 m_pDiffParm->context = m_pDiffContext;
80 m_pDiffParm->m_pAbortgate = m_pAbortgate.get();
84 m_pDiffParm->nThreadState = THREAD_COMPARING;
85 m_pDiffParm->nCollectThreadState = THREAD_COMPARING;
87 delete m_pDiffParm->pSemaphore;
88 m_pDiffParm->pSemaphore = new Semaphore(0, LONG_MAX);
90 m_pDiffParm->context->m_pCompareStats->SetCompareState(CompareStats::STATE_START);
92 m_threads[0].start(DiffThreadCollect, m_pDiffParm.get());
93 m_threads[1].start(DiffThreadCompare, m_pDiffParm.get());
99 * @brief Item collection thread function.
101 * This thread is responsible for finding and collecting all items to compare
103 * @param [in] lpParam Pointer to parameter structure.
104 * @return Thread's return value.
106 static void DiffThreadCollect(void *pParam)
108 DiffFuncStruct *myStruct = static_cast<DiffFuncStruct *>(pParam);
110 // Stash abortable interface into context
111 myStruct->context->SetAbortable(myStruct->m_pAbortgate);
113 if (myStruct->m_fncCollect)
114 myStruct->m_fncCollect(myStruct);
116 // Release Semaphore() once again to signal that collect phase is ready
117 myStruct->pSemaphore->set();
119 // Send message to UI to update
120 myStruct->nCollectThreadState = CDiffThread::THREAD_COMPLETED;
121 int event = CDiffThread::EVENT_COLLECT_COMPLETED;
122 myStruct->m_listeners.notify(myStruct, event);
126 * @brief Folder compare thread function.
128 * Compares items in item list. After compare is ready
129 * sends message to UI so UI can update itself.
130 * @param [in] lpParam Pointer to parameter structure.
131 * @return Thread's return value.
133 static void DiffThreadCompare(void *pParam)
135 DiffFuncStruct *myStruct = static_cast<DiffFuncStruct *>(pParam);
136 CAssureScriptsForThread scriptsForRescan(new MergeAppCOMClass());
138 // Stash abortable interface into context
139 myStruct->context->SetAbortable(myStruct->m_pAbortgate);
141 myStruct->context->m_pCompareStats->SetCompareState(CompareStats::STATE_COMPARE);
143 // Now do all pending file comparisons
144 myStruct->m_fncCompare(myStruct);
146 myStruct->context->m_pCompareStats->SetCompareState(CompareStats::STATE_IDLE);
148 // Send message to UI to update
149 myStruct->nThreadState = CDiffThread::THREAD_COMPLETED;
150 int event = CDiffThread::EVENT_COMPARE_COMPLETED;
151 myStruct->m_listeners.notify(myStruct, event);