struct Data {
tasks: DenseSlotMap<Ti, Task>,
awake: VecDeque<Ti>,
progressing_until_stalled: Option<ProgressingUntilStalled>,
scheduling: SchedulingPolicy,
thread_to_run: ThreadDescriptor,
}
Expand description
Executor’s state
§Task state machine
A task is created in tasks
, Awake
, so also in awake
.
When we poll it, we take it out of awake
and set it to Asleep
,
and then call poll()
.
Any time after that, it can be made Awake
again (and put back onto awake
)
by the waker (ActualWaker
, wrapped in Waker
).
The task’s future is of course also present here in this data structure.
However, during poll we must release the lock,
so we cannot borrow the future from Data
.
Instead, we move it out. So Task.fut
is an Option
.
§“Main” task - the argument to block_on
The signature of BlockOn::block_on
accepts a non-'static
future
(and a non-Send
/Sync
one).
So we cannot store that future in Data
because Data
is 'static
.
Instead, this main task future is passed as an argument down the call stack.
In the data structure we simply store a placeholder, TaskFutureInfo::Main
.
Fields§
§tasks: DenseSlotMap<Ti, Task>
Tasks
Includes tasks spawned with spawn
,
and also the future passed to block_on
.
awake: VecDeque<Ti>
awake
lists precisely: tasks that are Awake
, plus maybe stale TaskId
s
Tasks are pushed onto the back when woken, so back is the most recently woken.
progressing_until_stalled: Option<ProgressingUntilStalled>
If a future from progress_until_stalled
exists
scheduling: SchedulingPolicy
Scheduling policy
thread_to_run: ThreadDescriptor
(Sub)thread we want to run now
At any one time only one thread is meant to be running. Other threads are blocked in condvar wait, waiting for this to change.
Modified only within
thread_context_switch_send_instruction_to_run
,
which takes responsibility for preserving the following invariants:
- no-one but the named thread is allowed to modify this field.
- after modifying this field, signal
thread_condvar
Implementations§
Source§impl Data
impl Data
Sourcefn insert_task(&mut self, desc: String, fut: TaskFutureInfo) -> TaskId
fn insert_task(&mut self, desc: String, fut: TaskFutureInfo) -> TaskId
Insert a task given its TaskFutureInfo
and return its TaskId
.
Source§impl Data
impl Data
Sourcefn dump_backtraces(&self, f: &mut Formatter<'_>) -> Result
fn dump_backtraces(&self, f: &mut Formatter<'_>) -> Result
Dump tasks and their sleep location backtraces
Source§impl Data
impl Data
Sourcefn debug_dump(&mut self)
fn debug_dump(&mut self)
Convenience function: dump including backtraces, to stderr
Trait Implementations§
Source§impl From<Data> for MockExecutor
impl From<Data> for MockExecutor
Source§fn from(data: Data) -> MockExecutor
fn from(data: Data) -> MockExecutor
Auto Trait Implementations§
impl Freeze for Data
impl !RefUnwindSafe for Data
impl Send for Data
impl !Sync for Data
impl Unpin for Data
impl !UnwindSafe for Data
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<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more