Index: src/ch/ClipboardMonitor.cpp =================================================================== diff -u -r8b7479db2ee71a3d00779c67fe6a1b1d9ec414b8 -rba618764ec3c9221fa704e905a9f807bd85ed4c5 --- src/ch/ClipboardMonitor.cpp (.../ClipboardMonitor.cpp) (revision 8b7479db2ee71a3d00779c67fe6a1b1d9ec414b8) +++ src/ch/ClipboardMonitor.cpp (.../ClipboardMonitor.cpp) (revision ba618764ec3c9221fa704e905a9f807bd85ed4c5) @@ -141,7 +141,7 @@ chcore::TTaskPtr spTask = pData->m_pTasks->CreateTask(tTaskDefinition); // write spTask to a file - spTask->Store(); + spTask->Store(true); // start processing spTask->BeginProcessing(); Index: src/ch/MainWnd.cpp =================================================================== diff -u -r671f4b1792a20d98b186f4e0a9cc6a620dede019 -rba618764ec3c9221fa704e905a9f807bd85ed4c5 --- src/ch/MainWnd.cpp (.../MainWnd.cpp) (revision 671f4b1792a20d98b186f4e0a9cc6a620dede019) +++ src/ch/MainWnd.cpp (.../MainWnd.cpp) (revision ba618764ec3c9221fa704e905a9f807bd85ed4c5) @@ -396,9 +396,10 @@ case 1023: // autosave timer KillTimer(1023); - m_spTasks->Store(); + m_spTasks->Store(false); SetTimer(1023, GetPropValue(GetConfig()), NULL); break; + case 3245: // auto-delete finished tasks timer KillTimer(3245); @@ -412,6 +413,7 @@ SetTimer(3245, TM_AUTOREMOVE, NULL); break; + case 8743: { // wait state handling section @@ -569,7 +571,7 @@ { chcore::TTaskPtr spTask = m_spTasks->ImportTask(strPath); if(spTask) - spTask->Store(); + spTask->Store(true); bImported = true; } catch(icpf::exception& e) Index: src/libchcore/TTask.cpp =================================================================== diff -u -re96806b7f8ff7ca7e9f4afbea603e6351a3dc3e3 -rba618764ec3c9221fa704e905a9f807bd85ed4c5 --- src/libchcore/TTask.cpp (.../TTask.cpp) (revision e96806b7f8ff7ca7e9f4afbea603e6351a3dc3e3) +++ src/libchcore/TTask.cpp (.../TTask.cpp) (revision ba618764ec3c9221fa704e905a9f807bd85ed4c5) @@ -191,17 +191,40 @@ } } - void TTask::Store() + void TTask::Store(bool bForce) { if (GetTaskState() == eTaskState_LoadError) { DBTRACE0(_T("Task::Store() - not storing task as it was not loaded correctly\n")); return; } - TSimpleTimer timer(true); DBTRACE0(_T("###### Task::Store() - starting\n")); + // ensure we're only running one serialization of this task at a time; + // (this is usually called from the gui thread (on timer) and at specific points + // of task processing; there were times where + if(!bForce) + { + if (!m_mutexSerializer.try_lock()) + { + DBTRACE0(_T("###### Task::Store() - serialization already running. Skipping.\n")); + return; + } + } + else + { + if (!m_mutexSerializer.try_lock()) + { + DBTRACE0(_T("###### Task::Store() - waiting for serialization mutex...\n")); + m_mutexSerializer.lock(); + } + } + + std::unique_lock locke(m_mutexSerializer, std::adopt_lock); + + TSimpleTimer timer(true); + using namespace chcore; { @@ -550,7 +573,7 @@ m_tSubTaskContext.GetFilesCache().Clear(); // scanning for files did not finish processing, so the content of the files cache are useless // save progress before killed - Store(); + Store(true); // reset flags SetContinueFlag(false); Index: src/libchcore/TTask.h =================================================================== diff -u -re96806b7f8ff7ca7e9f4afbea603e6351a3dc3e3 -rba618764ec3c9221fa704e905a9f807bd85ed4c5 --- src/libchcore/TTask.h (.../TTask.h) (revision e96806b7f8ff7ca7e9f4afbea603e6351a3dc3e3) +++ src/libchcore/TTask.h (.../TTask.h) (revision ba618764ec3c9221fa704e905a9f807bd85ed4c5) @@ -34,6 +34,8 @@ #include "TTaskStatsSnapshot.h" #include "ISerializer.h" #include "TTaskBaseData.h" +#include "TEvent.h" +#include namespace chcore { @@ -66,7 +68,7 @@ void SetPriority(int nPriority); void Load(); - void Store(); + void Store(bool bForce); void BeginProcessing(); @@ -132,6 +134,7 @@ #pragma warning(push) #pragma warning(disable: 4251) ISerializerPtr m_spSerializer; + std::mutex m_mutexSerializer; IFeedbackHandlerPtr m_spInternalFeedbackHandler; #pragma warning(pop) Index: src/libchcore/TTaskManager.cpp =================================================================== diff -u -re96806b7f8ff7ca7e9f4afbea603e6351a3dc3e3 -rba618764ec3c9221fa704e905a9f807bd85ed4c5 --- src/libchcore/TTaskManager.cpp (.../TTaskManager.cpp) (revision e96806b7f8ff7ca7e9f4afbea603e6351a3dc3e3) +++ src/libchcore/TTaskManager.cpp (.../TTaskManager.cpp) (revision ba618764ec3c9221fa704e905a9f807bd85ed4c5) @@ -62,7 +62,7 @@ Add(spTask); - spTask->Store(); + spTask->Store(true); return spTask; } @@ -137,7 +137,7 @@ StopAllTasks(); // ensure everything is stored so that we can resume processing in the future - Store(); + Store(true); // now remove all tasks without serializing anymore (prevent accidental // serialization) @@ -436,7 +436,7 @@ } } - void TTaskManager::Store() + void TTaskManager::Store(bool bForce) { TSimpleTimer timer(true); @@ -450,7 +450,7 @@ for (size_t stIndex = 0; stIndex != m_tTasks.GetCount(); ++stIndex) { TTaskPtr spTask = m_tTasks.GetAt(stIndex).GetTask(); - spTask->Store(); + spTask->Store(bForce); } } Index: src/libchcore/TTaskManager.h =================================================================== diff -u -re96806b7f8ff7ca7e9f4afbea603e6351a3dc3e3 -rba618764ec3c9221fa704e905a9f807bd85ed4c5 --- src/libchcore/TTaskManager.h (.../TTaskManager.h) (revision e96806b7f8ff7ca7e9f4afbea603e6351a3dc3e3) +++ src/libchcore/TTaskManager.h (.../TTaskManager.h) (revision ba618764ec3c9221fa704e905a9f807bd85ed4c5) @@ -46,7 +46,7 @@ ~TTaskManager(); - void Store(); + void Store(bool bForce); void Load(); TTaskPtr CreateTask(const TTaskDefinition& tTaskDefinition);