waitable_event.h 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. // Windows-like event sync object
  2. //
  3. // Platform: ISO C++ 11
  4. // $Id$
  5. //
  6. // (c) __vic 2011
  7. #ifndef __VIC_WAITABLE_EVENT_H
  8. #define __VIC_WAITABLE_EVENT_H
  9. #include<__vic/defs.h>
  10. #include<mutex>
  11. #include<condition_variable>
  12. #include<atomic>
  13. #include<chrono>
  14. namespace __vic {
  15. //////////////////////////////////////////////////////////////////////////////
  16. class waitable_event
  17. {
  18. std::mutex mtx;
  19. std::condition_variable cond;
  20. class atomic_bool
  21. {
  22. std::atomic<bool> v;
  23. public:
  24. explicit atomic_bool(bool val) : v(val) {}
  25. void operator=(bool val) { v.store(val, std::memory_order_release); }
  26. bool load() const { return v.load(std::memory_order_acquire); }
  27. } signaled_;
  28. public:
  29. explicit waitable_event(bool = false);
  30. ~waitable_event();
  31. void set();
  32. void reset() { signaled_ = false; } // clear the signaled state
  33. bool signaled() const { return signaled_.load(); }
  34. void wait();
  35. template<class Rep, class Period>
  36. bool wait_for(const std::chrono::duration<Rep,Period> & );
  37. template<class Clock, class Duration>
  38. bool wait_until(const std::chrono::time_point<Clock,Duration> & );
  39. };
  40. //////////////////////////////////////////////////////////////////////////////
  41. //----------------------------------------------------------------------------
  42. template<class R, class P>
  43. bool waitable_event::wait_for(const std::chrono::duration<R,P> &t)
  44. {
  45. if(signaled()) return true;
  46. std::unique_lock<std::mutex> lock(mtx);
  47. auto &s = signaled_;
  48. return cond.wait_for(lock, t, [&s]{ return s.load(); });
  49. }
  50. //----------------------------------------------------------------------------
  51. template<class C, class D>
  52. bool waitable_event::wait_until(const std::chrono::time_point<C,D> &t)
  53. {
  54. if(signaled()) return true;
  55. std::unique_lock<std::mutex> lock(mtx);
  56. auto &s = signaled_;
  57. return cond.wait_until(lock, t, [&s]{ return s.load(); });
  58. }
  59. //----------------------------------------------------------------------------
  60. } // namespace
  61. #endif // header guard