Allow external handles to be provided to gpui_tokio (#42795)
This PR allows for a handle to an existing Tokio runtime to be passed to gpui_tokio's initialization function, which means that Tokio runtimes created externally can be used. Mikayla suggested that the function simply take the runtime from whatever context the initialization function is called from but I think there could reasonably be situations where that isn't the case and this shouldn't have a meaningful impact to code complexity. If you want to use the current context's runtime you can just do `gpui_tokio::init_from_handle(cx, Handle::current());`. This doesn't have an impact on the current users of the crate - the existing `init()` function is functionally unchanged. Release Notes: - N/A
This commit is contained in:
committed by
GitHub
parent
f4c3a6c236
commit
158ebdc580
@@ -5,25 +5,48 @@ use util::defer;
|
||||
|
||||
pub use tokio::task::JoinError;
|
||||
|
||||
/// Initializes the Tokio wrapper using a new Tokio runtime with 2 worker threads.
|
||||
///
|
||||
/// If you need more threads (or access to the runtime outside of GPUI), you can create the runtime
|
||||
/// yourself and pass a Handle to `init_from_handle`.
|
||||
pub fn init(cx: &mut App) {
|
||||
cx.set_global(GlobalTokio::new());
|
||||
let runtime = tokio::runtime::Builder::new_multi_thread()
|
||||
// Since we now have two executors, let's try to keep our footprint small
|
||||
.worker_threads(2)
|
||||
.enable_all()
|
||||
.build()
|
||||
.expect("Failed to initialize Tokio");
|
||||
|
||||
cx.set_global(GlobalTokio::new(RuntimeHolder::Owned(runtime)));
|
||||
}
|
||||
|
||||
/// Initializes the Tokio wrapper using a Tokio runtime handle.
|
||||
pub fn init_from_handle(cx: &mut App, handle: tokio::runtime::Handle) {
|
||||
cx.set_global(GlobalTokio::new(RuntimeHolder::Shared(handle)));
|
||||
}
|
||||
|
||||
enum RuntimeHolder {
|
||||
Owned(tokio::runtime::Runtime),
|
||||
Shared(tokio::runtime::Handle),
|
||||
}
|
||||
|
||||
impl RuntimeHolder {
|
||||
pub fn handle(&self) -> &tokio::runtime::Handle {
|
||||
match self {
|
||||
RuntimeHolder::Owned(runtime) => runtime.handle(),
|
||||
RuntimeHolder::Shared(handle) => handle,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct GlobalTokio {
|
||||
runtime: tokio::runtime::Runtime,
|
||||
runtime: RuntimeHolder,
|
||||
}
|
||||
|
||||
impl Global for GlobalTokio {}
|
||||
|
||||
impl GlobalTokio {
|
||||
fn new() -> Self {
|
||||
let runtime = tokio::runtime::Builder::new_multi_thread()
|
||||
// Since we now have two executors, let's try to keep our footprint small
|
||||
.worker_threads(2)
|
||||
.enable_all()
|
||||
.build()
|
||||
.expect("Failed to initialize Tokio");
|
||||
|
||||
fn new(runtime: RuntimeHolder) -> Self {
|
||||
Self { runtime }
|
||||
}
|
||||
}
|
||||
@@ -40,7 +63,7 @@ impl Tokio {
|
||||
R: Send + 'static,
|
||||
{
|
||||
cx.read_global(|tokio: &GlobalTokio, cx| {
|
||||
let join_handle = tokio.runtime.spawn(f);
|
||||
let join_handle = tokio.runtime.handle().spawn(f);
|
||||
let abort_handle = join_handle.abort_handle();
|
||||
let cancel = defer(move || {
|
||||
abort_handle.abort();
|
||||
@@ -62,7 +85,7 @@ impl Tokio {
|
||||
R: Send + 'static,
|
||||
{
|
||||
cx.read_global(|tokio: &GlobalTokio, cx| {
|
||||
let join_handle = tokio.runtime.spawn(f);
|
||||
let join_handle = tokio.runtime.handle().spawn(f);
|
||||
let abort_handle = join_handle.abort_handle();
|
||||
let cancel = defer(move || {
|
||||
abort_handle.abort();
|
||||
|
||||
Reference in New Issue
Block a user