wip: starter and reaper works
This commit is contained in:
parent
6ba6bc6cda
commit
ce9df6364f
@ -6,5 +6,5 @@ edition = "2021"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nix = {version = "0.27.1", features = ["process"]}
|
nix = {version = "0.27.1", features = ["process", "signal"]}
|
||||||
tokio = { version = "1.34.0", features = ["full"] }
|
tokio = { version = "1.34.0", features = ["full"] }
|
||||||
|
|||||||
@ -1,19 +1,42 @@
|
|||||||
mod sighandler;
|
mod sighandler;
|
||||||
mod waiter;
|
mod waiter;
|
||||||
|
mod starter;
|
||||||
|
|
||||||
use std::error;
|
use std::error;
|
||||||
use tokio::task::{self, JoinHandle};
|
use tokio::task::JoinSet;
|
||||||
use tokio::sync::watch;
|
use tokio::sync::watch;
|
||||||
|
|
||||||
pub async fn start() -> Result<(), Box<dyn error::Error>> {
|
pub async fn start() -> Result<(), Box<dyn error::Error>> {
|
||||||
let (tx, mut _rx) = watch::channel::<i32>(1);
|
let (tx, mut _rx) = watch::channel::<i32>(1);
|
||||||
|
|
||||||
let sig_handler_fn: JoinHandle<Result<(), Box<dyn error::Error + Send + Sync>>> = task::spawn(async move {
|
let mut set: JoinSet<Result<(), Box<dyn error::Error + Send + Sync>>> = JoinSet::new();
|
||||||
|
set.spawn(async move {
|
||||||
sighandler::sighandler(tx).await
|
sighandler::sighandler(tx).await
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Err(v) = sig_handler_fn.await? {
|
//TODO: start the process starter
|
||||||
return Err(v as Box<dyn error::Error>)
|
starter::start_process(&mut set);
|
||||||
|
|
||||||
|
//TODO: spawn_blocking for waiter
|
||||||
|
set.spawn_blocking(move || {
|
||||||
|
waiter::wait_all();
|
||||||
|
Ok(())
|
||||||
|
});
|
||||||
|
|
||||||
|
//TODO: we can't just return error when we got an error from a task
|
||||||
|
while let Some(res) = set.join_next().await {
|
||||||
|
match res {
|
||||||
|
Ok(v) => {
|
||||||
|
if let Err(ev) = v {
|
||||||
|
dbg!(&ev);
|
||||||
|
return Err(ev as Box<dyn error::Error>);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(e) => {
|
||||||
|
dbg!(&e);
|
||||||
|
return Err(e.into());
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
36
src/init/daemon/starter.rs
Normal file
36
src/init/daemon/starter.rs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
use tokio::task::JoinSet;
|
||||||
|
use tokio::process::Command;
|
||||||
|
use std::error;
|
||||||
|
|
||||||
|
pub fn start_process(ts: &mut JoinSet<Result<(), Box<dyn error::Error + Send + Sync>>>) {
|
||||||
|
for _j in 0..5 {
|
||||||
|
ts.spawn(async move {
|
||||||
|
for _i in 0..5 {
|
||||||
|
let mut child = Command::new("sleep").arg("1")
|
||||||
|
.spawn()
|
||||||
|
.expect("failed to spawn");
|
||||||
|
|
||||||
|
match child.wait().await {
|
||||||
|
Ok(status) => {
|
||||||
|
println!("starter: sleep exited: {}", status);
|
||||||
|
},
|
||||||
|
Err(e) => {
|
||||||
|
if let Some(eos) = e.raw_os_error() {
|
||||||
|
if eos != nix::Error::ECHILD as i32 {
|
||||||
|
return Err(e.into());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Err(e.into());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
// let status = child.wait().await?;
|
||||||
|
// println!("starter: sleep exited: {}", status);
|
||||||
|
}
|
||||||
|
println!("starter: task completed");
|
||||||
|
Ok(())
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
println!("starter: spawning completed");
|
||||||
|
}
|
||||||
@ -1,10 +1,33 @@
|
|||||||
use nix::sys::wait;
|
use nix::errno::Errno;
|
||||||
|
use nix::sys::wait::{self, WaitStatus};
|
||||||
use nix::unistd::Pid;
|
use nix::unistd::Pid;
|
||||||
|
|
||||||
#[allow(dead_code)]
|
pub fn wait_all() {
|
||||||
fn wait_all() {
|
'wait: loop {
|
||||||
match wait::waitpid(Pid::from_raw(-1), Some(wait::WaitPidFlag::WNOHANG)) {
|
match wait::waitpid(Pid::from_raw(-1), None) {
|
||||||
Ok(_x) => {},
|
Ok(x) => {
|
||||||
Err(_err) => {},
|
// dbg!(x);
|
||||||
|
match x {
|
||||||
|
WaitStatus::Exited(pid, v) => {
|
||||||
|
println!("wait_all: pid {}: exited with status {}", pid, v);
|
||||||
|
},
|
||||||
|
WaitStatus::Signaled(pid, sig, _dumped) => {
|
||||||
|
println!("wait_all: pid {} killed with signal {}", pid, sig);
|
||||||
|
},
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(err) => {
|
||||||
|
dbg!(err);
|
||||||
|
match err {
|
||||||
|
Errno::ECHILD => {
|
||||||
|
break 'wait;
|
||||||
|
},
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
// dbg!("sanity");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user