pub struct PreSend<T> { /* private fields */ }Expand description
Registry for parking SendRcs so they can be sent to another thread.
This type is not Send; when finished with calls to park(), invoke ready()
to obtain a Send token that can be moved to the other thread to re-enable the
SendRcs.
Implementations§
Source§impl<T> PreSend<T>
impl<T> PreSend<T>
Sourcepub fn park<'a>(&'a self, send_rc: &'a mut SendRc<T>) -> &'a T
pub fn park<'a>(&'a self, send_rc: &'a mut SendRc<T>) -> &'a T
Park the value pointed to by send_rc.
Parking a value makes it inaccessible through this or any other SendRc that
points to it. Attempts to dereference, clone, or drop either this SendRc or any
other that points to the same value will trigger a panic. Additionally, park()
registers send_rc in particular as having participated in the parking.
To send a SendRc to a different thread, park() must be invoked on all the
SendRcs that point to the value.
It is allowed to park SendRcs pointing to different values of the same type in
the same PreSend. Parking a SendRc that was already parked in the same
PreSend is a no-op.
Returns a reference to the underlying value, which may be used to visit additional
SendRcs that are only reachable through the value.
Panics when invoked from a thread different than the one send_rc was created in
or last pinned to. Also panics when passed a send_rc that was already parked by
a different PreSend.
Sourcepub fn ready(self) -> PostSend<T>
pub fn ready(self) -> PostSend<T>
Checks that there remain no unparked SendRcs pointing to values whose SendRcs
were parked by this PreSend, and returns a PostSend that can pin them to
another thread.
At the point of invocation of ready(), the compiler will statically verify that
there are no outstanding references to the data pointed to by SendRcs parked by
this PostSend.
Panics if the above check fails, i.e. if is_ready() would
return false.
Sourcepub fn is_ready(&self) -> bool
pub fn is_ready(&self) -> bool
Returns true if there remain no unparked SendRcs pointing to values whose
SendRcs were parked by this PreSend.
If this returns true, it means ready() will succeed.
For example:
let mut r1 = SendRc::new(RefCell::new(1));
let mut r2 = SendRc::clone(&r1);
let mut q1 = SendRc::new(RefCell::new(1));
let mut q2 = SendRc::clone(&q1);
let pre_send = SendRc::pre_send();
pre_send.park(&mut r1);
assert!(!pre_send.is_ready()); // r2 still unparked
pre_send.park(&mut r2);
assert!(pre_send.is_ready()); // r1/r2 shared value fully parked, q1/q2 not involved
pre_send.park(&mut q1);
assert!(!pre_send.is_ready()); // r1/r2 ok, but q2 unparked
pre_send.park(&mut q2);
assert!(pre_send.is_ready()); // both r1/r2 and q1/q2 shared values fully parkedSourcepub fn park_status_of(&self, send_rc: &SendRc<T>) -> ParkStatus
pub fn park_status_of(&self, send_rc: &SendRc<T>) -> ParkStatus
Describes the park status of send_rc and the value it points to.
This is useful for:
- detecting a
SendRcthat was already visited while traversing a graph ofSendRcs (sendrc_parked) - detecting whether the value behind this
SendRcis unreachable because one or moreSendRcs pointing to it have been parked (value_parked)
let mut r1 = SendRc::new(RefCell::new(1));
let mut r2 = SendRc::clone(&r1);
let pre_send = SendRc::pre_send();
pre_send.park(&mut r1);
assert!(pre_send.park_status_of(&r1).sendrc_parked); // r1 is parked
assert!(!pre_send.park_status_of(&r2).sendrc_parked); // r2 is not yet parked
assert!(pre_send.park_status_of(&r1).value_parked); // the underlying value is parked
assert!(pre_send.park_status_of(&r2).value_parked); // the underlying value is parkedPanics when invoked from a different thread than the one the SendRc was created
in or last pinned to.