123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276 |
- #ifndef QTCONCURRENT_THREADENGINE_H
- #define QTCONCURRENT_THREADENGINE_H
- #include <QtConcurrent/qtconcurrent_global.h>
- #ifndef QT_NO_CONCURRENT
- #include <QtCore/qthreadpool.h>
- #include <QtCore/qfuture.h>
- #include <QtCore/qdebug.h>
- #include <QtCore/qexception.h>
- #include <QtCore/qwaitcondition.h>
- #include <QtCore/qatomic.h>
- #include <QtCore/qsemaphore.h>
- QT_BEGIN_NAMESPACE
- #ifndef Q_QDOC
- namespace QtConcurrent {
- class ThreadEngineBarrier
- {
- private:
-
-
-
- QAtomicInt count;
- QSemaphore semaphore;
- public:
- ThreadEngineBarrier();
- void acquire();
- int release();
- void wait();
- int currentCount();
- bool releaseUnlessLast();
- };
- enum ThreadFunctionResult { ThrottleThread, ThreadFinished };
- class Q_CONCURRENT_EXPORT ThreadEngineBase: public QRunnable
- {
- public:
-
- ThreadEngineBase();
- virtual ~ThreadEngineBase();
- void startSingleThreaded();
- void startBlocking();
- void startThread();
- bool isCanceled();
- void waitForResume();
- bool isProgressReportingEnabled();
- void setProgressValue(int progress);
- void setProgressRange(int minimum, int maximum);
- void acquireBarrierSemaphore();
- protected:
- virtual void start() {}
- virtual void finish() {}
- virtual ThreadFunctionResult threadFunction() { return ThreadFinished; }
- virtual bool shouldStartThread() { return futureInterface ? !futureInterface->isPaused() : true; }
- virtual bool shouldThrottleThread() { return futureInterface ? futureInterface->isPaused() : false; }
- private:
- bool startThreadInternal();
- void startThreads();
- void threadExit();
- bool threadThrottleExit();
- void run() Q_DECL_OVERRIDE;
- virtual void asynchronousFinish() = 0;
- #ifndef QT_NO_EXCEPTIONS
- void handleException(const QException &exception);
- #endif
- protected:
- QFutureInterfaceBase *futureInterface;
- QThreadPool *threadPool;
- ThreadEngineBarrier barrier;
- QtPrivate::ExceptionStore exceptionStore;
- };
- template <typename T>
- class ThreadEngine : public virtual ThreadEngineBase
- {
- public:
- typedef T ResultType;
- virtual T *result() { return Q_NULLPTR; }
- QFutureInterface<T> *futureInterfaceTyped()
- {
- return static_cast<QFutureInterface<T> *>(futureInterface);
- }
-
- T *startSingleThreaded()
- {
- ThreadEngineBase::startSingleThreaded();
- return result();
- }
-
-
-
- T *startBlocking()
- {
- ThreadEngineBase::startBlocking();
- return result();
- }
-
-
- QFuture<T> startAsynchronously()
- {
- futureInterface = new QFutureInterface<T>();
-
-
-
- futureInterface->reportStarted();
- QFuture<T> future = QFuture<T>(futureInterfaceTyped());
- start();
- acquireBarrierSemaphore();
- threadPool->start(this);
- return future;
- }
- void asynchronousFinish() Q_DECL_OVERRIDE
- {
- finish();
- futureInterfaceTyped()->reportFinished(result());
- delete futureInterfaceTyped();
- delete this;
- }
- void reportResult(const T *_result, int index = -1)
- {
- if (futureInterface)
- futureInterfaceTyped()->reportResult(_result, index);
- }
- void reportResults(const QVector<T> &_result, int index = -1, int count = -1)
- {
- if (futureInterface)
- futureInterfaceTyped()->reportResults(_result, index, count);
- }
- };
- template <typename T>
- class ThreadEngineStarterBase
- {
- public:
- ThreadEngineStarterBase(ThreadEngine<T> *_threadEngine)
- : threadEngine(_threadEngine) { }
- inline ThreadEngineStarterBase(const ThreadEngineStarterBase &other)
- : threadEngine(other.threadEngine) { }
- QFuture<T> startAsynchronously()
- {
- return threadEngine->startAsynchronously();
- }
- operator QFuture<T>()
- {
- return startAsynchronously();
- }
- protected:
- ThreadEngine<T> *threadEngine;
- };
- template <typename T>
- class ThreadEngineStarter : public ThreadEngineStarterBase<T>
- {
- typedef ThreadEngineStarterBase<T> Base;
- typedef ThreadEngine<T> TypedThreadEngine;
- public:
- ThreadEngineStarter(TypedThreadEngine *eng)
- : Base(eng) { }
- T startBlocking()
- {
- T t = *this->threadEngine->startBlocking();
- delete this->threadEngine;
- return t;
- }
- };
- template <>
- class ThreadEngineStarter<void> : public ThreadEngineStarterBase<void>
- {
- public:
- ThreadEngineStarter<void>(ThreadEngine<void> *_threadEngine)
- :ThreadEngineStarterBase<void>(_threadEngine) {}
- void startBlocking()
- {
- this->threadEngine->startBlocking();
- delete this->threadEngine;
- }
- };
- template <typename ThreadEngine>
- inline ThreadEngineStarter<typename ThreadEngine::ResultType> startThreadEngine(ThreadEngine *threadEngine)
- {
- return ThreadEngineStarter<typename ThreadEngine::ResultType>(threadEngine);
- }
- }
- #endif
- QT_END_NAMESPACE
- #endif
- #endif
|