Skip to content

Commit

Permalink
feat: impl spawn_catch_unwind()
Browse files Browse the repository at this point in the history
  • Loading branch information
SteveLauC committed Nov 2, 2024
1 parent 90c9c3e commit 1674877
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 5 deletions.
2 changes: 1 addition & 1 deletion monoio/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ libc = "0.2"
pin-project-lite = "0.2"
socket2 = { version = "0.5", features = ["all"] }
memchr = "2.7"
futures = "0.3"

bytes = { version = "1", optional = true }
flume = { version = "0.11", optional = true }
Expand Down Expand Up @@ -55,7 +56,6 @@ nix = { version = "0.26", optional = true }
io-uring = { version = "0.6", optional = true }

[dev-dependencies]
futures = "0.3"
local-sync = "0.0.5"
tempfile = "3.2"

Expand Down
2 changes: 1 addition & 1 deletion monoio/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ pub use driver::IoUringDriver;
pub use driver::LegacyDriver;
#[cfg(feature = "macros")]
pub use monoio_macros::{main, test, test_all};
pub use runtime::{spawn, Runtime};
pub use runtime::{spawn, spawn_catch_unwind, Runtime};
#[cfg(any(all(target_os = "linux", feature = "iouring"), feature = "legacy"))]
pub use {builder::FusionDriver, runtime::FusionRuntime};

Expand Down
37 changes: 34 additions & 3 deletions monoio/src/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -351,9 +351,6 @@ impl From<Runtime<TimeDriver<IoUringDriver>>> for FusionRuntime<TimeDriver<IoUri
///
/// # Examples
///
/// In this example, a server is started and `spawn` is used to start a new task
/// that processes each received connection.
///
/// ```no_run
/// #[monoio::main]
/// async fn main() {
Expand Down Expand Up @@ -382,6 +379,40 @@ where
join
}

/// Similar to [`spawn()`], but it catches any panic that occurs in the spawned task.
///
/// Note that `.await`ing returned `JoinHandle` now returns a `Result<T::Output>`
/// rather than `T::Output`.
///
/// # Examples
///
/// ```no_run
/// #[monoio::main]
/// async fn main() {
/// let handle = monoio::spawn(async {
/// println!("hello from a background task");
/// });
///
/// // Let the task complete
/// handle.await.expect("no panic would happen!");
/// }
/// ```
pub fn spawn_catch_unwind<T>(
future: T,
) -> JoinHandle<Result<T::Output, Box<dyn std::any::Any + 'static>>>
where
T: Future + 'static,
T::Output: 'static,
{
use futures::{FutureExt, TryFutureExt};

let future = std::panic::AssertUnwindSafe(future)
.catch_unwind()
.map_err(|e| e as Box<dyn std::any::Any + 'static>);

spawn(future)
}

#[cfg(feature = "sync")]
unsafe fn spawn_without_static<T>(future: T) -> JoinHandle<T::Output>
where
Expand Down

0 comments on commit 1674877

Please sign in to comment.