Skip to content

Commit

Permalink
rt: fix error when calling block_on twice (#162)
Browse files Browse the repository at this point in the history
This fixes an issue where we would try and spawn a separate background task on the `LocalSet` for watching the `AsyncFd` for the uring instance every time we called `block_on`. Now, we only spawn at runtime creation.
  • Loading branch information
Noah-Kennedy authored Nov 3, 2022
1 parent b0e973a commit 046d09b
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 20 deletions.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ tokio-test = "0.4.2"
iai = "0.1.1"
futures = "0.3.25"
criterion = "0.4.0"
# we use joinset in our tests
tokio = "1.21.0"

[package.metadata.docs.rs]
all-features = true
Expand Down
33 changes: 13 additions & 20 deletions src/runtime/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::driver::Driver;
use std::future::Future;
use std::io;
use std::mem::ManuallyDrop;
use std::os::unix::io::{AsRawFd, RawFd};
use std::os::unix::io::AsRawFd;
use tokio::io::unix::AsyncFd;
use tokio::task::LocalSet;

Expand All @@ -17,9 +17,6 @@ thread_local! {

/// The Runtime executor
pub struct Runtime {
/// io-uring driver
uring_fd: RawFd,

/// LocalSet for !Send tasks
local: ManuallyDrop<LocalSet>,

Expand Down Expand Up @@ -79,21 +76,9 @@ impl Runtime {

CONTEXT.with(|cx| cx.set_driver(driver));

Ok(Runtime {
uring_fd: driver_fd,
local,
rt,
})
}

/// Runs a future to completion on the current runtime
pub fn block_on<F>(&self, future: F) -> F::Output
where
F: Future,
{
let drive = {
let _guard = self.rt.enter();
let driver = AsyncFd::new(self.uring_fd).unwrap();
let _guard = rt.enter();
let driver = AsyncFd::new(driver_fd).unwrap();

async move {
loop {
Expand All @@ -105,9 +90,17 @@ impl Runtime {
}
};

tokio::pin!(future);
local.spawn_local(drive);

self.local.spawn_local(drive);
Ok(Runtime { local, rt })
}

/// Runs a future to completion on the current runtime
pub fn block_on<F>(&self, future: F) -> F::Output
where
F: Future,
{
tokio::pin!(future);

self.rt
.block_on(self.local.run_until(crate::future::poll_fn(|cx| {
Expand Down

0 comments on commit 046d09b

Please sign in to comment.