diff options
author | Sergey Yershov <yershov@corp.mail.ru> | 2016-03-03 15:37:38 +0300 |
---|---|---|
committer | Sergey Yershov <yershov@corp.mail.ru> | 2016-03-23 16:51:10 +0300 |
commit | 1e3acb49ea3a8074341b5276844c55900ae4ddea (patch) | |
tree | a494a6917aa133c054897d73305b2b31ffa4effd /base | |
parent | 1ffafe2be5f781883cdad8f7dac58a44e3303521 (diff) |
Add deferred task implementation
Diffstat (limited to 'base')
-rw-r--r-- | base/base.pro | 2 | ||||
-rw-r--r-- | base/deferred_task.cpp | 44 | ||||
-rw-r--r-- | base/deferred_task.hpp | 35 |
3 files changed, 81 insertions, 0 deletions
diff --git a/base/base.pro b/base/base.pro index 58887276ef..934e3298ac 100644 --- a/base/base.pro +++ b/base/base.pro @@ -11,6 +11,7 @@ SOURCES += \ base.cpp \ condition.cpp \ gmtime.cpp \ + deferred_task.cpp \ exception.cpp \ internal/message.cpp \ logging.cpp \ @@ -42,6 +43,7 @@ HEADERS += \ collection_cast.hpp \ condition.hpp \ const_helper.hpp \ + deferred_task.hpp \ exception.hpp \ gmtime.hpp \ internal/messagex.hpp \ diff --git a/base/deferred_task.cpp b/base/deferred_task.cpp new file mode 100644 index 0000000000..c769dab253 --- /dev/null +++ b/base/deferred_task.cpp @@ -0,0 +1,44 @@ +#include "deferred_task.hpp" + +DeferredTask::DeferredTask(TDuration duration) : m_duration(duration) +{ + m_thread = thread([this] { + unique_lock<mutex> l(m_mutex); + while (!m_terminate) + { + if (!m_fn) + { + m_cv.wait(l); + continue; + } + + if (m_cv.wait_for(l, m_duration) != cv_status::timeout) + continue; + + auto local_fn = move(m_fn); + m_fn = nullptr; + l.unlock(); + local_fn(); + l.lock(); + } + }); +} + +DeferredTask::~DeferredTask() +{ + { + unique_lock<mutex> l(m_mutex); + m_terminate = true; + } + m_cv.notify_one(); + m_thread.join(); +} + +void DeferredTask::Drop() +{ + { + unique_lock<mutex> l(m_mutex); + m_fn = nullptr; + } + m_cv.notify_one(); +} diff --git a/base/deferred_task.hpp b/base/deferred_task.hpp new file mode 100644 index 0000000000..517953150d --- /dev/null +++ b/base/deferred_task.hpp @@ -0,0 +1,35 @@ +#pragma once + +#include "std/thread.hpp" +#include "std/chrono.hpp" +#include "std/mutex.hpp" +#include "std/condition_variable.hpp" +#include "std/function.hpp" + + +class DeferredTask +{ + using TDuration = duration<double>; + thread m_thread; + mutex m_mutex; + condition_variable m_cv; + function<void()> m_fn; + TDuration m_duration; + bool m_terminate = false; + +public: + DeferredTask(TDuration duration); + ~DeferredTask(); + + void Drop(); + + template<typename TFn> + void RestartWith(TFn const && fn) + { + { + unique_lock<mutex> l(m_mutex); + m_fn = fn; + } + m_cv.notify_one(); + } +}; |