-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathdispatcher.h
59 lines (47 loc) · 1.27 KB
/
dispatcher.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#pragma once
#include <event2/event.h>
#include <event2/thread.h>
#include <condition_variable>
#include <functional>
#include <queue>
namespace tl {
// event_base_dispatch wrapper
// accept callbacks to run inside the dispatch loop.
class Dispatcher {
public:
Dispatcher();
~Dispatcher();
// start dispatch loop.
void dispatch();
// stop dispatch loop.
void stop();
// wait dispatch loop to exit after call stop().
void join();
// Commit a function to be called inside the dispatch loop.
// It will be called in the callback of "ev_timer_".
template <class F, class... Args>
void post(F&& f, Args&&... args);
void timerCB();
event_base* ev_base() { return ev_base_; }
private:
struct event_base* ev_base_ = nullptr;
struct event* ev_timer_ = nullptr;
std::queue<std::function<void()> > post_callbacks_;
bool stop_ = false;
std::mutex mu_;
std::condition_variable cond_;
};
template <class F, class... Args>
void Dispatcher::post(F&& f, Args&&... args) {
bool do_post = false;
{
std::unique_lock<std::mutex> lock(mu_);
do_post = post_callbacks_.empty();
post_callbacks_.push(
std::bind(std::forward<F>(f), std::forward<Args>(args)...));
}
if (do_post) {
event_active(ev_timer_, 0, 0);
}
}
} // namespace tl