Skip to content

Instantly share code, notes, and snippets.

@ssrlive
Last active May 4, 2023 04:29
Show Gist options
  • Save ssrlive/f13643855dc31c8c95c5be9474ae5918 to your computer and use it in GitHub Desktop.
Save ssrlive/f13643855dc31c8c95c5be9474ae5918 to your computer and use it in GitHub Desktop.
Guard a thread and restart it when it exits unexpectedly.
use std::sync::atomic::{AtomicBool, Ordering};
use tokio::{
signal::ctrl_c,
sync::mpsc::{channel, Sender},
task::spawn,
};
static STOP_FLAG: AtomicBool = AtomicBool::new(false);
// worker function to be executed in a separate thread
async fn worker(tx: Sender<()>) {
let mut count = 0;
loop {
if STOP_FLAG.load(Ordering::Relaxed) {
println!("Worker exiting for STOP_FLAG");
break;
}
println!("Worker running");
tokio::time::sleep(tokio::time::Duration::from_secs(5)).await;
count += 1;
// check if the thread should exit
if count == 3 {
println!("Worker exiting unexpectedly");
break;
}
}
// send a message back to the main thread to indicate that this thread has exited
let _ = tx.send(());
println!("Worker exiting done");
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
tokio::spawn(async move {
ctrl_c().await.unwrap();
println!("Received CTRL-C signal");
STOP_FLAG.store(true, Ordering::Relaxed);
});
loop {
// check if the stop flag has been set
if STOP_FLAG.load(Ordering::Relaxed) {
println!("main loop exiting for STOP_FLAG");
break;
}
println!("loop begin");
let (tx, mut rx) = channel::<()>(100);
// spawn the initial worker thread
let _ = spawn(worker(tx)).await?;
let _ = rx.recv().await;
println!("rx.recv().await");
}
Ok(())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment