Brian Silverman | f5f3490 | 2015-03-29 17:57:59 -0400 | [diff] [blame] | 1 | #ifndef AOS_COMMON_EVENT_H_ |
| 2 | #define AOS_COMMON_EVENT_H_ |
| 3 | |
Brian Silverman | 3060894 | 2015-04-08 19:16:46 -0400 | [diff] [blame] | 4 | #include "aos/common/time.h" |
| 5 | |
Brian Silverman | f5f3490 | 2015-03-29 17:57:59 -0400 | [diff] [blame] | 6 | #include "aos/linux_code/ipc_lib/aos_sync.h" |
| 7 | |
| 8 | namespace aos { |
| 9 | |
| 10 | // An abstraction of an event which is easy to implement for Linux and in other |
| 11 | // environments. |
| 12 | // On Linux at least, this is definitely safe for passing through C code with |
| 13 | // memcpy etc. |
| 14 | // |
| 15 | // An event is either "set" or "unset". Any thread can transition it between |
| 16 | // these two states and other threads can wait for an unset->set transition. |
| 17 | // This is not a particularly powerful synchronization primitive, but it can be |
| 18 | // much easier to use than more complicated ones in some situations. The name is |
| 19 | // taken from Python's implementation of the same thing. |
| 20 | // |
| 21 | // An event is equivalent to a semaphore which is either set to 0 or infinity. |
| 22 | // It is also equivalent to a condition variable with the monitored condition |
| 23 | // being "is it set or not". |
| 24 | // |
| 25 | // IMPORTANT: You can NOT use this to successfully replace a standard condition |
| 26 | // variable in most cases. When the condition being monitored changes separately |
| 27 | // from the actual state of the condition variable/event, there WILL be race |
| 28 | // conditions if you try to use this class. |
| 29 | // |
| 30 | // It is undefined behavior to destroy an Event while there are current |
| 31 | // Wait()ers. |
| 32 | class Event { |
| 33 | public: |
| 34 | // Creates an unset event. |
| 35 | Event(); |
| 36 | // There must be no waiters when an Event is destroyed. |
| 37 | ~Event() = default; |
| 38 | |
| 39 | // Waits for the event to be set. Returns immediately if it is already set. |
| 40 | void Wait(); |
| 41 | |
Brian Silverman | 3060894 | 2015-04-08 19:16:46 -0400 | [diff] [blame] | 42 | // Waits for the event to be set or until timeout has elapsed. Returns |
| 43 | // immediately if it is already set. |
| 44 | // Returns true if the event was Set or false if the timeout expired. |
Austin Schuh | f2a50ba | 2016-12-24 16:16:26 -0800 | [diff] [blame^] | 45 | bool WaitTimeout(monotonic_clock::duration timeout); |
Brian Silverman | 3060894 | 2015-04-08 19:16:46 -0400 | [diff] [blame] | 46 | |
Brian Silverman | f5f3490 | 2015-03-29 17:57:59 -0400 | [diff] [blame] | 47 | // Wakes up all Wait()ers and sets the event (atomically). |
| 48 | void Set(); |
| 49 | // Unsets the event so future Wait() callers will block instead of returning |
| 50 | // immediately. |
| 51 | // Returns true if the event was previously set. |
| 52 | bool Clear(); |
| 53 | |
| 54 | private: |
| 55 | aos_futex impl_; |
| 56 | }; |
| 57 | |
| 58 | } // namespace aos |
| 59 | |
| 60 | #endif // AOS_COMMON_EVENT_H_ |