signal: guarantee that listeners never return None (#7869)

This commit is contained in:
Tim Vilgot Mikael Fredenberg
2026-01-29 19:24:47 -08:00
committed by GitHub
parent b68ea4156a
commit c3b31ba2ab
3 changed files with 47 additions and 39 deletions
+5 -9
View File
@@ -83,18 +83,14 @@ impl RxFuture {
}
}
async fn recv(&mut self) -> Option<()> {
async fn recv(&mut self) {
use std::future::poll_fn;
poll_fn(|cx| self.poll_recv(cx)).await
}
fn poll_recv(&mut self, cx: &mut Context<'_>) -> Poll<Option<()>> {
match self.inner.poll(cx) {
Poll::Pending => Poll::Pending,
Poll::Ready(rx) => {
self.inner.set(make_future(rx));
Poll::Ready(Some(()))
}
}
fn poll_recv(&mut self, cx: &mut Context<'_>) -> Poll<()> {
self.inner
.poll(cx)
.map(|rx| self.inner.set(make_future(rx)))
}
}
+7 -10
View File
@@ -421,7 +421,8 @@ pub(crate) fn signal_with_handle(
impl Signal {
/// Receives the next signal notification event.
///
/// `None` is returned if no more events can be received by this stream.
/// Although this returns `Option<()>`, it will never actually return `None`.
/// This was accidentally exposed and would be a breaking change to be removed.
///
/// # Cancel safety
///
@@ -449,19 +450,15 @@ impl Signal {
/// }
/// ```
pub async fn recv(&mut self) -> Option<()> {
self.inner.recv().await
self.inner.recv().await;
Some(())
}
/// Polls to receive the next signal notification event, outside of an
/// `async` context.
///
/// This method returns:
///
/// * `Poll::Pending` if no signals are available but the channel is not
/// closed.
/// * `Poll::Ready(Some(()))` if a signal is available.
/// * `Poll::Ready(None)` if the channel has been closed and all signals
/// sent before it was closed have been received.
/// Although this returns `Option<()>`, it will never actually return `None`.
/// This was accidentally exposed and would be a breaking change to be removed.
///
/// # Examples
///
@@ -487,7 +484,7 @@ impl Signal {
/// }
/// ```
pub fn poll_recv(&mut self, cx: &mut Context<'_>) -> Poll<Option<()>> {
self.inner.poll_recv(cx)
self.inner.poll_recv(cx).map(Some)
}
}
+35 -20
View File
@@ -72,7 +72,8 @@ pub struct CtrlC {
impl CtrlC {
/// Receives the next signal notification event.
///
/// `None` is returned if no more events can be received by the listener.
/// Although this returns `Option<()>`, it will never actually return `None`.
/// This was accidentally exposed and would be a breaking change to be removed.
///
/// # Examples
///
@@ -93,13 +94,15 @@ impl CtrlC {
/// }
/// ```
pub async fn recv(&mut self) -> Option<()> {
self.inner.recv().await
self.inner.recv().await;
Some(())
}
/// Polls to receive the next signal notification event, outside of an
/// `async` context.
///
/// `None` is returned if no more events can be received.
/// Although this returns `Option<()>`, it will never actually return `None`.
/// This was accidentally exposed and would be a breaking change to be removed.
///
/// # Examples
///
@@ -125,7 +128,7 @@ impl CtrlC {
/// }
/// ```
pub fn poll_recv(&mut self, cx: &mut Context<'_>) -> Poll<Option<()>> {
self.inner.poll_recv(cx)
self.inner.poll_recv(cx).map(Some)
}
}
@@ -149,7 +152,8 @@ pub struct CtrlBreak {
impl CtrlBreak {
/// Receives the next signal notification event.
///
/// `None` is returned if no more events can be received by this listener.
/// Although this returns `Option<()>`, it will never actually return `None`.
/// This was accidentally exposed and would be a breaking change to be removed.
///
/// # Examples
///
@@ -169,13 +173,15 @@ impl CtrlBreak {
/// }
/// ```
pub async fn recv(&mut self) -> Option<()> {
self.inner.recv().await
self.inner.recv().await;
Some(())
}
/// 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 listener.
/// Although this returns `Option<()>`, it will never actually return `None`.
/// This was accidentally exposed and would be a breaking change to be removed.
///
/// # Examples
///
@@ -201,7 +207,7 @@ impl CtrlBreak {
/// }
/// ```
pub fn poll_recv(&mut self, cx: &mut Context<'_>) -> Poll<Option<()>> {
self.inner.poll_recv(cx)
self.inner.poll_recv(cx).map(Some)
}
}
@@ -275,7 +281,8 @@ pub struct CtrlClose {
impl CtrlClose {
/// Receives the next signal notification event.
///
/// `None` is returned if no more events can be received by this listener.
/// Although this returns `Option<()>`, it will never actually return `None`.
/// This was accidentally exposed and would be a breaking change to be removed.
///
/// # Examples
///
@@ -295,13 +302,15 @@ impl CtrlClose {
/// }
/// ```
pub async fn recv(&mut self) -> Option<()> {
self.inner.recv().await
self.inner.recv().await;
Some(())
}
/// 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 listener.
/// Although this returns `Option<()>`, it will never actually return `None`.
/// This was accidentally exposed and would be a breaking change to be removed.
///
/// # Examples
///
@@ -327,7 +336,7 @@ impl CtrlClose {
/// }
/// ```
pub fn poll_recv(&mut self, cx: &mut Context<'_>) -> Poll<Option<()>> {
self.inner.poll_recv(cx)
self.inner.poll_recv(cx).map(Some)
}
}
@@ -372,7 +381,8 @@ pub struct CtrlShutdown {
impl CtrlShutdown {
/// Receives the next signal notification event.
///
/// `None` is returned if no more events can be received by this listener.
/// Although this returns `Option<()>`, it will never actually return `None`.
/// This was accidentally exposed and would be a breaking change to be removed.
///
/// # Examples
///
@@ -392,13 +402,15 @@ impl CtrlShutdown {
/// }
/// ```
pub async fn recv(&mut self) -> Option<()> {
self.inner.recv().await
self.inner.recv().await;
Some(())
}
/// 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 listener.
/// Although this returns `Option<()>`, it will never actually return `None`.
/// This was accidentally exposed and would be a breaking change to be removed.
///
/// # Examples
///
@@ -424,7 +436,7 @@ impl CtrlShutdown {
/// }
/// ```
pub fn poll_recv(&mut self, cx: &mut Context<'_>) -> Poll<Option<()>> {
self.inner.poll_recv(cx)
self.inner.poll_recv(cx).map(Some)
}
}
@@ -469,7 +481,8 @@ pub struct CtrlLogoff {
impl CtrlLogoff {
/// Receives the next signal notification event.
///
/// `None` is returned if no more events can be received by this listener.
/// Although this returns `Option<()>`, it will never actually return `None`.
/// This was accidentally exposed and would be a breaking change to be removed.
///
/// # Examples
///
@@ -489,13 +502,15 @@ impl CtrlLogoff {
/// }
/// ```
pub async fn recv(&mut self) -> Option<()> {
self.inner.recv().await
self.inner.recv().await;
Some(())
}
/// 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 listener.
/// Although this returns `Option<()>`, it will never actually return `None`.
/// This was accidentally exposed and would be a breaking change to be removed.
///
/// # Examples
///
@@ -521,6 +536,6 @@ impl CtrlLogoff {
/// }
/// ```
pub fn poll_recv(&mut self, cx: &mut Context<'_>) -> Poll<Option<()>> {
self.inner.poll_recv(cx)
self.inner.poll_recv(cx).map(Some)
}
}