mirror of
https://github.com/tokio-rs/tokio.git
synced 2025-09-28 12:10:37 +00:00
signal: expose CtrlC stream on windows (#3186)
* Make tokio::signal::windows::ctrl_c() public. * Stop referring to private tokio::signal::windows::Event in module documentation. Closes #3178
This commit is contained in:
parent
5e406a7a47
commit
4912943419
@ -1,9 +1,9 @@
|
||||
//! Windows-specific types for signal handling.
|
||||
//!
|
||||
//! This module is only defined on Windows and contains the primary `Event` type
|
||||
//! for receiving notifications of events. These events are listened for via the
|
||||
//! This module is only defined on Windows and allows receiving "ctrl-c"
|
||||
//! and "ctrl-break" notifications. These events are listened for via the
|
||||
//! `SetConsoleCtrlHandler` function which receives events of the type
|
||||
//! `CTRL_C_EVENT` and `CTRL_BREAK_EVENT`
|
||||
//! `CTRL_C_EVENT` and `CTRL_BREAK_EVENT`.
|
||||
|
||||
#![cfg(windows)]
|
||||
|
||||
@ -79,10 +79,6 @@ pub(crate) struct Event {
|
||||
rx: Receiver<()>,
|
||||
}
|
||||
|
||||
pub(crate) fn ctrl_c() -> io::Result<Event> {
|
||||
Event::new(CTRL_C_EVENT)
|
||||
}
|
||||
|
||||
impl Event {
|
||||
fn new(signum: DWORD) -> io::Result<Self> {
|
||||
global_init()?;
|
||||
@ -135,6 +131,116 @@ unsafe extern "system" fn handler(ty: DWORD) -> BOOL {
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new stream which receives "ctrl-c" notifications sent to the
|
||||
/// process.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// use tokio::signal::windows::ctrl_c;
|
||||
///
|
||||
/// #[tokio::main]
|
||||
/// async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
/// // An infinite stream of CTRL-C events.
|
||||
/// let mut stream = ctrl_c()?;
|
||||
///
|
||||
/// // Print whenever a CTRL-C event is received.
|
||||
/// for countdown in (0..3).rev() {
|
||||
/// stream.recv().await;
|
||||
/// println!("got CTRL-C. {} more to exit", countdown);
|
||||
/// }
|
||||
///
|
||||
/// Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
pub fn ctrl_c() -> io::Result<CtrlC> {
|
||||
Event::new(CTRL_C_EVENT).map(|inner| CtrlC { inner })
|
||||
}
|
||||
|
||||
/// Represents a stream which receives "ctrl-c" notifications sent to the process
|
||||
/// via `SetConsoleCtrlHandler`.
|
||||
///
|
||||
/// A notification to this process notifies *all* streams listening for
|
||||
/// this event. Moreover, the notifications **are coalesced** if they aren't processed
|
||||
/// quickly enough. This means that if two notifications are received back-to-back,
|
||||
/// then the stream may only receive one item about the two notifications.
|
||||
#[must_use = "streams do nothing unless polled"]
|
||||
#[derive(Debug)]
|
||||
pub struct CtrlC {
|
||||
inner: Event,
|
||||
}
|
||||
|
||||
impl CtrlC {
|
||||
/// Receives the next signal notification event.
|
||||
///
|
||||
/// `None` is returned if no more events can be received by this stream.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// use tokio::signal::windows::ctrl_c;
|
||||
///
|
||||
/// #[tokio::main]
|
||||
/// async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
/// // An infinite stream of CTRL-C events.
|
||||
/// let mut stream = ctrl_c()?;
|
||||
///
|
||||
/// // Print whenever a CTRL-C event is received.
|
||||
/// for countdown in (0..3).rev() {
|
||||
/// stream.recv().await;
|
||||
/// println!("got CTRL-C. {} more to exit", countdown);
|
||||
/// }
|
||||
///
|
||||
/// Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
pub async fn recv(&mut self) -> Option<()> {
|
||||
self.inner.recv().await
|
||||
}
|
||||
|
||||
/// Polls to receive the next signal notification event, outside of an
|
||||
/// `async` context.
|
||||
///
|
||||
/// `None` is returned if no more events can be received by this stream.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Polling from a manually implemented future
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// use std::pin::Pin;
|
||||
/// use std::future::Future;
|
||||
/// use std::task::{Context, Poll};
|
||||
/// use tokio::signal::windows::CtrlC;
|
||||
///
|
||||
/// struct MyFuture {
|
||||
/// ctrl_c: CtrlC,
|
||||
/// }
|
||||
///
|
||||
/// impl Future for MyFuture {
|
||||
/// type Output = Option<()>;
|
||||
///
|
||||
/// fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
/// println!("polling MyFuture");
|
||||
/// self.ctrl_c.poll_recv(cx)
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
pub fn poll_recv(&mut self, cx: &mut Context<'_>) -> Poll<Option<()>> {
|
||||
self.inner.rx.poll_recv(cx)
|
||||
}
|
||||
}
|
||||
|
||||
cfg_stream! {
|
||||
impl crate::stream::Stream for CtrlC {
|
||||
type Item = ();
|
||||
|
||||
fn poll_next(mut self: std::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<()>> {
|
||||
self.poll_recv(cx)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a stream which receives "ctrl-break" notifications sent to the process
|
||||
/// via `SetConsoleCtrlHandler`.
|
||||
///
|
||||
@ -163,7 +269,7 @@ impl CtrlBreak {
|
||||
/// // An infinite stream of CTRL-BREAK events.
|
||||
/// let mut stream = ctrl_break()?;
|
||||
///
|
||||
/// // Print whenever a CTRL-BREAK event is received
|
||||
/// // Print whenever a CTRL-BREAK event is received.
|
||||
/// loop {
|
||||
/// stream.recv().await;
|
||||
/// println!("got signal CTRL-BREAK");
|
||||
@ -171,8 +277,7 @@ impl CtrlBreak {
|
||||
/// }
|
||||
/// ```
|
||||
pub async fn recv(&mut self) -> Option<()> {
|
||||
use crate::future::poll_fn;
|
||||
poll_fn(|cx| self.poll_recv(cx)).await
|
||||
self.inner.recv().await
|
||||
}
|
||||
|
||||
/// Polls to receive the next signal notification event, outside of an
|
||||
@ -231,7 +336,7 @@ cfg_stream! {
|
||||
/// // An infinite stream of CTRL-BREAK events.
|
||||
/// let mut stream = ctrl_break()?;
|
||||
///
|
||||
/// // Print whenever a CTRL-BREAK event is received
|
||||
/// // Print whenever a CTRL-BREAK event is received.
|
||||
/// loop {
|
||||
/// stream.recv().await;
|
||||
/// println!("got signal CTRL-BREAK");
|
||||
|
Loading…
x
Reference in New Issue
Block a user