mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-08-24 00:00:11 +02:00
sync: name mpsc semaphore types (#5146)
Make code easier to read. No functional/perf changes.
This commit is contained in:
@@ -143,7 +143,10 @@ pub struct Receiver<T> {
|
||||
#[track_caller]
|
||||
pub fn channel<T>(buffer: usize) -> (Sender<T>, Receiver<T>) {
|
||||
assert!(buffer > 0, "mpsc bounded channel requires buffer > 0");
|
||||
let semaphore = (semaphore::Semaphore::new(buffer), buffer);
|
||||
let semaphore = Semaphore {
|
||||
semaphore: semaphore::Semaphore::new(buffer),
|
||||
bound: buffer,
|
||||
};
|
||||
let (tx, rx) = chan::channel(semaphore);
|
||||
|
||||
let tx = Sender::new(tx);
|
||||
@@ -154,7 +157,11 @@ pub fn channel<T>(buffer: usize) -> (Sender<T>, Receiver<T>) {
|
||||
|
||||
/// Channel semaphore is a tuple of the semaphore implementation and a `usize`
|
||||
/// representing the channel bound.
|
||||
type Semaphore = (semaphore::Semaphore, usize);
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct Semaphore {
|
||||
pub(crate) semaphore: semaphore::Semaphore,
|
||||
pub(crate) bound: usize,
|
||||
}
|
||||
|
||||
impl<T> Receiver<T> {
|
||||
pub(crate) fn new(chan: chan::Rx<T, Semaphore>) -> Receiver<T> {
|
||||
@@ -572,7 +579,7 @@ impl<T> Sender<T> {
|
||||
/// }
|
||||
/// ```
|
||||
pub fn try_send(&self, message: T) -> Result<(), TrySendError<T>> {
|
||||
match self.chan.semaphore().0.try_acquire(1) {
|
||||
match self.chan.semaphore().semaphore.try_acquire(1) {
|
||||
Ok(_) => {}
|
||||
Err(TryAcquireError::Closed) => return Err(TrySendError::Closed(message)),
|
||||
Err(TryAcquireError::NoPermits) => return Err(TrySendError::Full(message)),
|
||||
@@ -852,7 +859,7 @@ impl<T> Sender<T> {
|
||||
}
|
||||
|
||||
async fn reserve_inner(&self) -> Result<(), SendError<()>> {
|
||||
match self.chan.semaphore().0.acquire(1).await {
|
||||
match self.chan.semaphore().semaphore.acquire(1).await {
|
||||
Ok(_) => Ok(()),
|
||||
Err(_) => Err(SendError(())),
|
||||
}
|
||||
@@ -902,7 +909,7 @@ impl<T> Sender<T> {
|
||||
/// }
|
||||
/// ```
|
||||
pub fn try_reserve(&self) -> Result<Permit<'_, T>, TrySendError<()>> {
|
||||
match self.chan.semaphore().0.try_acquire(1) {
|
||||
match self.chan.semaphore().semaphore.try_acquire(1) {
|
||||
Ok(_) => {}
|
||||
Err(TryAcquireError::Closed) => return Err(TrySendError::Closed(())),
|
||||
Err(TryAcquireError::NoPermits) => return Err(TrySendError::Full(())),
|
||||
@@ -967,7 +974,7 @@ impl<T> Sender<T> {
|
||||
/// }
|
||||
/// ```
|
||||
pub fn try_reserve_owned(self) -> Result<OwnedPermit<T>, TrySendError<Self>> {
|
||||
match self.chan.semaphore().0.try_acquire(1) {
|
||||
match self.chan.semaphore().semaphore.try_acquire(1) {
|
||||
Ok(_) => {}
|
||||
Err(TryAcquireError::Closed) => return Err(TrySendError::Closed(self)),
|
||||
Err(TryAcquireError::NoPermits) => return Err(TrySendError::Full(self)),
|
||||
@@ -1028,7 +1035,7 @@ impl<T> Sender<T> {
|
||||
/// [`channel`]: channel
|
||||
/// [`max_capacity`]: Sender::max_capacity
|
||||
pub fn capacity(&self) -> usize {
|
||||
self.chan.semaphore().0.available_permits()
|
||||
self.chan.semaphore().semaphore.available_permits()
|
||||
}
|
||||
|
||||
/// Converts the `Sender` to a [`WeakSender`] that does not count
|
||||
@@ -1074,7 +1081,7 @@ impl<T> Sender<T> {
|
||||
/// [`max_capacity`]: Sender::max_capacity
|
||||
/// [`capacity`]: Sender::capacity
|
||||
pub fn max_capacity(&self) -> usize {
|
||||
self.chan.semaphore().1
|
||||
self.chan.semaphore().bound
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+11
-12
@@ -4,7 +4,7 @@ use crate::loom::sync::atomic::AtomicUsize;
|
||||
use crate::loom::sync::Arc;
|
||||
use crate::park::thread::CachedParkThread;
|
||||
use crate::sync::mpsc::error::TryRecvError;
|
||||
use crate::sync::mpsc::list;
|
||||
use crate::sync::mpsc::{bounded, list, unbounded};
|
||||
use crate::sync::notify::Notify;
|
||||
|
||||
use std::fmt;
|
||||
@@ -12,7 +12,6 @@ use std::process;
|
||||
use std::sync::atomic::Ordering::{AcqRel, Acquire, Relaxed, Release};
|
||||
use std::task::Poll::{Pending, Ready};
|
||||
use std::task::{Context, Poll};
|
||||
use std::usize;
|
||||
|
||||
/// Channel sender.
|
||||
pub(crate) struct Tx<T, S> {
|
||||
@@ -382,29 +381,29 @@ impl<T, S> Drop for Chan<T, S> {
|
||||
|
||||
// ===== impl Semaphore for (::Semaphore, capacity) =====
|
||||
|
||||
impl Semaphore for (crate::sync::batch_semaphore::Semaphore, usize) {
|
||||
impl Semaphore for bounded::Semaphore {
|
||||
fn add_permit(&self) {
|
||||
self.0.release(1)
|
||||
self.semaphore.release(1)
|
||||
}
|
||||
|
||||
fn is_idle(&self) -> bool {
|
||||
self.0.available_permits() == self.1
|
||||
self.semaphore.available_permits() == self.bound
|
||||
}
|
||||
|
||||
fn close(&self) {
|
||||
self.0.close();
|
||||
self.semaphore.close();
|
||||
}
|
||||
|
||||
fn is_closed(&self) -> bool {
|
||||
self.0.is_closed()
|
||||
self.semaphore.is_closed()
|
||||
}
|
||||
}
|
||||
|
||||
// ===== impl Semaphore for AtomicUsize =====
|
||||
|
||||
impl Semaphore for AtomicUsize {
|
||||
impl Semaphore for unbounded::Semaphore {
|
||||
fn add_permit(&self) {
|
||||
let prev = self.fetch_sub(2, Release);
|
||||
let prev = self.0.fetch_sub(2, Release);
|
||||
|
||||
if prev >> 1 == 0 {
|
||||
// Something went wrong
|
||||
@@ -413,14 +412,14 @@ impl Semaphore for AtomicUsize {
|
||||
}
|
||||
|
||||
fn is_idle(&self) -> bool {
|
||||
self.load(Acquire) >> 1 == 0
|
||||
self.0.load(Acquire) >> 1 == 0
|
||||
}
|
||||
|
||||
fn close(&self) {
|
||||
self.fetch_or(1, Release);
|
||||
self.0.fetch_or(1, Release);
|
||||
}
|
||||
|
||||
fn is_closed(&self) -> bool {
|
||||
self.load(Acquire) & 1 == 1
|
||||
self.0.load(Acquire) & 1 == 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ impl<T> fmt::Debug for UnboundedReceiver<T> {
|
||||
/// the channel. Using an `unbounded` channel has the ability of causing the
|
||||
/// process to run out of memory. In this case, the process will be aborted.
|
||||
pub fn unbounded_channel<T>() -> (UnboundedSender<T>, UnboundedReceiver<T>) {
|
||||
let (tx, rx) = chan::channel(AtomicUsize::new(0));
|
||||
let (tx, rx) = chan::channel(Semaphore(AtomicUsize::new(0)));
|
||||
|
||||
let tx = UnboundedSender::new(tx);
|
||||
let rx = UnboundedReceiver::new(rx);
|
||||
@@ -70,7 +70,8 @@ pub fn unbounded_channel<T>() -> (UnboundedSender<T>, UnboundedReceiver<T>) {
|
||||
}
|
||||
|
||||
/// No capacity
|
||||
type Semaphore = AtomicUsize;
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct Semaphore(pub(crate) AtomicUsize);
|
||||
|
||||
impl<T> UnboundedReceiver<T> {
|
||||
pub(crate) fn new(chan: chan::Rx<T, Semaphore>) -> UnboundedReceiver<T> {
|
||||
@@ -279,7 +280,7 @@ impl<T> UnboundedSender<T> {
|
||||
use std::process;
|
||||
use std::sync::atomic::Ordering::{AcqRel, Acquire};
|
||||
|
||||
let mut curr = self.chan.semaphore().load(Acquire);
|
||||
let mut curr = self.chan.semaphore().0.load(Acquire);
|
||||
|
||||
loop {
|
||||
if curr & 1 == 1 {
|
||||
@@ -295,6 +296,7 @@ impl<T> UnboundedSender<T> {
|
||||
match self
|
||||
.chan
|
||||
.semaphore()
|
||||
.0
|
||||
.compare_exchange(curr, curr + 2, AcqRel, Acquire)
|
||||
{
|
||||
Ok(_) => return true,
|
||||
|
||||
Reference in New Issue
Block a user