Skip to content

Commit

Permalink
QoL improvements
Browse files Browse the repository at this point in the history
- Add prelude
- Split up IoBackend to IoBackendExt
- Test runtime integrations in mfio-rt
- Add SeekableRef
  • Loading branch information
h33p committed Dec 5, 2023
1 parent 54fe777 commit 2941ce7
Show file tree
Hide file tree
Showing 12 changed files with 329 additions and 107 deletions.
16 changes: 14 additions & 2 deletions mfio-derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,14 @@ pub fn io_read(item: TokenStream) -> TokenStream {
let impl_bounds = &st.generics.params;
let where_bounds = st.generics.where_clause.as_ref().map(|v| &v.predicates);

let impl_comma = if !impl_bounds.trailing_punct() && !impl_bounds.is_empty() {
Some(token::Comma::default())
} else {
None
};

quote! {
impl<__Pos: 'static, #impl_bounds> mfio::traits::sync::SyncIoRead<__Pos> for #ident #type_gens where #ident #type_gens: mfio::traits::IoRead<__Pos> + mfio::backend::IoBackend, #where_bounds {}
impl<#impl_bounds #impl_comma __Pos: 'static> mfio::traits::sync::SyncIoRead<__Pos> for #ident #type_gens where #ident #type_gens: mfio::traits::IoRead<__Pos> + mfio::backend::IoBackend, #where_bounds {}
}.into()
}

Expand All @@ -25,7 +31,13 @@ pub fn io_write(item: TokenStream) -> TokenStream {
let impl_bounds = &st.generics.params;
let where_bounds = st.generics.where_clause.as_ref().map(|v| &v.predicates);

let impl_comma = if !impl_bounds.trailing_punct() && !impl_bounds.is_empty() {
Some(token::Comma::default())
} else {
None
};

quote! {
impl<__Pos: 'static, #impl_bounds> mfio::traits::sync::SyncIoWrite<__Pos> for #ident #type_gens where #ident #type_gens: mfio::traits::IoWrite<__Pos> + mfio::backend::IoBackend, #where_bounds {}
impl<#impl_bounds #impl_comma __Pos: 'static> mfio::traits::sync::SyncIoWrite<__Pos> for #ident #type_gens where #ident #type_gens: mfio::traits::IoWrite<__Pos> + mfio::backend::IoBackend, #where_bounds {}
}.into()
}
2 changes: 1 addition & 1 deletion mfio-netfs/src/net/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use super::{FsRequest, FsResponse, HeaderRouter, Request, Response};
use async_mutex::Mutex as AsyncMutex;
use cglue::result::IntError;
use log::*;
use mfio::backend::IoBackend;
use mfio::backend::IoBackendExt;
use mfio::error::Error;
use mfio::io::{NoPos, OwnedPacket, PacketIoExt, PacketView, PacketVtblRef, Read};
use mfio::stdeq::Seekable;
Expand Down
3 changes: 2 additions & 1 deletion mfio-rt/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ nix = "0.26"
io-uring = { version = "0.6", optional = true }

[dev-dependencies]
mfio = { version = "0.1", path = "../mfio", default-features = false }
tokio = { version = "1", features = ["rt", "rt-multi-thread"] }
mfio = { version = "0.1", path = "../mfio", default-features = false, features = ["tokio", "async-io"] }
pollster = { version = "0.3.0", features = ["macro"] }
criterion = { version = "0.5", git = "https://github.com/h33p/criterion.rs", branch = "tput2", features = ["async_tokio", "async_smol", "async_futures"] }
rand = "0.8"
Expand Down
2 changes: 1 addition & 1 deletion mfio-rt/src/__doctest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::NativeRt;
#[cfg(any(miri, test, feature = "native", feature = "virt"))]
use core::future::Future;
#[cfg(any(miri, test, feature = "native", feature = "virt"))]
use mfio::backend::IoBackend;
use mfio::backend::IoBackendExt;

