| 14 | namespace platforms { |
| 15 | |
| 16 | class ChannelPollSignal { |
| 17 | public: |
| 18 | ChannelPollSignal() FL_NOEXCEPT : mSignal(0), mPending(false) {} |
| 19 | |
| 20 | void notify() FL_NOEXCEPT { |
| 21 | const bool alreadyPending = mPending.exchange(true, fl::memory_order_acq_rel); |
| 22 | if (!alreadyPending) { |
| 23 | mSignal.release(); |
| 24 | } |
| 25 | } |
| 26 | |
| 27 | bool wait(fl::u32 timeoutMs) FL_NOEXCEPT { |
| 28 | const bool signaled = (timeoutMs == 0) ? waitForever() : mSignal.try_acquire_for_ms(timeoutMs); |
| 29 | if (signaled) { |
| 30 | mPending.store(false, fl::memory_order_release); |
| 31 | } |
| 32 | return signaled; |
| 33 | } |
| 34 | |
| 35 | private: |
| 36 | bool waitForever() FL_NOEXCEPT { |
| 37 | mSignal.acquire(); |
| 38 | return true; |
| 39 | } |
| 40 | |
| 41 | fl::binary_semaphore mSignal; |
| 42 | fl::atomic_bool mPending; |
| 43 | }; |
| 44 | |
| 45 | } // namespace platforms |
| 46 | } // namespace fl |