Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include "TaskDispatcher.h"
#include "QtConcurrent"
typedef std::unique_lock<std::mutex> ULock;
namespace nemo_interface {
TaskDispatcher::TaskDispatcher() : _running(false) {}
TaskDispatcher::~TaskDispatcher() { stop(); }
std::future<QVariant> TaskDispatcher::dispatch(std::unique_ptr<Task> c) {
ULock lk1(this->_mutex);
this->_taskQueue.push_back(std::move(c));
std::promise<QVariant> promise;
auto future = promise.get_future();
this->_promiseQueue.push_back(std::move(promise));
if (!this->_running) {
lk1.unlock();
this->start();
}
return future;
}
std::future<QVariant> TaskDispatcher::dispatchNext(std::unique_ptr<Task> c) {
ULock lk1(this->_mutex);
this->_taskQueue.push_front(std::move(c));
std::promise<QVariant> promise;
auto future = promise.get_future();
this->_promiseQueue.push_front(std::move(promise));
if (!this->_running) {
lk1.unlock();
this->start();
}
return future;
}
void TaskDispatcher::clear() {
ULock lk(this->_mutex);
this->_taskQueue.clear();
this->_promiseQueue.clear();
}
void TaskDispatcher::start() {
ULock lk1(this->_mutex);
if (!_running) {
this->_running = true;
QtConcurrent::run([this]() mutable { return this->run(); });
}
}
void TaskDispatcher::stop() {
ULock lk1(this->_mutex);
if (_running) {
this->_running = false;
lk1.unlock();
}
}
void TaskDispatcher::reset() {
stop();
}
bool TaskDispatcher::isInterruptionRequested() {
ULock lk1(this->_mutex);
return !_running;
}
bool TaskDispatcher::isRunning() {
ULock lk1(this->_mutex);
return _running;
}
std::size_t TaskDispatcher::pendingTasks() {
ULock lk1(this->_mutex);
return this->_taskQueue.size() + (_running ? 1 : 0);
}
bool TaskDispatcher::idle() { return this->pendingTasks() == 0; }
void TaskDispatcher::run() {
while (true) {
ULock lk1(this->_mutex);
if (this->_taskQueue.size() > 0 && this->_running) {
Q_ASSERT(this->_taskQueue.size() == this->_promiseQueue.size());
// pop task and promise
auto pTask = std::move(this->_taskQueue.front());
auto promise = std::move(this->_promiseQueue.front());
this->_taskQueue.pop_front();
this->_promiseQueue.pop_front();
lk1.unlock();
// exec task
QVariant var = pTask->exec();
bool r = var.toBool();
Q_ASSERT(r == true || r == false);
promise.set_value(var);