#[cfg(feature = "native")]
pub fn run_each<'a, Func: Fn(&'a NativeRt) -> F, F: Future>(func: Func) {
Expand Down
225 changes: 184 additions & 41 deletions mfio-rt/src/native/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1117,51 +1117,194 @@ mod tests {
}

#[cfg(test)]
test_suite!(tests_default, |test_name, closure| {
let _ = ::env_logger::builder().is_test(true).try_init();
let mut rt = crate::NativeRt::default();
let rt = staticify(&mut rt);
let dir = TempDir::new(test_name).unwrap();
rt.set_cwd(dir.path().to_path_buf());
rt.run(move |rt| {
let run = TestRun::new(rt, dir);
closure(run)
mod suite_tests {
use super::*;
test_suite!(tests_default, |test_name, closure| {
let _ = ::env_logger::builder().is_test(true).try_init();
let mut rt = crate::NativeRt::default();
let rt = staticify(&mut rt);
let dir = TempDir::new(test_name).unwrap();
rt.set_cwd(dir.path().to_path_buf());
rt.run(move |rt| {
let run = TestRun::new(rt, dir);
closure(run)
});
});
});

#[cfg(test)]
test_suite!(tests_all, |test_name, closure| {
let _ = ::env_logger::builder().is_test(true).try_init();
for (name, rt) in crate::NativeRt::builder().enable_all().build_each() {
println!("{name}");
if let Ok(mut rt) = rt {
let rt = staticify(&mut rt);
let dir = TempDir::new(test_name).unwrap();
rt.set_cwd(dir.path().to_path_buf());
rt.run(move |rt| {
let run = TestRun::new(rt, dir);
closure(run)
});
test_suite!(tests_all, |test_name, closure| {
let _ = ::env_logger::builder().is_test(true).try_init();
for (name, rt) in crate::NativeRt::builder().enable_all().build_each() {
println!("{name}");
if let Ok(mut rt) = rt {
let rt = staticify(&mut rt);
let dir = TempDir::new(test_name).unwrap();
rt.set_cwd(dir.path().to_path_buf());
rt.run(move |rt| {
let run = TestRun::new(rt, dir);
closure(run)
});
}
}
}
});
});

#[cfg(test)]
net_test_suite!(net_tests_default, |closure| {
let _ = ::env_logger::builder().is_test(true).try_init();
let mut rt = crate::NativeRt::default();
let rt = staticify(&mut rt);
rt.run(closure);
});
net_test_suite!(net_tests_default, |closure| {
let _ = ::env_logger::builder().is_test(true).try_init();
let mut rt = crate::NativeRt::default();
let rt = staticify(&mut rt);
rt.run(closure);
});

#[cfg(test)]
net_test_suite!(net_tests_all, |closure| {
let _ = ::env_logger::builder().is_test(true).try_init();
for (name, rt) in crate::NativeRt::builder().enable_all().build_each() {
println!("{name}");
if let Ok(mut rt) = rt {
let rt = staticify(&mut rt);
rt.run(closure);
net_test_suite!(net_tests_all, |closure| {
let _ = ::env_logger::builder().is_test(true).try_init();
for (name, rt) in crate::NativeRt::builder().enable_all().build_each() {
println!("{name}");
if let Ok(mut rt) = rt {
let rt = staticify(&mut rt);
rt.run(closure);
}
}
});

// Test with different async runtimes
#[cfg(unix)]
mod smol {
use super::*;

test_suite!(tests_default, |test_name, closure| {
let _ = ::env_logger::builder().is_test(true).try_init();

smol::block_on(async {
use mfio::backend::{integrations::async_io::AsyncIo, *};

let mut rt = crate::NativeRt::default();
let rt = staticify(&mut rt);
let dir = TempDir::new(test_name).unwrap();
rt.set_cwd(dir.path().to_path_buf());

AsyncIo::run_with_mut(rt, move |rt| {
let run = TestRun::new(rt, dir);
closure(run)
})
.await;
});
});

test_suite!(tests_all, |test_name, closure| {
let _ = ::env_logger::builder().is_test(true).try_init();

smol::block_on(async {
use mfio::backend::{integrations::async_io::AsyncIo, *};

for (name, rt) in crate::NativeRt::builder().enable_all().build_each() {
println!("{name}");
if let Ok(mut rt) = rt {
let rt = staticify(&mut rt);
let dir = TempDir::new(test_name).unwrap();
rt.set_cwd(dir.path().to_path_buf());
AsyncIo::run_with_mut(rt, move |rt| {
let run = TestRun::new(rt, dir);
closure(run)
})
.await;
}
}
});
});

net_test_suite!(net_tests_default, |closure| {
let _ = ::env_logger::builder().is_test(true).try_init();

smol::block_on(async {
use mfio::backend::{integrations::async_io::AsyncIo, *};
let mut rt = crate::NativeRt::default();
let rt = staticify(&mut rt);
AsyncIo::run_with_mut(rt, closure).await;
});
});

net_test_suite!(net_tests_all, |closure| {
let _ = ::env_logger::builder().is_test(true).try_init();
smol::block_on(async {
use mfio::backend::{integrations::async_io::AsyncIo, *};
for (name, rt) in crate::NativeRt::builder().enable_all().build_each() {
println!("{name}");
if let Ok(mut rt) = rt {
let rt = staticify(&mut rt);
AsyncIo::run_with_mut(rt, closure).await;
}
}
});
});
}

#[cfg(unix)]
mod tokio {
use super::*;

test_suite!(tests_default, |test_name, closure| {
let _ = ::env_logger::builder().is_test(true).try_init();

tokio::runtime::Runtime::new().unwrap().block_on(async {
use mfio::backend::{integrations::tokio::Tokio, *};

let mut rt = crate::NativeRt::default();
let rt = staticify(&mut rt);
let dir = TempDir::new(test_name).unwrap();
rt.set_cwd(dir.path().to_path_buf());

Tokio::run_with_mut(rt, move |rt| {
let run = TestRun::new(rt, dir);
closure(run)
})
.await;
});
});

test_suite!(tests_all, |test_name, closure| {
let _ = ::env_logger::builder().is_test(true).try_init();

tokio::runtime::Runtime::new().unwrap().block_on(async {
use mfio::backend::{integrations::tokio::Tokio, *};

for (name, rt) in crate::NativeRt::builder().enable_all().build_each() {
println!("{name}");
if let Ok(mut rt) = rt {
let rt = staticify(&mut rt);
let dir = TempDir::new(test_name).unwrap();
rt.set_cwd(dir.path().to_path_buf());
Tokio::run_with_mut(rt, move |rt| {
let run = TestRun::new(rt, dir);
closure(run)
})
.await;
}
}
});
});

net_test_suite!(net_tests_default, |closure| {
let _ = ::env_logger::builder().is_test(true).try_init();

tokio::runtime::Runtime::new().unwrap().block_on(async {
use mfio::backend::{integrations::tokio::Tokio, *};
let mut rt = crate::NativeRt::default();
let rt = staticify(&mut rt);
Tokio::run_with_mut(rt, closure).await;
});
});

net_test_suite!(net_tests_all, |closure| {
let _ = ::env_logger::builder().is_test(true).try_init();
tokio::runtime::Runtime::new().unwrap().block_on(async {
use mfio::backend::{integrations::tokio::Tokio, *};
for (name, rt) in crate::NativeRt::builder().enable_all().build_each() {
println!("{name}");
if let Ok(mut rt) = rt {
let rt = staticify(&mut rt);
Tokio::run_with_mut(rt, closure).await;
}
}
});
});
}
});
}
2 changes: 1 addition & 1 deletion mfio-rt/src/test_suite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pub use alloc::{
};
pub use core::future::Future;
pub use futures::StreamExt;
pub use mfio::backend::IoBackend;
pub use mfio::backend::IoBackendExt;
pub use mfio::traits::{IoRead, IoWrite};
pub use once_cell::sync::Lazy;
pub use tempdir::TempDir;
Expand Down
4 changes: 4 additions & 0 deletions mfio/src/backend/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,9 @@ pub trait IoBackend<Handle: Pollable = DefaultHandle> {
/// function does not return an `Option`, because such case usually indicates a bug in the
/// code.
fn get_backend(&self) -> BackendHandle<Self::Backend>;
}

pub trait IoBackendExt<Handle: Pollable>: IoBackend<Handle> {
/// Builds a composite future that also polls the backend future.
///
/// If second tuple element is not `None`, then the caller is responsible for registering and
Expand Down Expand Up @@ -389,6 +391,8 @@ pub trait IoBackend<Handle: Pollable = DefaultHandle> {
}
}

impl<T: ?Sized + IoBackend<Handle>, Handle: Pollable> IoBackendExt<Handle> for T {}

/// Represents types that contain an `IoBackend`.
pub trait LinksIoBackend {
type Link: IoBackend + ?Sized;
Expand Down
19 changes: 12 additions & 7 deletions mfio/src/io/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,8 @@ pub use opaque::*;
///
/// ```
/// use mfio::io::*;
/// use mfio::traits::*;
/// use mfio::mferr;
/// use mfio::traits::*;
///
/// enum Request {
/// Hi,
Expand Down Expand Up @@ -176,8 +176,8 @@ pub trait PacketIo<Perms: PacketPerms, Param>: Sized {
/// # include!("../sample.rs");
/// # }
/// # use sample::SampleIo;
/// use mfio::io::*;
/// use mfio::backend::*;
/// use mfio::io::*;
/// use mfio::mferr;
///
/// let handle = SampleIo::new(vec![0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144]);
Expand Down Expand Up @@ -285,14 +285,19 @@ impl NoPos {
}
}

pub struct IoFut<'a, T, Perms: PacketPerms, Param, Packet: PacketStore<'a, Perms>> {
pub struct IoFut<'a, T: ?Sized, Perms: PacketPerms, Param, Packet: PacketStore<'a, Perms>> {
pkt: UnsafeCell<Option<Packet::StackReq<'a>>>,
initial_state: UnsafeCell<Option<(&'a T, Param)>>,
_phantom: PhantomData<Perms>,
}

impl<'a, T: PacketIo<Perms, Param>, Perms: PacketPerms, Param, Pkt: PacketStore<'a, Perms>> Future
for IoFut<'a, T, Perms, Param, Pkt>
impl<
'a,
T: PacketIo<Perms, Param> + ?Sized,
Perms: PacketPerms,
Param,
Pkt: PacketStore<'a, Perms>,
> Future for IoFut<'a, T, Perms, Param, Pkt>
{
type Output = Pkt::StackReq<'a>;

Expand Down Expand Up @@ -333,7 +338,7 @@ impl<'a, T: PacketIo<Perms, Param>, Perms: PacketPerms, Param, Pkt: PacketStore<

pub struct IoToFut<
'a,
T,
T: ?Sized,
Perms: PacketPerms,
Param,
Packet: PacketStore<'a, Perms>,
Expand All @@ -346,7 +351,7 @@ pub struct IoToFut<

impl<
'a,
T: PacketIo<Perms, Param>,
T: PacketIo<Perms, Param> + ?Sized,
Perms: PacketPerms,
Param,
Pkt: PacketStore<'a, Perms>,
Expand Down
Loading

0 comments on commit 2941ce7

Please sign in to comment.