BeeeOn Gateway  v2020.3.1-2-g6f737dc
Platform to interconnect the IoT world
DelayedAsyncWork.h
1 #pragma once
2 
3 #include <functional>
4 #include <string>
5 
6 #include <Poco/Event.h>
7 #include <Poco/Logger.h>
8 #include <Poco/RunnableAdapter.h>
9 #include <Poco/Thread.h>
10 
11 #include "util/AbstractAsyncWork.h"
12 #include "util/Joiner.h"
13 #include "util/Loggable.h"
14 #include "util/ThreadNamer.h"
15 
16 namespace BeeeOn {
17 
23 template <typename Result = Poco::Void>
24 class DelayedAsyncWork : public AbstractAsyncWork<Result>, Loggable {
25 public:
26  typedef Poco::SharedPtr<DelayedAsyncWork<Result>> Ptr;
27  typedef std::function<void(DelayedAsyncWork<Result> &)> Call;
28 
30  Call f,
31  const Poco::Timespan &delay);
33  Call f,
34  Call cancelled,
35  const Poco::Timespan &delay);
36 
37  bool tryJoin(const Poco::Timespan &timeout) override;
38  void cancel() override;
39 
40 protected:
41  void run();
42 
43 private:
44  Call m_f;
45  Call m_cancelled;
46  Poco::Timespan m_delay;
47  Poco::Event m_event;
48  Poco::RunnableAdapter<DelayedAsyncWork> m_runnable;
49  Poco::Thread m_thread;
50  Joiner m_finished;
51 };
52 
53 template <typename Result>
55  Call f,
56  const Poco::Timespan &delay):
57  DelayedAsyncWork<Result>(f, [](DelayedAsyncWork<Result> &){}, delay)
58 {
59 }
60 
61 template <typename Result>
62 DelayedAsyncWork<Result>::DelayedAsyncWork(
63  Call f,
64  Call cancelled,
65  const Poco::Timespan &delay):
66  m_f(f),
67  m_cancelled(cancelled),
68  m_delay(delay),
69  m_runnable(*this, &DelayedAsyncWork<Result>::run),
70  m_finished(m_thread)
71 {
72  m_thread.start(m_runnable);
73 }
74 
75 template <typename Result>
76 bool DelayedAsyncWork<Result>::tryJoin(const Poco::Timespan &timeout)
77 {
78  return m_finished.tryJoin(timeout);
79 }
80 
81 template <typename Result>
83 {
84  m_event.set();
85  m_finished.join();
86 }
87 
88 template <typename Result>
90 {
91  ThreadNamer namer("delayed-by-" + std::to_string(m_delay.totalMilliseconds()));
92 
93  if (m_event.tryWait(m_delay.totalMilliseconds())) {
94  m_cancelled(*this);
95  return; // cancelled
96  }
97 
98  try {
99  m_f(*this); // not cancellable, must not sleep
100  }
101  BEEEON_CATCH_CHAIN(logger())
102 }
103 
104 }
void cancel() override
Cancel the operation this object represents. It should exit immediatelly or at least as soon as possi...
Definition: DelayedAsyncWork.h:82
Implementation of the AsyncWork interface that executes a given function once after the the given del...
Definition: DelayedAsyncWork.h:24
AbstractAsyncWork provides a generic implementation of method result() and a supplementary method set...
Definition: AbstractAsyncWork.h:17
Name the current thread. The name can be assigned permanently or just until the destructor is called...
Definition: ThreadNamer.h:11
Joiner implements join() on a thread that can be called multiple times from different threads...
Definition: Joiner.h:21
Definition: Result.h:29
bool tryJoin(const Poco::Timespan &timeout) override
Definition: DelayedAsyncWork.h:76
Definition: Loggable.h:19