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