Module lilos::handoff [−][src]
Mechanism for handing data from one task to another, minimizing copies.
There are two sides to a Handoff<T>
, the sender and the receiver. When both
the sender and receiver are ready, a single T
gets transferred from the
sender’s ownership to the receiver’s. In this case, “ready” means that
either the sender or receiver was already blocked waiting for its peer when
that peer arrived – with both tasks waiting at the handoff, we can copy the
data and then unblock both.
Because we don’t need any sort of holding area for a copy of the T
, a
Handoff<T>
is very small – about the size of two pointers.
In computer science this is referred to as a rendezvous, but that’s harder to spell than handoff.
Creating and using a Handoff
Because the Handoff
itself contains no storage, they’re cheap to create on
the stack. You then need to split
then into their Push
and Pop
ends –
these both borrow the Handoff
, so you need to keep it around. You can
then hand the ends off to other futures. A typical use case looks like this:
let mut handoff = Handoff::new(); let (push, pop) = handoff.split(); join!(data_producer(push), data_consumer(pop));
If you just want to synchronize two tasks at a rendezvous point, and don’t
need to move data, use Handoff<()>
. It does the right thing.
Caveats and alternatives
Only one Push
and Pop
can exist at a time – the compiler ensures this.
This simplifies the implementation quite a bit, but it means that if you
want a multi-party rendezvous this isn’t the right tool.
If you would like to be able to push data and go on about your business
without waiting for it to be popped, you want a queue, not a handoff. See
the spsc
module.
Note that none of these types are Send
or Sync
– they are very much not
thread safe, so they can be freely used across async
tasks but cannot be
shared with an interrupt handler. For the same reason, you probably don’t
want to attempt to store one in a static
– you will succeed with enough
unsafe
, but the result will not be useful! The queues provided in spsc
do not have this limitation, at the cost of being more work to set up.
Structs
Handoff | Shared control block for a |
Pop | Pop endpoint for a |
Push | Push endpoint for a |