librf

_awaker.h
1 #pragma once
2
3 #ifndef DOXYGEN_SKIP_PROPERTY
4
5 namespace resumef
6 {
7 namespace detail
8 {
9 template<class _Ety, class... _Types>
10 struct _awaker
11 {
12 //如果超时
13 // e 始终为nullptr
14 // 不关心返回值
15 //如果不是超时，
16 // e 指向当前触发的事件，用于实现wait_any
17 // 返回true表示成功触发了事件，event内部减小一次事件计数，并删除此awaker
18 // 返回false表示此事件已经无效，event内部只删除此awaker
19 typedef std::function<bool(_Ety * e, _Types...)> callee_type;
20 private:
21 typedef spinlock lock_type;
22 //typedef std::recursive_mutex lock_type;
23
24 lock_type _lock;
25 callee_type _callee;
26 std::atomic<intptr_t> _counter;
27 public:
28 _awaker(callee_type && callee_, intptr_t init_count_ = 0)
29 : _callee(std::forward<callee_type>(callee_))
30 , _counter(init_count_)
31 {
32 }
33
34 //调用一次后，_callee就被置nullptr，下次再调用，必然返回false
35 //第一次调用，返回调用_callee的返回值
36 //超时通过传入nullptr来调用
37 bool awake(_Ety * e, intptr_t count_, const _Types&... args)
38 {
39 assert(count_ > 0);
40 scoped_lock<lock_type> lock_(this->_lock);
41
42 if ((this->_counter.fetch_sub(count_) - count_) <= 0)
43 {
44 if (this->_callee)
45 {
46 callee_type callee_ = std::move(this->_callee);
47 return callee_(e, args...);
48 }
49 return false;
50 }
51 return true;
52 }
53
54 private:
55 _awaker(const _awaker &) = delete;
56 _awaker(_awaker &&) = delete;
57 _awaker & operator = (const _awaker &) = delete;
58 _awaker & operator = (_awaker &&) = delete;
59 };
60 }
61 }
62
63 #endif //DOXYGEN_SKIP_PROPERTY
64