summaryrefslogtreecommitdiff
path: root/shared/parallelCall.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'shared/parallelCall.cpp')
-rw-r--r--shared/parallelCall.cpp159
1 files changed, 159 insertions, 0 deletions
diff --git a/shared/parallelCall.cpp b/shared/parallelCall.cpp
new file mode 100644
index 00000000..ce0a3633
--- /dev/null
+++ b/shared/parallelCall.cpp
@@ -0,0 +1,159 @@
+// **************************************************************************
+// * This file is part of the FreeFileSync project. It is distributed under *
+// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
+// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
+// **************************************************************************
+//
+#include "parallelCall.h"
+#include <wx/thread.h>
+#include <stdexcept>
+#include <wx/string.h>
+#include <wx/msgdlg.h>
+
+namespace
+{
+class WorkerThread : public wxThread
+{
+public:
+ WorkerThread(const Async::AsyncProcess& proc,
+ const boost::shared_ptr<wxMutex>& mainIsListening,
+ const boost::shared_ptr<wxCondition>& procHasFinished) :
+ wxThread(wxTHREAD_DETACHED),
+ proc_(proc), //copy input data by value
+ mainIsListening_(mainIsListening), //
+ procHasFinished_(procHasFinished) //
+ {
+ if (Create() != wxTHREAD_NO_ERROR)
+ throw std::runtime_error("Error creating async worker thread!");
+
+ if (Run() != wxTHREAD_NO_ERROR)
+ throw std::runtime_error("Error starting async worker thread!");
+ }
+
+ ExitCode Entry()
+ {
+ try
+ {
+ proc_->doWork();
+
+ //notify that work is done
+ wxMutexLocker dummy(*mainIsListening_);
+ procHasFinished_->Signal();
+ }
+ catch (const std::exception& e) //exceptions must be catched per thread
+ {
+ wxMessageBox(wxString::FromAscii(e.what()), _("An exception occured!"), wxOK | wxICON_ERROR);
+ }
+ catch (...) //exceptions must be catched per thread
+ {
+ wxMessageBox(wxT("Unknown exception in worker thread"), _("An exception occured!"), wxOK | wxICON_ERROR);
+ }
+
+ return 0;
+ }
+
+private:
+ Async::AsyncProcess proc_;
+ boost::shared_ptr<wxMutex> mainIsListening_; //shared pointer is safe to use in MT context (same guarantee like builtin types!)
+ boost::shared_ptr<wxCondition> procHasFinished_; //http://www.boost.org/doc/libs/1_43_0/libs/smart_ptr/shared_ptr.htm#ThreadSafety
+};
+}
+
+
+Async::Result Async::execute(AsyncProcess proc, size_t maxWait) //maxWait = max. wait time in milliseconds
+{
+ boost::shared_ptr<wxMutex> mainIsListening(new wxMutex);
+ boost::shared_ptr<wxCondition> procHasFinished(new wxCondition(*mainIsListening));
+ wxMutexLocker dummy(*mainIsListening); //the mutex should be initially locked (= "main not listening")
+
+ new WorkerThread(proc, mainIsListening, procHasFinished);
+
+ return procHasFinished->WaitTimeout(static_cast<unsigned long>(maxWait)) == wxCOND_NO_ERROR ? WORK_DONE : TIMEOUT;
+}
+
+
+// ------------------------------------------------------
+// |Pattern: workload queue and multiple worker threads |
+// ------------------------------------------------------
+//typedef std::vector<DirectoryDescrType*> Workload;
+//
+//class ThreadSorting : public wxThread
+//{
+//public:
+// ThreadSorting(wxCriticalSection& syncWorkload, Workload& workload) :
+// wxThread(wxTHREAD_JOINABLE),
+// syncWorkload_(syncWorkload),
+// workload_(workload)
+// {
+// if (Create() != wxTHREAD_NO_ERROR)
+// throw RuntimeException(wxString(wxT("Error creating thread for sorting!")));
+// }
+//
+// ~ThreadSorting() {}
+//
+//
+// ExitCode Entry()
+// {
+// while (true)
+// {
+// DirectoryDescrType* descr = NULL;
+// { //see if there is work to do...
+// wxCriticalSectionLocker dummy(syncWorkload_);
+// if (workload_.empty())
+// return 0;
+// else
+// {
+// descr = workload_.back();
+// workload_.pop_back();
+// }
+// }
+// //do work
+// std::sort(descr->begin(), descr->end());
+// }
+// }
+//
+//private:
+// wxCriticalSection& syncWorkload_;
+// Workload& workload_;
+//};
+//
+//
+//void DirectoryDescrBuffer::preFillBuffers(const std::vector<FolderPairCfg>& fpConfigFormatted)
+//{
+// //assemble workload
+// ...
+//
+// //we use binary search when comparing the directory structures: so sort() first
+// const int CPUCount = wxThread::GetCPUCount();
+// if (CPUCount >= 2) //do it the multithreaded way:
+// {
+// wxCriticalSection syncWorkload;
+//
+// typedef std::vector<boost::shared_ptr<ThreadSorting> > ThreadContainer;
+// ThreadContainer sortThreads;
+// sortThreads.reserve(CPUCount);
+//
+// //start CPUCount worker threads
+// for (size_t i = 0; i < std::min(static_cast<size_t>(CPUCount), workload.size()); ++i)
+// {
+// boost::shared_ptr<ThreadSorting> newWorker(new ThreadSorting(syncWorkload, workload));
+//
+// if (newWorker->Run() != wxTHREAD_NO_ERROR)
+// throw RuntimeException(wxString(wxT("Error starting thread for sorting!")));
+//
+// sortThreads.push_back(newWorker);
+// }
+//
+// //wait until all worker are finished
+// for (ThreadContainer::iterator i = sortThreads.begin(); i != sortThreads.end(); ++i)
+// {
+// if ((*i)->Wait() != 0)
+// throw RuntimeException(wxString(wxT("Error waiting for thread (sorting)!")));
+// }
+// }
+// else //single threaded
+// {
+// for (Workload::iterator i = workload.begin(); i != workload.end(); ++i)
+// std::sort((*i)->begin(), (*i)->end());
+// }
+//}
bgstack15