rt: internally split Handle into two structs (#4629)

Previously, `runtime::Handle` was a single struct composed of the
internal handles for each runtime component. This patch splits the
`Handle` struct into a `HandleInner` which contains everything
**except** the task scheduler handle. Now, `HandleInner` is passed to
the task scheduler during creation and the task scheduler is responsible
for storing it. `Handle` only  needs to hold the scheduler handle and
can access the rest of the component handles by querying the task
scheduler.

The motivation for this change is it now enables the multi-threaded
scheduler to have direct access to the blocking spawner handle.
Previously, when spawning a new thread, the multi-threaded scheduler had
to access the blocking spawner by accessing a thread-local variable.
Now, in theory, the multi-threaded scheduler can use `HandleInner`
directly. However, this change hasn't been done in this PR yet.

Also, now the `Handle` struct is much smaller.

This change is intended to make it easier for the multi-threaded
scheduler to shutdown idle threads and respawn them on demand.
This commit is contained in:
Carl Lerche
2022-04-20 12:56:55 -07:00
committed by GitHub
parent d590a369d5
commit 911a0efa87
16 changed files with 235 additions and 166 deletions
+6 -6
View File
@@ -7,7 +7,7 @@ use crate::runtime::blocking::shutdown;
use crate::runtime::builder::ThreadNameFn;
use crate::runtime::context;
use crate::runtime::task::{self, JoinHandle};
use crate::runtime::{Builder, Callback, Handle};
use crate::runtime::{Builder, Callback, ToHandle};
use std::collections::{HashMap, VecDeque};
use std::fmt;
@@ -129,7 +129,7 @@ cfg_fs! {
R: Send + 'static,
{
let rt = context::current();
rt.spawn_mandatory_blocking(func)
rt.as_inner().spawn_mandatory_blocking(&rt, func)
}
}
@@ -220,7 +220,7 @@ impl fmt::Debug for BlockingPool {
// ===== impl Spawner =====
impl Spawner {
pub(crate) fn spawn(&self, task: Task, rt: &Handle) -> Result<(), ()> {
pub(crate) fn spawn(&self, task: Task, rt: &dyn ToHandle) -> Result<(), ()> {
let mut shared = self.inner.shared.lock();
if shared.shutdown {
@@ -283,7 +283,7 @@ impl Spawner {
fn spawn_thread(
&self,
shutdown_tx: shutdown::Sender,
rt: &Handle,
rt: &dyn ToHandle,
id: usize,
) -> std::io::Result<thread::JoinHandle<()>> {
let mut builder = thread::Builder::new().name((self.inner.thread_name)());
@@ -292,12 +292,12 @@ impl Spawner {
builder = builder.stack_size(stack_size);
}
let rt = rt.clone();
let rt = rt.to_handle();
builder.spawn(move || {
// Only the reference should be moved into the closure
let _enter = crate::runtime::context::enter(rt.clone());
rt.blocking_spawner.inner.run(id);
rt.as_inner().blocking_spawner.inner.run(id);
drop(shutdown_tx);
})
}