pub struct ExitStack<Mem> { /* private fields */ }
Expand description
Provides memory suitable for dynamically stack-allocating pinned values.
Alternatively, you can also use this as a pre-allocated buffer for pinning values to the heap.
The internal implementation guarantees that the stack can allocate at least one value of type
Mem
. Also, there will be no changes that reduce the amount of values in a patch version, it
will require require at least a minor version bump.
Implementations§
Source§impl<Mem> ExitStack<Mem>
impl<Mem> ExitStack<Mem>
Sourcepub fn new() -> Self
pub fn new() -> Self
Create an empty exit stack.
The available memory for the stack is specified by the Mem
type parameter.
Sourcepub fn slot<'stack, T: 'static>(
self: Pin<&'stack Self>,
) -> Option<Slot<'stack, T>>
pub fn slot<'stack, T: 'static>( self: Pin<&'stack Self>, ) -> Option<Slot<'stack, T>>
Prepare a slot for pinning a value to the stack.
Note that dropping may be delayed arbitrarily since this method can’t control when the
ExitStack
itself is dropped. Thus the pinned value must not borrow temporary data.
Sourcepub fn set<'stack>(
self: Pin<&'stack mut Self>,
val: Mem,
) -> Pin<&'stack mut Mem>where
Mem: 'static,
pub fn set<'stack>(
self: Pin<&'stack mut Self>,
val: Mem,
) -> Pin<&'stack mut Mem>where
Mem: 'static,
Infallibly get a slot for the type of the memory, and pin a value.
This is useful a small utility wrapper if you want to have a small ‘stack’ that can make room for a single entry, on demand. All other entries in the exit stack will be popped, and the memory allocator will be cleared before the new value is pinned.
You can also use this method to defer dropping of a pinned task beyond your own method’s body.
§Usage
use core::pin::Pin;
use exit_stack::ExitStack;
// Some async future that is not Unpin.
#[derive(Default)]
struct Task {
// ..
}
async fn with_stack(mut stack: Pin<&mut ExitStack<Task>>) {
stack.as_mut().set(Task::default()).await;
// Reuse the stack another time.
// The previous task is dropped.
stack.as_mut().set(Task::default()).await;
// Note that the second task still lives when we return.
}