#include "TaskDispatcher.h" #include "QtConcurrent" typedef std::unique_lock ULock; namespace nemo_interface { TaskDispatcher::TaskDispatcher() : _running(false) {} TaskDispatcher::~TaskDispatcher() { stop(); } std::future TaskDispatcher::dispatch(std::unique_ptr c) { ULock lk1(this->_mutex); this->_taskQueue.push_back(std::move(c)); std::promise promise; auto future = promise.get_future(); this->_promiseQueue.push_back(std::move(promise)); if (!this->_running) { lk1.unlock(); this->start(); } return future; } std::future TaskDispatcher::dispatchNext(std::unique_ptr c) { ULock lk1(this->_mutex); this->_taskQueue.push_front(std::move(c)); std::promise 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(); }); lk1.unlock(); } } void TaskDispatcher::stop() { ULock lk1(this->_mutex); if (_running) { this->_running = false; lk1.unlock(); } } void TaskDispatcher::reset() { stop(); clear(); } 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); } else { this->_running = false; lk1.unlock(); break; } } } } // namespace nemo_interface