Rename reactor -> driver, prep for lib/reactivity

This commit is contained in:
2026-03-19 19:47:06 -04:00
parent 3fd8209420
commit 7b3c2fcbef
13 changed files with 490 additions and 62 deletions

View File

@@ -1,3 +1,5 @@
//! Multi-producer, single-consumer channels.
use std::collections::VecDeque;
use std::future::poll_fn;
use std::pin::Pin;
@@ -7,6 +9,13 @@ use std::task::{Context, Poll};
use crate::op::completion::{CompletionFuture, CompletionHandle};
use crate::sys::linux::channel::runtime_waiter;
/// Creates a bounded channel with room for at most `capacity` queued messages.
///
/// Bounded senders provide both [`Sender::try_send`] and async [`Sender::send`] backpressure.
///
/// # Panics
///
/// Panics if `capacity == 0`.
pub fn channel<T: Send + 'static>(capacity: usize) -> (Sender<T>, Receiver<T>) {
assert!(capacity > 0, "bounded channels require capacity > 0");
let shared = Arc::new(Mutex::new(State::new(Some(capacity))));
@@ -18,6 +27,9 @@ pub fn channel<T: Send + 'static>(capacity: usize) -> (Sender<T>, Receiver<T>) {
)
}
/// Creates an unbounded channel.
///
/// Unbounded senders never wait for capacity, but the single receiver is still asynchronous.
pub fn unbounded_channel<T: Send + 'static>() -> (UnboundedSender<T>, Receiver<T>) {
let shared = Arc::new(Mutex::new(State::new(None)));
(
@@ -28,14 +40,17 @@ pub fn unbounded_channel<T: Send + 'static>() -> (UnboundedSender<T>, Receiver<T
)
}
/// Bounded multi-producer sender.
pub struct Sender<T: Send + 'static> {
shared: Arc<Mutex<State<T>>>,
}
/// Unbounded multi-producer sender.
pub struct UnboundedSender<T: Send + 'static> {
shared: Arc<Mutex<State<T>>>,
}
/// Single consumer for both bounded and unbounded MPSC channels.
pub struct Receiver<T: Send + 'static> {
shared: Arc<Mutex<State<T>>>,
}
@@ -57,17 +72,24 @@ struct SendWaiter<T: Send + 'static> {
}
#[derive(Debug, Eq, PartialEq)]
/// Error returned when sending fails because the receiver has been closed or dropped.
pub struct SendError<T>(pub T);
#[derive(Debug, Eq, PartialEq)]
/// Error returned by [`Sender::try_send`] when a message cannot be queued immediately.
pub enum TrySendError<T> {
/// The bounded queue is currently full.
Full(T),
/// The receiver has been closed or dropped.
Closed(T),
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
/// Error returned by [`Receiver::try_recv`] when no message is available immediately.
pub enum TryRecvError {
/// The channel is still open, but currently empty.
Empty,
/// The channel is closed and no more messages can arrive.
Disconnected,
}
@@ -215,12 +237,20 @@ impl<T: Send + 'static> Clone for UnboundedSender<T> {
}
impl<T: Send + 'static> Sender<T> {
/// Waits until the message can be queued.
///
/// When the bounded channel is full, this future waits until the receiver frees capacity.
///
/// # Panics
///
/// Panics if this future is first polled outside a runtime-managed thread.
pub async fn send(&self, value: T) -> Result<(), SendError<T>> {
let mut value = Some(value);
let mut wait = None;
poll_fn(|cx| self.poll_send(cx, &mut value, &mut wait)).await
}
/// Attempts to queue a message immediately.
pub fn try_send(&self, value: T) -> Result<(), TrySendError<T>> {
self.shared
.lock()
@@ -228,6 +258,7 @@ impl<T: Send + 'static> Sender<T> {
.try_send_now(value)
}
/// Returns `true` if the receiver has been closed or dropped.
pub fn is_closed(&self) -> bool {
self.shared
.lock()
@@ -306,6 +337,7 @@ impl<T: Send + 'static> Sender<T> {
}
impl<T: Send + 'static> UnboundedSender<T> {
/// Queues a message immediately.
pub fn send(&self, value: T) -> Result<(), SendError<T>> {
self.shared
.lock()
@@ -316,6 +348,7 @@ impl<T: Send + 'static> UnboundedSender<T> {
})
}
/// Returns `true` if the receiver has been closed or dropped.
pub fn is_closed(&self) -> bool {
self.shared
.lock()
@@ -325,11 +358,19 @@ impl<T: Send + 'static> UnboundedSender<T> {
}
impl<T: Send + 'static> Receiver<T> {
/// Waits for the next message.
///
/// Returns `None` when the channel is closed and all buffered messages have been drained.
///
/// # Panics
///
/// Panics if this future is first polled outside a runtime-managed thread.
pub async fn recv(&mut self) -> Option<T> {
let mut wait = None;
poll_fn(|cx| self.poll_recv(cx, &mut wait)).await
}
/// Attempts to receive a message immediately.
pub fn try_recv(&mut self) -> Result<T, TryRecvError> {
let mut state = self
.shared
@@ -345,6 +386,10 @@ impl<T: Send + 'static> Receiver<T> {
}
}
/// Closes the channel to future sends.
///
/// Already-buffered messages remain available to [`recv`](Self::recv) and
/// [`try_recv`](Self::try_recv).
pub fn close(&mut self) {
self.shared
.lock()
@@ -352,6 +397,7 @@ impl<T: Send + 'static> Receiver<T> {
.close_receiver();
}
/// Returns `true` if the channel is closed or all senders have been dropped.
pub fn is_closed(&self) -> bool {
let state = self
.shared