pub struct PreSend<T> { /* private fields */ }
Expand description
Registry for parking SendRc
s 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
SendRc
s.
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
SendRc
s that point to the value.
It is allowed to park SendRc
s 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
SendRc
s 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 SendRc
s pointing to values whose SendRc
s
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 SendRc
s 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 SendRc
s pointing to values whose
SendRc
s 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 parked
Sourcepub 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
SendRc
that was already visited while traversing a graph ofSendRc
s (sendrc_parked
) - detecting whether the value behind this
SendRc
is unreachable because one or moreSendRc
s 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 parked
Panics when invoked from a different thread than the one the SendRc
was created
in or last pinned to.