concurrent(Args&&... args) : _worker(std::forward<Args>(args)...) , _done(false) , _thd([ = ]{concurrent_helper::Callback call; while (!_done) { _q.wait_and_pop(call); call(); }}) { }
void run() const { concurrent_helper::Callback call; while (!_done) { _q.wait_and_pop(call); call(); } }
void fire(AsyncCall func, Args&& ... args) const noexcept(false) { if (empty()) { throw std::runtime_error("nullptr instantiated worker"); } // weak compiler support for expanding parameter pack in a lambda. std::function is the // work-around, With better compiler support it can be changed to: // auto bgCall = [&, args...]{ return (_worker.*func)(args...); }; auto bgCall = std::bind(func, _worker.get(), std::forward<Args>(args)...); _q.push(bgCall); return; }
/** * Moves in a unique_ptr<T> to be the background object. Starts up the worker thread * @param worker to act as the background object */ concurrent(std::unique_ptr<T> worker) : _worker(std::move(worker)) , _done(false) , _thd([ = ] { concurrent_helper::Callback call; while (_worker && !_done) { _q.wait_and_pop(call); call(); } }) { }
/// return snapshot of size virtual size_t size() { return _q.size(); }
/** * Clean shutdown. All pending messages are executed before the shutdown message is received */ virtual ~concurrent() { _q.push([ = ] {_done = true;}); if (_thd.joinable()) { _thd.join(); } }
~concurrent() { _q.push([ = ]{_done = true;}); _thd.join(); }