Add smol implementation for spawn
Although this is used in apps that use `tokio`, if we're going to support `smol`, this seems suboptimal to require. This assumes the function will be called by a tokio executor if the `tokio` feature is used. Otherwise it can be spawned from any executor. That should be consistent with everything else. This fails to compile without either the `tokio` or `smol` feature. This seems reasonable, since `zbus` also fails to compile in that case.
This commit is contained in:
parent
8c00bf3d8b
commit
732c7aef5c
2 changed files with 23 additions and 6 deletions
|
|
@ -33,7 +33,6 @@ desktop = [
|
|||
"dep:freedesktop-desktop-entry",
|
||||
"dep:mime",
|
||||
"dep:shlex",
|
||||
"dep:tokio",
|
||||
"dep:textdistance",
|
||||
"dep:zbus",
|
||||
]
|
||||
|
|
@ -42,7 +41,7 @@ serde-keycode = ["iced_core/serde"]
|
|||
# Prevents multiple separate process instances.
|
||||
single-instance = ["dep:zbus", "ron"]
|
||||
# smol async runtime
|
||||
smol = ["iced/smol", "zbus?/async-io"]
|
||||
smol = ["dep:smol", "iced/smol", "zbus?/async-io"]
|
||||
tokio = [
|
||||
"dep:tokio",
|
||||
"ashpd?/tokio",
|
||||
|
|
@ -92,13 +91,14 @@ rfd = { version = "0.14.0", optional = true }
|
|||
rustix = { version = "0.38.34", features = ["pipe", "process"], optional = true }
|
||||
serde = { version = "1.0.180", features = ["derive"] }
|
||||
slotmap = "1.0.6"
|
||||
smol = { version = "2.0.0", optional = true }
|
||||
textdistance = { version = "1.0.2", optional = true }
|
||||
thiserror = "1.0.44"
|
||||
tokio = { version = "1.24.2", optional = true }
|
||||
tracing = "0.1"
|
||||
unicode-segmentation = "1.6"
|
||||
url = "2.4.0"
|
||||
zbus = { version = "4.2.1", default-features = false, features = ["tokio"], optional = true }
|
||||
zbus = { version = "4.2.1", default-features = false, optional = true }
|
||||
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
freedesktop-icons = "0.2.5"
|
||||
|
|
|
|||
|
|
@ -1,8 +1,26 @@
|
|||
#[cfg(all(feature = "smol", not(feature = "tokio")))]
|
||||
use smol::io::AsyncReadExt;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
use std::os::fd::OwnedFd;
|
||||
use std::process::{exit, Command, Stdio};
|
||||
#[cfg(feature = "tokio")]
|
||||
use tokio::io::AsyncReadExt;
|
||||
|
||||
#[cfg(feature = "tokio")]
|
||||
async fn read_from_pipe(read: OwnedFd) -> Option<u32> {
|
||||
let mut read = tokio::net::unix::pipe::Receiver::from_owned_fd(read).unwrap();
|
||||
read.read_u32().await.ok()
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "smol", not(feature = "tokio")))]
|
||||
async fn read_from_pipe(read: OwnedFd) -> Option<u32> {
|
||||
let mut read = smol::Async::new(std::fs::File::from(read)).unwrap();
|
||||
let mut bytes = [0; 4];
|
||||
read.read_exact(&mut bytes).await.ok()?;
|
||||
Some(u32::from_be_bytes(bytes))
|
||||
}
|
||||
|
||||
/// Performs a double fork with setsid to spawn and detach a command.
|
||||
pub async fn spawn(mut command: Command) -> Option<u32> {
|
||||
command
|
||||
|
|
@ -17,10 +35,9 @@ pub async fn spawn(mut command: Command) -> Option<u32> {
|
|||
match unsafe { libc::fork() } {
|
||||
// Parent process
|
||||
1.. => {
|
||||
// Drop copy of write end, then read PID from pipe
|
||||
drop(write);
|
||||
// Read PID from pipe
|
||||
let mut read = tokio::net::unix::pipe::Receiver::from_owned_fd(read).unwrap();
|
||||
read.read_u32().await.ok()
|
||||
read_from_pipe(read).await
|
||||
}
|
||||
|
||||
// Child process
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue