Scope
Active.h
1 #pragma once
2 
3 #include "SyncQueues.h"
4 #include "helpers.h"
5 
10 template<class RT>
11 class Active {
12 
13 public:
16  typedef std::function<RT(StopCondition* const sc)> Command;
17 
18 protected:
21 
23  bool done;
24 
27 
29  std::thread thread;
30 
31 protected:
33  Active(const Active&);
34 
36  void operator=(const Active&);
37 
38 protected:
39 
40 public:
43  : stop()
44  , done(false)
45  , ptq()
46  , thread([=]() {while ( !done ) {
47  stop.Set(false);
48  ptq.Dequeue()(&stop); }
49  DBOUT(L"Active::thread ended"); }) {
50  }
51 
52  ~Active() {
53  Quit();
54  }
55 
59  std::future<RT> Send(const Command& _cmd) {
60  // make a shared_ptr to the promise (we need this since promise it non-copyable
61  auto p = std::make_shared<std::promise<RT>>();
62 
63  // get the future of the promise to return it at the end
64  std::future<RT> ret = std::future<RT>(std::move(p->get_future()));
65 
66  // the promise pointer is caught by the lambda, thus outlives the Send function
67  ptq.Enqueue([=](StopCondition* const sc) {
68  p->set_value(_cmd(sc));
69  });
70 
71  return ret;
72  }
73 
75  void AbortCurrent() {
76  stop.Set(true);
77  }
78 
80  void Quit() {
81  ptq.Enqueue( [=] (StopCondition* const sc) { done = true; DBOUT(L"Active::Quit enqueued\n");} );
82  if ( thread.joinable() ) // This is not unfallably safe, could get unjoinable right after if?!
83  thread.join();
84  DBOUT(L"Active::Quitted\n");
85  }
86 };
87 
void AbortCurrent()
Aborts the currently executed worker function.
Definition: Active.h:75
Thread-safe lock-free bool to signal a requested stop to the worker function currently executed in th...
Definition: helpers.h:87
An active object implementation.
Definition: Active.h:11
void Quit()
Send lambda with done=true to the worker, join the worker thread, and clear the packaged task queue...
Definition: Active.h:80
void Enqueue(const T &elem)
Enqueues an element and notifies one waiting operation that queue is not empty.
Definition: SyncQueues.h:43
std::function< RT(StopCondition *const sc)> Command
Type of the worker function to be executed in Active's thread.
Definition: Active.h:16
Active()
The thread execution loop is created from a lambda.
Definition: Active.h:42
std::future< RT > Send(const Command &_cmd)
Sends a worker function/packaged task to the queue to be executed in the Active's thread...
Definition: Active.h:59
StopCondition stop
the abort signal
Definition: Active.h:20
#define DBOUT(s)
A debug output to the debug console.
Definition: helpers.h:153
bool done
this is set to quit the worker thread
Definition: Active.h:23
A synchronized, thread-safe queue was modeled after ringbuffer example from boost?! and/or a Herb Sutter column?!
Definition: DaqController.h:7
void Set(const bool &_a=true)
Definition: helpers.h:108
SynchronizedQueue< const std::function< void(StopCondition *const sc)> > ptq
synchronized queue of worker functions/packaged tasks that are executed in the Active' thread (see la...
Definition: Active.h:26
std::thread thread
a thread in which Run runs
Definition: Active.h:29
void operator=(const Active &)
disable assignment
Various helper functions and classes for Scope.
T Dequeue()
Dequeues front element, waits indefinitely if queue is empty.
Definition: SyncQueues.h:61