pub struct Signal { /* private fields */ }Expand description
A data structure that can be used to wake other workers.
To use this struct, you must register worker handles through
Signal::set_handles, then you can make use of sleep/wake methods like
so,
Signal::wait: Sleep indefinitely.Signal::notify: Wake a specific worker.Signal::notify_one: Wake a random worker.Signal::notify_all: Wake all workers.
Implementations§
Source§impl Signal
impl Signal
Sourcepub fn new(seed: NonZeroU32) -> Self
pub fn new(seed: NonZeroU32) -> Self
Creates a new empty Signal with the given random seed number.
Don’t forget to call Signal::set_handles before using the signal.
§Examples
use my_ecs::ds::Signal;
use std::num::NonZeroU32;
let signal = Signal::new(NonZeroU32::MIN);Sourcepub fn set_handles(&mut self, handles: Vec<Thread>) -> Vec<Thread>
pub fn set_handles(&mut self, handles: Vec<Thread>) -> Vec<Thread>
Sets worker handles to the signal then returns former worker handles.
§Examples
use my_ecs::ds::Signal;
use std::thread;
let join = thread::spawn(|| { /* ... */ });
let handle = join.thread().clone();
let mut signal = Signal::default();
signal.set_handles(vec![handle]);Sourcepub fn wait(&self, this_index: usize)
pub fn wait(&self, this_index: usize)
Blocks until another worker signals.
- this_index - Index to the handle of this worker in the vector that
you inserted through
Signal::set_handles.
Current worker cannot be woken up unless another worker wakes the
current worker through Signal because this method blocks repeatedly
to ignore spurious wakeup. See park for more details.
Also, note that signaling looks like being buffered in a single slot.
For example, if another worker woke current worker up and current worker
didn’t sleep at that time, next call to Signal::wait will consume
the signal in the single slot buffer then be ignored.
§Note
index is an index for the current worker handle in the vector you
inserted at Signal::set_handles. By receiving the index from
caller, this method can avoid unnecessary matching opeartion. But note
that incorrect index causes panic or undefinitely long sleep.
§Examples
use my_ecs::ds::Signal;
let mut signal = Signal::default();
let handle = std::thread::current();
signal.set_handles(vec![handle, /* other handles */]);
// Current worker will be blocked by this call.
signal.wait(0); // Current handle index is 0.Sourcepub fn notify(&self, target_index: usize)
pub fn notify(&self, target_index: usize)
Wakes up a worker for the given target index or another worker.
- target_index - Index to a handle of the vector that you inserted
through
Signal::set_handles.
If the target worker is not blocked at the time, tries to wake another
worker instead. If failed to wake any worker, then mark ALARM on the
target worker, so that the worker will not be blocked by
Signal::wait next time.
§Examples
use my_ecs::ds::Signal;
use std::thread;
let mut signal = Signal::default();
// Worker A.
let join_a = thread::spawn(|| { /* ... */});
let handle_a = join_a.thread().clone();
// Worker B.
let join_b = thread::spawn(|| { /* ... */});
let handle_b = join_b.thread().clone();
signal.set_handles(vec![handle_a, handle_b]);
// Wakes up worker A.
signal.notify(0);
// Wakes up worker B.
signal.notify(1);
Sourcepub fn notify_one(&self)
pub fn notify_one(&self)
Wakes up a random worker.
If failed to wake any worker, then mark ALARM on one worker, so that
the worker will not be blocked by Signal::wait next time.
§Examples
use my_ecs::ds::Signal;
use std::thread;
let mut signal = Signal::default();
// Worker A.
let join_a = thread::spawn(|| { /* ... */});
let handle_a = join_a.thread().clone();
// Worker B.
let join_b = thread::spawn(|| { /* ... */});
let handle_b = join_b.thread().clone();
signal.set_handles(vec![handle_a, handle_b]);
// Wakes up one random worker.
signal.notify_one();
Sourcepub fn notify_all(&self)
pub fn notify_all(&self)
Wakes up all workers.
Each worker is marked ALARM when it’s not blocked at the time, so that
the worker will not be blocked by Signal::wait next time.
§Examples
use my_ecs::ds::Signal;
use std::thread;
let mut signal = Signal::default();
// Worker A.
let join_a = thread::spawn(|| { /* ... */});
let handle_a = join_a.thread().clone();
// Worker B.
let join_b = thread::spawn(|| { /* ... */});
let handle_b = join_b.thread().clone();
signal.set_handles(vec![handle_a, handle_b]);
// Wakes up all workers, Worker A & B.
signal.notify_all();
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for Signal
impl RefUnwindSafe for Signal
impl Send for Signal
impl Sync for Signal
impl Unpin for Signal
impl UnwindSafe for Signal
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more