1 | use std::{thread::{self, Thread}, time::Duration, any::Any}; |
2 | |
3 | pub trait Signal: Send + Sync + 'static { |
4 | /// Fire the signal, returning whether it is a stream signal. This is because streams do not |
5 | /// acquire a message when woken, so signals must be fired until one that does acquire a message |
6 | /// is fired, otherwise a wakeup could be missed, leading to a lost message until one is eagerly |
7 | /// grabbed by a receiver. |
8 | fn fire(&self) -> bool; |
9 | fn as_any(&self) -> &(dyn Any + 'static); |
10 | fn as_ptr(&self) -> *const (); |
11 | } |
12 | |
13 | pub struct SyncSignal(Thread); |
14 | |
15 | impl Default for SyncSignal { |
16 | fn default() -> Self { |
17 | Self(thread::current()) |
18 | } |
19 | } |
20 | |
21 | impl Signal for SyncSignal { |
22 | fn fire(&self) -> bool { |
23 | self.0.unpark(); |
24 | false |
25 | } |
26 | fn as_any(&self) -> &(dyn Any + 'static) { self } |
27 | fn as_ptr(&self) -> *const () { self as *const _ as *const () } |
28 | } |
29 | |
30 | impl SyncSignal { |
31 | pub fn wait(&self) { thread::park(); } |
32 | pub fn wait_timeout(&self, dur: Duration) { thread::park_timeout(dur); } |
33 | } |
34 | |