//TODO: The API for spawning the `signal_hook` thread & returning a `CrosslinkReceiver` that it notifies on `SIGWINCH`s (with its join-handle) (that will break out of the loop and cleanly exit the thread if there are no receivers left.)
/// Spawn a background thread to intercept specified `signals` to this process.
///
/// When any of the specified signals are intercepted, a notification is sent to the returned [CrosslinkReceiver], which can be waited on in an async context.
///
/// # Closing
/// The background thread can be explicitly communicated with through `Handle`, but will automatically close if a signal arrives *after* the returned receiver has been dropped.
/// However, as the dropping of the receiver will not auto-shutdown the background thread *until* another signal comes in and it notices it cannot send the notification, it is desireable that one of the explicit `close()` methods on `Handle` be registered to be called when either the receiver becomes unavailable to the caller's task-set or the task is over.
///
/// Dropping the handle will not communicate a close, and since the lifetimes of the receiver and handle are seperated, they do not automatically interface with eachother.
returnErr(io::Error::new(io::ErrorKind::NotFound,format!("Signal {:?} was not found in the original signal list {:?}",sig,signals.iter().copied().collect::<Box<[_]>>())));
@ -144,10 +144,46 @@ where I: IntoIterator<Item=T>,
}
};
// To close the backing handle and un-hook the signals: `close_resize_handle().await.expect("Failed to close reactive handle")`
// NOTE: This must be called *before* shutting down the progress-bar.
#[cfg(feature="progress-reactive")]
let_size_handle={
letclose_resize_handle={
letmutprogress=progress.clone();
todo!("progress-reactive: Spawn the `signal_hooks` thread and set up the Tokio `CondVar` to wait on in a background task, sending `Resize{{to: None}} to `progress` when an event comes in.");
Ok(_)=>(),// NOTE: Do not wait for the resize to complete before checking if we may need to do so again.
Err(e)ife.can_ignore_on_com_send_failure()=>{
// The progress-bar has been requested to shut down, we should end the task here.
// _on_exit.now();
return;
},
Err(e)=>{
let_=progress.eprintln(format!("[{}] {}: Failed to resize progress-bar: {:?}",colour::style(colour!(Color::BrightRed),"!"),colour::style(colour!(Color::BrightWhite),"Error"),e)).await;
}
}
}
});
usestd::io;
asyncmove||-> io::Result<()>{
ifhandle.close()?==false{
returnErr(io::Error::new(io::ErrorKind::BrokenPipe,"The `resize_handle` task has already exited before it was requested to (BUG: This is not a problem, but means the resize-handle has not been closed in the right order in the bringdown code.)"));
}
rx.await?;
Ok(())
}
};
letdisplay={
@ -299,6 +335,11 @@ where I: IntoIterator<Item=T>,
let_=progress.eprintln(format!("[{}] Warning! Failed to close progress-reactive resize handle: {:?}",colour::style(colour!(Color::Yellow),"!"),e)).await;