Struct corosensei::ScopedCoroutine
source · pub struct ScopedCoroutine<'a, Input, Yield, Return, Stack: Stack> { /* private fields */ }
Expand description
A coroutine wraps a closure and allows suspending its execution more than once, returning a value each time.
Lifetime
The 'a
lifetime here refers to the lifetime of the initial function in a
coroutine and ensures that the coroutine doesn’t exceed the lifetime of the
initial function.
Dropping a coroutine
When a coroutine is dropped, its stack must be unwound so that all object on
it are properly dropped. This is done by calling force_unwind
to unwind
the stack. If force_unwind
fails then the program is aborted.
See the Coroutine::force_unwind
function for more details.
Send
In the general case, a coroutine can only be sent to another if all of the
data on its stack is Send
. There is no way to guarantee this using Rust
language features so Coroutine
does not implement the Send
trait.
However if all of the code executed by a coroutine is under your control and
you can ensure that all types on the stack when a coroutine is suspended
are Send
then it is safe to manually implement Send
for a coroutine.
Implementations§
source§impl<'a, Input, Yield, Return> ScopedCoroutine<'a, Input, Yield, Return, DefaultStack>
impl<'a, Input, Yield, Return> ScopedCoroutine<'a, Input, Yield, Return, DefaultStack>
sourcepub fn new<F>(f: F) -> Selfwhere
F: FnOnce(&Yielder<Input, Yield>, Input) -> Return + 'a,
pub fn new<F>(f: F) -> Selfwhere F: FnOnce(&Yielder<Input, Yield>, Input) -> Return + 'a,
Creates a new coroutine which will execute func
on a new stack.
This function returns a Coroutine
which, when resumed, will execute
func
to completion. When desired the func
can suspend itself via
Yielder::suspend
.
source§impl<'a, Input, Yield, Return, Stack: Stack> ScopedCoroutine<'a, Input, Yield, Return, Stack>
impl<'a, Input, Yield, Return, Stack: Stack> ScopedCoroutine<'a, Input, Yield, Return, Stack>
sourcepub fn with_stack<F>(stack: Stack, f: F) -> Selfwhere
F: FnOnce(&Yielder<Input, Yield>, Input) -> Return + 'a,
pub fn with_stack<F>(stack: Stack, f: F) -> Selfwhere F: FnOnce(&Yielder<Input, Yield>, Input) -> Return + 'a,
Creates a new coroutine which will execute func
on the given stack.
This function returns a coroutine which, when resumed, will execute
func
to completion. When desired the func
can suspend itself via
Yielder::suspend
.
sourcepub fn resume(&mut self, val: Input) -> CoroutineResult<Yield, Return>
pub fn resume(&mut self, val: Input) -> CoroutineResult<Yield, Return>
Resumes execution of this coroutine.
This function will transfer execution to the coroutine and resume from where it last left off.
If the coroutine calls Yielder::suspend
then this function returns
CoroutineResult::Yield
with the value passed to suspend
.
If the coroutine returns then this function returns
CoroutineResult::Return
with the return value of the coroutine.
Panics
Panics if the coroutine has already finished executing.
If the coroutine itself panics during execution then the panic will be propagated to this caller.
sourcepub fn done(&self) -> bool
pub fn done(&self) -> bool
Returns whether this coroutine has finished executing.
A coroutine that has returned from its initial function can no longer be resumed.
sourcepub unsafe fn force_reset(&mut self)
pub unsafe fn force_reset(&mut self)
Forcibly marks the coroutine as having completed, even if it is currently suspended in the middle of a function.
Safety
This is equivalent to a longjmp
all the way back to the initial
function of the coroutine, so the same rules apply.
This can only be done safely if there are no objects currently on the
coroutine’s stack that need to execute Drop
code.
sourcepub fn force_unwind(&mut self)
pub fn force_unwind(&mut self)
Unwinds the coroutine stack, dropping any live objects that are currently on the stack. This is automatically called when the coroutine is dropped.
If the coroutine has already completed then this function is a no-op.
If the coroutine is currently suspended on a Yielder::suspend
call
then unwinding it requires the unwind
feature to be enabled and
for the crate to be compiled with -C panic=unwind
.
Panics
This function panics if the coroutine could not be fully unwound. This can happen for one of two reasons:
- The
ForcedUnwind
panic that is used internally was caught and not rethrown. - This crate was compiled without the
unwind
feature and the coroutine is currently suspended in the yielder (started && !done
).
sourcepub fn into_stack(self) -> Stack
pub fn into_stack(self) -> Stack
Extracts the stack from a coroutine that has finished executing.
This allows the stack to be re-used for another coroutine.
sourcepub fn trap_handler(&self) -> CoroutineTrapHandler<Return>
pub fn trap_handler(&self) -> CoroutineTrapHandler<Return>
Returns a CoroutineTrapHandler
which can be used to handle traps that
occur inside the coroutine. Examples of traps that can be handled are
invalid memory accesses and stack overflows.
The returned CoroutineTrapHandler
can be used in a trap handler to
force the trapping coroutine to return with a specific value, after
which is it considered to have completed and can no longer be resumed.
Needless to say, this is extremely unsafe and must be used with extreme
care. See CoroutineTrapHandler::setup_trap_handler
for the exact
safety requirements.