From 804c76229b6a5bd6db7a9e568d1c090c69efc719 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20B=C3=BChler?= Date: Sun, 14 Nov 2021 20:04:18 +0100 Subject: [PATCH] Get rid of tokio/smol feature conflict in rtnetlink --- rtnetlink/src/ns.rs | 61 ++++++++++++++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 20 deletions(-) diff --git a/rtnetlink/src/ns.rs b/rtnetlink/src/ns.rs index 3ca6cc40..52bed9c4 100644 --- a/rtnetlink/src/ns.rs +++ b/rtnetlink/src/ns.rs @@ -1,9 +1,3 @@ -#[cfg(feature = "tokio_socket")] -use tokio::task; - -#[cfg(feature = "smol_socket")] -use async_std::task; - use crate::Error; use nix::{ fcntl::OFlag, @@ -16,6 +10,43 @@ use nix::{ }; use std::{option::Option, path::Path, process::exit}; +// if "only" smol or smol+tokio were enabled, we use smol because +// it doesn't require an active tokio runtime - just to be sure. +#[cfg(feature = "smol_socket")] +async fn try_spawn_blocking(fut: F) -> R +where + F: FnOnce() -> R + Send + 'static, + R: Send + 'static, +{ + async_std::task::spawn_blocking(fut).await +} + +// only tokio enabled, so use tokio +#[cfg(all(not(feature = "smol_socket"), feature = "tokio_socket"))] +async fn try_spawn_blocking(fut: F) -> R +where + F: FnOnce() -> R + Send + 'static, + R: Send + 'static, +{ + match tokio::task::spawn_blocking(fut).await { + Ok(v) => v, + Err(err) => { + std::panic::resume_unwind(err.into_panic()); + } + } +} + +// neither smol nor tokio - just run blocking op directly. +// hopefully not too blocking... +#[cfg(all(not(feature = "smol_socket"), not(feature = "tokio_socket")))] +async fn try_spawn_blocking(fut: F) -> R +where + F: FnOnce() -> R + Send + 'static, + R: Send + 'static, +{ + fut() +} + pub const NETNS_PATH: &str = "/run/netns/"; pub const SELF_NS_PATH: &str = "/proc/self/ns/net"; pub const NONE_FS: &str = "none"; @@ -46,7 +77,7 @@ impl NetworkNamespace { /// Remove a network namespace /// This is equivalent to `ip netns del NS_NAME`. pub async fn del(ns_name: String) -> Result<(), Error> { - let res = task::spawn_blocking(move || { + try_spawn_blocking(move || { let mut netns_path = String::new(); netns_path.push_str(NETNS_PATH); netns_path.push_str(&ns_name); @@ -62,20 +93,10 @@ impl NetworkNamespace { String::from("Namespace file remove failed (are you running as root?)"); return Err(Error::NamespaceError(err_msg)); } - #[cfg(feature = "tokio_socket")] - return Ok(()); - - #[cfg(feature = "smol_socket")] - return Ok(Ok(())); - }); - match res.await { - Ok(r) => r, - Err(e) => { - let err_msg = format!("Namespace removal failed: {}", e); - Err(Error::NamespaceError(err_msg)) - } - } + Ok(()) + }) + .await } pub fn prep_for_fork() -> Result<(), Error> {