pub struct Task {
pub clock: VectorClock,
pub step_span: Span,
pub backtrace: Option<Backtrace>,
pub signature: TaskSignature,
/* private fields */
}Expand description
A Task represents a user-level unit of concurrency. Each task has an id that is unique within
the execution, and a state reflecting whether the task is runnable (enabled) or not.
Fields§
§clock: VectorClock§step_span: Span§backtrace: Option<Backtrace>If crate::CAPTURE_BACKTRACE is set then this will be populated on task block.
If the test then fails, then each task’s backtrace will be printed.
signature: TaskSignatureThe signature of a Task; this is an identifier that is not guaranteed to be unique but should be mostly stable across iterations in a single Shuttle test. Tasks with the same signature are very likely to exhibit similar behavior
Implementations§
Source§impl Task
impl Task
pub fn from_closure( f: Box<dyn FnOnce() + 'static>, stack_size: usize, id: TaskId, name: Option<String>, clock: VectorClock, parent_span_id: Option<Id>, schedule_len: usize, tag: Option<Arc<dyn Tag>>, parent_task_id: Option<TaskId>, signature: TaskSignature, ) -> Self
pub fn from_future<F>( future: F, stack_size: usize, id: TaskId, name: Option<String>, clock: VectorClock, parent_span_id: Option<Id>, schedule_len: usize, tag: Option<Arc<dyn Tag>>, parent_task_id: Option<TaskId>, signature: TaskSignature, ) -> Self
Sourcepub fn parent_task_id(&self) -> Option<TaskId>
pub fn parent_task_id(&self) -> Option<TaskId>
Returns the identifier of the task that spawned this task.
pub fn runnable(&self) -> bool
pub fn blocked(&self) -> bool
pub fn can_spuriously_wakeup(&self) -> bool
pub fn sleeping(&self) -> bool
pub fn finished(&self) -> bool
pub fn is_detached(&self) -> bool
pub fn detach(&mut self)
Sourcepub fn abort(&mut self)
pub fn abort(&mut self)
Wake this task so the Wrapper future can observe the abort flag on its next poll.
pub fn waker(&self) -> Waker
Sourcepub fn block(&mut self, allow_spurious_wakeups: bool)
pub fn block(&mut self, allow_spurious_wakeups: bool)
Block the current thread. If allow_spurious_wakeups is true, then the scheduler is
permitted to spuriously wake up the thread (though it will still not count as a live thread
for deadlock detection purposes for as long as it remains blocked).
pub fn sleep(&mut self)
pub fn unblock(&mut self)
pub fn finish(&mut self)
Sourcepub fn sleep_unless_woken(&mut self)
pub fn sleep_unless_woken(&mut self)
Potentially put this task to sleep after it was polled by the executor, unless someone has called its waker first.
A synchronous Task should never call this, because we want threads to be enabled-by-default to avoid bugs where Shuttle incorrectly omits a potential execution.
Sourcepub fn set_waiter(&mut self, waiter: TaskId) -> bool
pub fn set_waiter(&mut self, waiter: TaskId) -> bool
Register a waiter for this thread to terminate. Returns a boolean indicating whether the waiter should block or not. If false, this task has already finished, and so the waiter need not block.
pub fn take_waiter(&mut self) -> Option<TaskId>
pub fn name(&self) -> Option<String>
Sourcepub fn local<T: 'static>(
&self,
key: &'static LocalKey<T>,
) -> Option<Result<&T, AlreadyDestructedError>>
pub fn local<T: 'static>( &self, key: &'static LocalKey<T>, ) -> Option<Result<&T, AlreadyDestructedError>>
Retrieve a reference to the given thread-local storage slot.
Returns Some(Err(_)) if the slot has already been destructed. Returns None if the slot has not yet been initialized.
Sourcepub fn init_local<T: 'static>(&mut self, key: &'static LocalKey<T>, value: T)
pub fn init_local<T: 'static>(&mut self, key: &'static LocalKey<T>, value: T)
Initialize the given thread-local storage slot with a new value.
Panics if the slot has already been initialized.
Sourcepub fn pop_local(&mut self) -> Option<Box<dyn Any>>
pub fn pop_local(&mut self) -> Option<Box<dyn Any>>
Return ownership of the next still-initialized thread-local storage slot, to be used when running thread-local storage destructors.
TLS destructors are a little tricky:
- Their code can perform synchronization operations (and so require Shuttle to call back into ExecutionState), so we can’t drop them from within an ExecutionState borrow. Instead we move the contents of a slot to the caller to be dropped outside the borrow.
- It’s valid for destructors to read other TLS slots, although destructor order is
undefined. This also means it’s valid for a destructor to initialize another TLS slot.
To make this work, we run the destructors incrementally, so one destructor can initialize
another slot that just gets added via
init_locallike normal, and then will be available to be popped on a future call topop_local. To prevent an infinite loop, we forbid reinitializing a TLS slot whose destructor has already run, or is currently being run.
Sourcepub fn park(&mut self) -> bool
pub fn park(&mut self) -> bool
Park the task if its park token is unavailable. If the task blocks, then it will be woken up
when the token becomes available or spuriously without consuming the token (see the
documentation for std::thread::park, which says that “it may also return spuriously,
without consuming the token”). Returns true if the execution should switch to a different
task (e.g., if the token was unavailable).
Sourcepub fn unpark(&mut self)
pub fn unpark(&mut self)
Make the task’s park token available, and unblock the task if it was parked.
pub fn get_tag(&self) -> Option<Arc<dyn Tag>>
Sourcepub fn set_tag(&mut self, tag: Arc<dyn Tag>) -> Option<Arc<dyn Tag>>
pub fn set_tag(&mut self, tag: Arc<dyn Tag>) -> Option<Arc<dyn Tag>>
Sets the tag field of the current task.
Returns the tag which was there previously.
pub fn format_for_deadlock(&self) -> String
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for Task
impl !RefUnwindSafe for Task
impl !Send for Task
impl !Sync for Task
impl !UnwindSafe for Task
impl Unpin for Task
impl UnsafeUnpin for Task
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> FmtForward for T
impl<T> FmtForward for T
Source§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.Source§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.Source§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.Source§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.Source§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.Source§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.Source§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.Source§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
Source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
Source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
Source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.Source§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.Source§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<T> Tap for T
impl<T> Tap for T
Source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read moreSource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read moreSource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read moreSource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read moreSource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.Source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.Source§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.Source§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.Source§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.