diff --git a/implementations/caching/cache/PeriodicTask.cpp b/implementations/caching/cache/PeriodicTask.cpp index 8fa35179..d3baf339 100644 --- a/implementations/caching/cache/PeriodicTask.cpp +++ b/implementations/caching/cache/PeriodicTask.cpp @@ -8,27 +8,24 @@ using namespace cpputils::logging; namespace blockstore { namespace caching { -PeriodicTask::PeriodicTask(function task, double intervalSec) : _thread(), _task(task), _intervalSec(intervalSec) { - _thread = boost::thread([this]() { - boost::chrono::nanoseconds interval((uint64_t)(UINT64_C(1000000000) * _intervalSec)); - try { - while(true) { - boost::this_thread::sleep_for(interval); - _task(); - } - } catch (const boost::thread_interrupted &e) { - //Do nothing, exit thread. - } catch (const std::exception &e) { - LOG(ERROR) << "PeriodicTask crashed: " << e.what(); - } catch (...) { - LOG(ERROR) << "PeriodicTask crashed"; - } - }); +PeriodicTask::PeriodicTask(function task, double intervalSec) : + _task(task), + _interval((uint64_t)(UINT64_C(1000000000) * intervalSec)), + _thread(std::bind(&PeriodicTask::_loopIteration, this)) { + _thread.start(); } -PeriodicTask::~PeriodicTask() { - _thread.interrupt(); - _thread.join(); +void PeriodicTask::_loopIteration() { + try { + boost::this_thread::sleep_for(_interval); + _task(); + } catch (const std::exception &e) { + LOG(ERROR) << "PeriodicTask crashed: " << e.what(); + throw; + } catch (...) { + LOG(ERROR) << "PeriodicTask crashed"; + throw; + } } } diff --git a/implementations/caching/cache/PeriodicTask.h b/implementations/caching/cache/PeriodicTask.h index c4c85f2d..751397ff 100644 --- a/implementations/caching/cache/PeriodicTask.h +++ b/implementations/caching/cache/PeriodicTask.h @@ -3,20 +3,25 @@ #define MESSMER_BLOCKSTORE_IMPLEMENTATIONS_CACHING_CACHE_PERIODICTASK_H_ #include -#include +#include +#include namespace blockstore { namespace caching { -class PeriodicTask { +class PeriodicTask final { public: PeriodicTask(std::function task, double intervalSec); - virtual ~PeriodicTask(); private: - boost::thread _thread; - std::function _task; - double _intervalSec; + void _loopIteration(); + + std::function _task; + boost::chrono::nanoseconds _interval; + + //This member has to be last, so the thread is destructed first. Otherwise the thread might access elements from a + //partly destructed PeriodicTask. + cpputils::LoopThread _thread; }; }