mirror of
https://github.com/fafhrd91/actix-net
synced 2024-11-24 02:21:07 +01:00
actix-utils: Remove unsound custom Cell as well (#161)
This commit is contained in:
parent
5d6d309e66
commit
0dca1a705a
@ -1,7 +1,9 @@
|
|||||||
# Changes
|
# Changes
|
||||||
|
|
||||||
## Unreleased - 2020-xx-xx
|
## Unreleased - 2020-xx-xx
|
||||||
|
|
||||||
* Upgrade `tokio-util` to `0.3`.
|
* Upgrade `tokio-util` to `0.3`.
|
||||||
|
* Remove unsound custom Cell and use `std::cell::RefCell` instead, as well as `actix-service`.
|
||||||
|
|
||||||
## [1.0.6] - 2020-01-08
|
## [1.0.6] - 2020-01-08
|
||||||
|
|
||||||
|
@ -1,48 +0,0 @@
|
|||||||
//! Custom cell impl
|
|
||||||
|
|
||||||
use std::cell::UnsafeCell;
|
|
||||||
use std::fmt;
|
|
||||||
use std::rc::Rc;
|
|
||||||
|
|
||||||
pub(crate) struct Cell<T> {
|
|
||||||
pub(crate) inner: Rc<UnsafeCell<T>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Clone for Cell<T> {
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
Self {
|
|
||||||
inner: self.inner.clone(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: fmt::Debug> fmt::Debug for Cell<T> {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
self.inner.fmt(f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Cell<T> {
|
|
||||||
pub(crate) fn new(inner: T) -> Self {
|
|
||||||
Self {
|
|
||||||
inner: Rc::new(UnsafeCell::new(inner)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn strong_count(&self) -> usize {
|
|
||||||
Rc::strong_count(&self.inner)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn get_ref(&self) -> &T {
|
|
||||||
unsafe { &*self.inner.as_ref().get() }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn get_mut(&mut self) -> &mut T {
|
|
||||||
unsafe { &mut *self.inner.as_ref().get() }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(clippy::mut_from_ref)]
|
|
||||||
pub(crate) unsafe fn get_mut_unsafe(&self) -> &mut T {
|
|
||||||
&mut *self.inner.as_ref().get()
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,14 +1,15 @@
|
|||||||
|
use std::cell::RefCell;
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
|
use std::rc::Rc;
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
|
|
||||||
use slab::Slab;
|
use slab::Slab;
|
||||||
|
|
||||||
use crate::cell::Cell;
|
|
||||||
use crate::task::LocalWaker;
|
use crate::task::LocalWaker;
|
||||||
|
|
||||||
/// Condition allows to notify multiple receivers at the same time
|
/// Condition allows to notify multiple receivers at the same time
|
||||||
pub struct Condition(Cell<Inner>);
|
pub struct Condition(Rc<RefCell<Inner>>);
|
||||||
|
|
||||||
struct Inner {
|
struct Inner {
|
||||||
data: Slab<Option<LocalWaker>>,
|
data: Slab<Option<LocalWaker>>,
|
||||||
@ -22,12 +23,12 @@ impl Default for Condition {
|
|||||||
|
|
||||||
impl Condition {
|
impl Condition {
|
||||||
pub fn new() -> Condition {
|
pub fn new() -> Condition {
|
||||||
Condition(Cell::new(Inner { data: Slab::new() }))
|
Condition(Rc::new(RefCell::new(Inner { data: Slab::new() })))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get condition waiter
|
/// Get condition waiter
|
||||||
pub fn wait(&mut self) -> Waiter {
|
pub fn wait(&mut self) -> Waiter {
|
||||||
let token = self.0.get_mut().data.insert(None);
|
let token = self.0.borrow_mut().data.insert(None);
|
||||||
Waiter {
|
Waiter {
|
||||||
token,
|
token,
|
||||||
inner: self.0.clone(),
|
inner: self.0.clone(),
|
||||||
@ -36,7 +37,7 @@ impl Condition {
|
|||||||
|
|
||||||
/// Notify all waiters
|
/// Notify all waiters
|
||||||
pub fn notify(&self) {
|
pub fn notify(&self) {
|
||||||
let inner = self.0.get_ref();
|
let inner = self.0.borrow();
|
||||||
for item in inner.data.iter() {
|
for item in inner.data.iter() {
|
||||||
if let Some(waker) = item.1 {
|
if let Some(waker) = item.1 {
|
||||||
waker.wake();
|
waker.wake();
|
||||||
@ -54,12 +55,12 @@ impl Drop for Condition {
|
|||||||
#[must_use = "Waiter do nothing unless polled"]
|
#[must_use = "Waiter do nothing unless polled"]
|
||||||
pub struct Waiter {
|
pub struct Waiter {
|
||||||
token: usize,
|
token: usize,
|
||||||
inner: Cell<Inner>,
|
inner: Rc<RefCell<Inner>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clone for Waiter {
|
impl Clone for Waiter {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
let token = unsafe { self.inner.get_mut_unsafe() }.data.insert(None);
|
let token = self.inner.borrow_mut().data.insert(None);
|
||||||
Waiter {
|
Waiter {
|
||||||
token,
|
token,
|
||||||
inner: self.inner.clone(),
|
inner: self.inner.clone(),
|
||||||
@ -73,7 +74,8 @@ impl Future for Waiter {
|
|||||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
let this = self.get_mut();
|
let this = self.get_mut();
|
||||||
|
|
||||||
let inner = unsafe { this.inner.get_mut().data.get_unchecked_mut(this.token) };
|
let mut inner = this.inner.borrow_mut();
|
||||||
|
let inner = unsafe { inner.data.get_unchecked_mut(this.token) };
|
||||||
if inner.is_none() {
|
if inner.is_none() {
|
||||||
let waker = LocalWaker::default();
|
let waker = LocalWaker::default();
|
||||||
waker.register(cx.waker());
|
waker.register(cx.waker());
|
||||||
@ -89,7 +91,7 @@ impl Future for Waiter {
|
|||||||
|
|
||||||
impl Drop for Waiter {
|
impl Drop for Waiter {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.inner.get_mut().data.remove(self.token);
|
self.inner.borrow_mut().data.remove(self.token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ use std::pin::Pin;
|
|||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
|
|
||||||
use actix_service::{Service, ServiceFactory};
|
use actix_service::{Service, ServiceFactory};
|
||||||
use futures_util::{future, ready, future::Future};
|
use futures_util::{future, future::Future, ready};
|
||||||
|
|
||||||
/// Combine two different service types into a single type.
|
/// Combine two different service types into a single type.
|
||||||
///
|
///
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
#![deny(rust_2018_idioms)]
|
#![deny(rust_2018_idioms)]
|
||||||
#![allow(clippy::type_complexity)]
|
#![allow(clippy::type_complexity)]
|
||||||
|
|
||||||
mod cell;
|
|
||||||
pub mod condition;
|
pub mod condition;
|
||||||
pub mod counter;
|
pub mod counter;
|
||||||
pub mod either;
|
pub mod either;
|
||||||
|
@ -1,24 +1,25 @@
|
|||||||
//! A multi-producer, single-consumer, futures-aware, FIFO queue.
|
//! A multi-producer, single-consumer, futures-aware, FIFO queue.
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
|
use std::cell::RefCell;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
|
use std::rc::Rc;
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
|
|
||||||
use futures_sink::Sink;
|
use futures_sink::Sink;
|
||||||
use futures_util::stream::Stream;
|
use futures_util::stream::Stream;
|
||||||
|
|
||||||
use crate::cell::Cell;
|
|
||||||
use crate::task::LocalWaker;
|
use crate::task::LocalWaker;
|
||||||
|
|
||||||
/// Creates a unbounded in-memory channel with buffered storage.
|
/// Creates a unbounded in-memory channel with buffered storage.
|
||||||
pub fn channel<T>() -> (Sender<T>, Receiver<T>) {
|
pub fn channel<T>() -> (Sender<T>, Receiver<T>) {
|
||||||
let shared = Cell::new(Shared {
|
let shared = Rc::new(RefCell::new(Shared {
|
||||||
has_receiver: true,
|
has_receiver: true,
|
||||||
buffer: VecDeque::new(),
|
buffer: VecDeque::new(),
|
||||||
blocked_recv: LocalWaker::new(),
|
blocked_recv: LocalWaker::new(),
|
||||||
});
|
}));
|
||||||
let sender = Sender {
|
let sender = Sender {
|
||||||
shared: shared.clone(),
|
shared: shared.clone(),
|
||||||
};
|
};
|
||||||
@ -38,7 +39,7 @@ struct Shared<T> {
|
|||||||
/// This is created by the `channel` function.
|
/// This is created by the `channel` function.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Sender<T> {
|
pub struct Sender<T> {
|
||||||
shared: Cell<Shared<T>>,
|
shared: Rc<RefCell<Shared<T>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Unpin for Sender<T> {}
|
impl<T> Unpin for Sender<T> {}
|
||||||
@ -46,7 +47,7 @@ impl<T> Unpin for Sender<T> {}
|
|||||||
impl<T> Sender<T> {
|
impl<T> Sender<T> {
|
||||||
/// Sends the provided message along this channel.
|
/// Sends the provided message along this channel.
|
||||||
pub fn send(&self, item: T) -> Result<(), SendError<T>> {
|
pub fn send(&self, item: T) -> Result<(), SendError<T>> {
|
||||||
let shared = unsafe { self.shared.get_mut_unsafe() };
|
let mut shared = self.shared.borrow_mut();
|
||||||
if !shared.has_receiver {
|
if !shared.has_receiver {
|
||||||
return Err(SendError(item)); // receiver was dropped
|
return Err(SendError(item)); // receiver was dropped
|
||||||
};
|
};
|
||||||
@ -60,7 +61,7 @@ impl<T> Sender<T> {
|
|||||||
/// This prevents any further messages from being sent on the channel while
|
/// This prevents any further messages from being sent on the channel while
|
||||||
/// still enabling the receiver to drain messages that are buffered.
|
/// still enabling the receiver to drain messages that are buffered.
|
||||||
pub fn close(&mut self) {
|
pub fn close(&mut self) {
|
||||||
self.shared.get_mut().has_receiver = false;
|
self.shared.borrow_mut().has_receiver = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,8 +95,8 @@ impl<T> Sink<T> for Sender<T> {
|
|||||||
|
|
||||||
impl<T> Drop for Sender<T> {
|
impl<T> Drop for Sender<T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
let count = self.shared.strong_count();
|
let count = Rc::strong_count(&self.shared);
|
||||||
let shared = self.shared.get_mut();
|
let shared = self.shared.borrow_mut();
|
||||||
|
|
||||||
// check is last sender is about to drop
|
// check is last sender is about to drop
|
||||||
if shared.has_receiver && count == 2 {
|
if shared.has_receiver && count == 2 {
|
||||||
@ -110,7 +111,7 @@ impl<T> Drop for Sender<T> {
|
|||||||
/// This is created by the `channel` function.
|
/// This is created by the `channel` function.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Receiver<T> {
|
pub struct Receiver<T> {
|
||||||
shared: Cell<Shared<T>>,
|
shared: Rc<RefCell<Shared<T>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Receiver<T> {
|
impl<T> Receiver<T> {
|
||||||
@ -127,15 +128,16 @@ impl<T> Unpin for Receiver<T> {}
|
|||||||
impl<T> Stream for Receiver<T> {
|
impl<T> Stream for Receiver<T> {
|
||||||
type Item = T;
|
type Item = T;
|
||||||
|
|
||||||
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
|
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
|
||||||
if self.shared.strong_count() == 1 {
|
let mut shared = self.shared.borrow_mut();
|
||||||
|
if Rc::strong_count(&self.shared) == 1 {
|
||||||
// All senders have been dropped, so drain the buffer and end the
|
// All senders have been dropped, so drain the buffer and end the
|
||||||
// stream.
|
// stream.
|
||||||
Poll::Ready(self.shared.get_mut().buffer.pop_front())
|
Poll::Ready(shared.buffer.pop_front())
|
||||||
} else if let Some(msg) = self.shared.get_mut().buffer.pop_front() {
|
} else if let Some(msg) = shared.buffer.pop_front() {
|
||||||
Poll::Ready(Some(msg))
|
Poll::Ready(Some(msg))
|
||||||
} else {
|
} else {
|
||||||
self.shared.get_mut().blocked_recv.register(cx.waker());
|
shared.blocked_recv.register(cx.waker());
|
||||||
Poll::Pending
|
Poll::Pending
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -143,7 +145,7 @@ impl<T> Stream for Receiver<T> {
|
|||||||
|
|
||||||
impl<T> Drop for Receiver<T> {
|
impl<T> Drop for Receiver<T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
let shared = self.shared.get_mut();
|
let mut shared = self.shared.borrow_mut();
|
||||||
shared.buffer.clear();
|
shared.buffer.clear();
|
||||||
shared.has_receiver = false;
|
shared.has_receiver = false;
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,21 @@
|
|||||||
//! A one-shot, futures-aware channel.
|
//! A one-shot, futures-aware channel.
|
||||||
|
use std::cell::RefCell;
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
|
use std::rc::Rc;
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
|
|
||||||
pub use futures_channel::oneshot::Canceled;
|
pub use futures_channel::oneshot::Canceled;
|
||||||
use slab::Slab;
|
use slab::Slab;
|
||||||
|
|
||||||
use crate::cell::Cell;
|
|
||||||
use crate::task::LocalWaker;
|
use crate::task::LocalWaker;
|
||||||
|
|
||||||
/// Creates a new futures-aware, one-shot channel.
|
/// Creates a new futures-aware, one-shot channel.
|
||||||
pub fn channel<T>() -> (Sender<T>, Receiver<T>) {
|
pub fn channel<T>() -> (Sender<T>, Receiver<T>) {
|
||||||
let inner = Cell::new(Inner {
|
let inner = Rc::new(RefCell::new(Inner {
|
||||||
value: None,
|
value: None,
|
||||||
rx_task: LocalWaker::new(),
|
rx_task: LocalWaker::new(),
|
||||||
});
|
}));
|
||||||
let tx = Sender {
|
let tx = Sender {
|
||||||
inner: inner.clone(),
|
inner: inner.clone(),
|
||||||
};
|
};
|
||||||
@ -24,14 +25,14 @@ pub fn channel<T>() -> (Sender<T>, Receiver<T>) {
|
|||||||
|
|
||||||
/// Creates a new futures-aware, pool of one-shot's.
|
/// Creates a new futures-aware, pool of one-shot's.
|
||||||
pub fn pool<T>() -> Pool<T> {
|
pub fn pool<T>() -> Pool<T> {
|
||||||
Pool(Cell::new(Slab::new()))
|
Pool(Rc::new(RefCell::new(Slab::new())))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents the completion half of a oneshot through which the result of a
|
/// Represents the completion half of a oneshot through which the result of a
|
||||||
/// computation is signaled.
|
/// computation is signaled.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Sender<T> {
|
pub struct Sender<T> {
|
||||||
inner: Cell<Inner<T>>,
|
inner: Rc<RefCell<Inner<T>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A future representing the completion of a computation happening elsewhere in
|
/// A future representing the completion of a computation happening elsewhere in
|
||||||
@ -39,7 +40,7 @@ pub struct Sender<T> {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[must_use = "futures do nothing unless polled"]
|
#[must_use = "futures do nothing unless polled"]
|
||||||
pub struct Receiver<T> {
|
pub struct Receiver<T> {
|
||||||
inner: Cell<Inner<T>>,
|
inner: Rc<RefCell<Inner<T>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// The channels do not ever project Pin to the inner T
|
// The channels do not ever project Pin to the inner T
|
||||||
@ -63,9 +64,9 @@ impl<T> Sender<T> {
|
|||||||
/// then `Ok(())` is returned. If the receiving end was dropped before
|
/// then `Ok(())` is returned. If the receiving end was dropped before
|
||||||
/// this function was called, however, then `Err` is returned with the value
|
/// this function was called, however, then `Err` is returned with the value
|
||||||
/// provided.
|
/// provided.
|
||||||
pub fn send(mut self, val: T) -> Result<(), T> {
|
pub fn send(self, val: T) -> Result<(), T> {
|
||||||
if self.inner.strong_count() == 2 {
|
if Rc::strong_count(&self.inner) == 2 {
|
||||||
let inner = self.inner.get_mut();
|
let mut inner = self.inner.borrow_mut();
|
||||||
inner.value = Some(val);
|
inner.value = Some(val);
|
||||||
inner.rx_task.wake();
|
inner.rx_task.wake();
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -77,13 +78,13 @@ impl<T> Sender<T> {
|
|||||||
/// Tests to see whether this `Sender`'s corresponding `Receiver`
|
/// Tests to see whether this `Sender`'s corresponding `Receiver`
|
||||||
/// has gone away.
|
/// has gone away.
|
||||||
pub fn is_canceled(&self) -> bool {
|
pub fn is_canceled(&self) -> bool {
|
||||||
self.inner.strong_count() == 1
|
Rc::strong_count(&self.inner) == 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Drop for Sender<T> {
|
impl<T> Drop for Sender<T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.inner.get_ref().rx_task.wake();
|
self.inner.borrow().rx_task.wake();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,22 +95,22 @@ impl<T> Future for Receiver<T> {
|
|||||||
let this = self.get_mut();
|
let this = self.get_mut();
|
||||||
|
|
||||||
// If we've got a value, then skip the logic below as we're done.
|
// If we've got a value, then skip the logic below as we're done.
|
||||||
if let Some(val) = this.inner.get_mut().value.take() {
|
if let Some(val) = this.inner.borrow_mut().value.take() {
|
||||||
return Poll::Ready(Ok(val));
|
return Poll::Ready(Ok(val));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if sender is dropped and return error if it is.
|
// Check if sender is dropped and return error if it is.
|
||||||
if this.inner.strong_count() == 1 {
|
if Rc::strong_count(&this.inner) == 1 {
|
||||||
Poll::Ready(Err(Canceled))
|
Poll::Ready(Err(Canceled))
|
||||||
} else {
|
} else {
|
||||||
this.inner.get_ref().rx_task.register(cx.waker());
|
this.inner.borrow().rx_task.register(cx.waker());
|
||||||
Poll::Pending
|
Poll::Pending
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Futures-aware, pool of one-shot's.
|
/// Futures-aware, pool of one-shot's.
|
||||||
pub struct Pool<T>(Cell<Slab<PoolInner<T>>>);
|
pub struct Pool<T>(Rc<RefCell<Slab<PoolInner<T>>>>);
|
||||||
|
|
||||||
bitflags::bitflags! {
|
bitflags::bitflags! {
|
||||||
pub struct Flags: u8 {
|
pub struct Flags: u8 {
|
||||||
@ -127,7 +128,7 @@ struct PoolInner<T> {
|
|||||||
|
|
||||||
impl<T> Pool<T> {
|
impl<T> Pool<T> {
|
||||||
pub fn channel(&mut self) -> (PSender<T>, PReceiver<T>) {
|
pub fn channel(&mut self) -> (PSender<T>, PReceiver<T>) {
|
||||||
let token = self.0.get_mut().insert(PoolInner {
|
let token = self.0.borrow_mut().insert(PoolInner {
|
||||||
flags: Flags::all(),
|
flags: Flags::all(),
|
||||||
value: None,
|
value: None,
|
||||||
waker: LocalWaker::default(),
|
waker: LocalWaker::default(),
|
||||||
@ -157,7 +158,7 @@ impl<T> Clone for Pool<T> {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PSender<T> {
|
pub struct PSender<T> {
|
||||||
token: usize,
|
token: usize,
|
||||||
inner: Cell<Slab<PoolInner<T>>>,
|
inner: Rc<RefCell<Slab<PoolInner<T>>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A future representing the completion of a computation happening elsewhere in
|
/// A future representing the completion of a computation happening elsewhere in
|
||||||
@ -166,7 +167,7 @@ pub struct PSender<T> {
|
|||||||
#[must_use = "futures do nothing unless polled"]
|
#[must_use = "futures do nothing unless polled"]
|
||||||
pub struct PReceiver<T> {
|
pub struct PReceiver<T> {
|
||||||
token: usize,
|
token: usize,
|
||||||
inner: Cell<Slab<PoolInner<T>>>,
|
inner: Rc<RefCell<Slab<PoolInner<T>>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// The oneshots do not ever project Pin to the inner T
|
// The oneshots do not ever project Pin to the inner T
|
||||||
@ -184,8 +185,9 @@ impl<T> PSender<T> {
|
|||||||
/// then `Ok(())` is returned. If the receiving end was dropped before
|
/// then `Ok(())` is returned. If the receiving end was dropped before
|
||||||
/// this function was called, however, then `Err` is returned with the value
|
/// this function was called, however, then `Err` is returned with the value
|
||||||
/// provided.
|
/// provided.
|
||||||
pub fn send(mut self, val: T) -> Result<(), T> {
|
pub fn send(self, val: T) -> Result<(), T> {
|
||||||
let inner = unsafe { self.inner.get_mut().get_unchecked_mut(self.token) };
|
let mut inner = self.inner.borrow_mut();
|
||||||
|
let inner = unsafe { inner.get_unchecked_mut(self.token) };
|
||||||
|
|
||||||
if inner.flags.contains(Flags::RECEIVER) {
|
if inner.flags.contains(Flags::RECEIVER) {
|
||||||
inner.value = Some(val);
|
inner.value = Some(val);
|
||||||
@ -199,7 +201,7 @@ impl<T> PSender<T> {
|
|||||||
/// Tests to see whether this `Sender`'s corresponding `Receiver`
|
/// Tests to see whether this `Sender`'s corresponding `Receiver`
|
||||||
/// has gone away.
|
/// has gone away.
|
||||||
pub fn is_canceled(&self) -> bool {
|
pub fn is_canceled(&self) -> bool {
|
||||||
!unsafe { self.inner.get_ref().get_unchecked(self.token) }
|
!unsafe { self.inner.borrow().get_unchecked(self.token) }
|
||||||
.flags
|
.flags
|
||||||
.contains(Flags::RECEIVER)
|
.contains(Flags::RECEIVER)
|
||||||
}
|
}
|
||||||
@ -207,23 +209,25 @@ impl<T> PSender<T> {
|
|||||||
|
|
||||||
impl<T> Drop for PSender<T> {
|
impl<T> Drop for PSender<T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
let inner = unsafe { self.inner.get_mut().get_unchecked_mut(self.token) };
|
let mut inner = self.inner.borrow_mut();
|
||||||
if inner.flags.contains(Flags::RECEIVER) {
|
let inner_token = unsafe { inner.get_unchecked_mut(self.token) };
|
||||||
inner.waker.wake();
|
if inner_token.flags.contains(Flags::RECEIVER) {
|
||||||
inner.flags.remove(Flags::SENDER);
|
inner_token.waker.wake();
|
||||||
|
inner_token.flags.remove(Flags::SENDER);
|
||||||
} else {
|
} else {
|
||||||
self.inner.get_mut().remove(self.token);
|
inner.remove(self.token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Drop for PReceiver<T> {
|
impl<T> Drop for PReceiver<T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
let inner = unsafe { self.inner.get_mut().get_unchecked_mut(self.token) };
|
let mut inner = self.inner.borrow_mut();
|
||||||
if inner.flags.contains(Flags::SENDER) {
|
let inner_token = unsafe { inner.get_unchecked_mut(self.token) };
|
||||||
inner.flags.remove(Flags::RECEIVER);
|
if inner_token.flags.contains(Flags::SENDER) {
|
||||||
|
inner_token.flags.remove(Flags::RECEIVER);
|
||||||
} else {
|
} else {
|
||||||
self.inner.get_mut().remove(self.token);
|
inner.remove(self.token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -233,7 +237,8 @@ impl<T> Future for PReceiver<T> {
|
|||||||
|
|
||||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
let this = self.get_mut();
|
let this = self.get_mut();
|
||||||
let inner = unsafe { this.inner.get_mut().get_unchecked_mut(this.token) };
|
let mut inner = this.inner.borrow_mut();
|
||||||
|
let inner = unsafe { inner.get_unchecked_mut(this.token) };
|
||||||
|
|
||||||
// If we've got a value, then skip the logic below as we're done.
|
// If we've got a value, then skip the logic below as we're done.
|
||||||
if let Some(val) = inner.value.take() {
|
if let Some(val) = inner.value.take() {
|
||||||
|
@ -3,7 +3,7 @@ use std::pin::Pin;
|
|||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
|
|
||||||
use actix_service::{IntoService, Service};
|
use actix_service::{IntoService, Service};
|
||||||
use futures_util::{FutureExt, stream::Stream};
|
use futures_util::{stream::Stream, FutureExt};
|
||||||
|
|
||||||
use crate::mpsc;
|
use crate::mpsc;
|
||||||
|
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
|
use std::cell::RefCell;
|
||||||
use std::convert::Infallible;
|
use std::convert::Infallible;
|
||||||
|
use std::rc::Rc;
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
use std::time::{self, Duration, Instant};
|
use std::time::{self, Duration, Instant};
|
||||||
|
|
||||||
@ -6,10 +8,8 @@ use actix_rt::time::delay_for;
|
|||||||
use actix_service::{Service, ServiceFactory};
|
use actix_service::{Service, ServiceFactory};
|
||||||
use futures_util::future::{ok, ready, FutureExt, Ready};
|
use futures_util::future::{ok, ready, FutureExt, Ready};
|
||||||
|
|
||||||
use super::cell::Cell;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct LowResTime(Cell<Inner>);
|
pub struct LowResTime(Rc<RefCell<Inner>>);
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Inner {
|
struct Inner {
|
||||||
@ -28,7 +28,7 @@ impl Inner {
|
|||||||
|
|
||||||
impl LowResTime {
|
impl LowResTime {
|
||||||
pub fn with(resolution: Duration) -> LowResTime {
|
pub fn with(resolution: Duration) -> LowResTime {
|
||||||
LowResTime(Cell::new(Inner::new(resolution)))
|
LowResTime(Rc::new(RefCell::new(Inner::new(resolution))))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn timer(&self) -> LowResTimeService {
|
pub fn timer(&self) -> LowResTimeService {
|
||||||
@ -38,7 +38,7 @@ impl LowResTime {
|
|||||||
|
|
||||||
impl Default for LowResTime {
|
impl Default for LowResTime {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
LowResTime(Cell::new(Inner::new(Duration::from_secs(1))))
|
LowResTime(Rc::new(RefCell::new(Inner::new(Duration::from_secs(1)))))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,30 +57,30 @@ impl ServiceFactory for LowResTime {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct LowResTimeService(Cell<Inner>);
|
pub struct LowResTimeService(Rc<RefCell<Inner>>);
|
||||||
|
|
||||||
impl LowResTimeService {
|
impl LowResTimeService {
|
||||||
pub fn with(resolution: Duration) -> LowResTimeService {
|
pub fn with(resolution: Duration) -> LowResTimeService {
|
||||||
LowResTimeService(Cell::new(Inner::new(resolution)))
|
LowResTimeService(Rc::new(RefCell::new(Inner::new(resolution))))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get current time. This function has to be called from
|
/// Get current time. This function has to be called from
|
||||||
/// future's poll method, otherwise it panics.
|
/// future's poll method, otherwise it panics.
|
||||||
pub fn now(&self) -> Instant {
|
pub fn now(&self) -> Instant {
|
||||||
let cur = self.0.get_ref().current;
|
let cur = self.0.borrow().current;
|
||||||
if let Some(cur) = cur {
|
if let Some(cur) = cur {
|
||||||
cur
|
cur
|
||||||
} else {
|
} else {
|
||||||
let now = Instant::now();
|
let now = Instant::now();
|
||||||
let mut inner = self.0.clone();
|
let inner = self.0.clone();
|
||||||
let interval = {
|
let interval = {
|
||||||
let mut b = inner.get_mut();
|
let mut b = inner.borrow_mut();
|
||||||
b.current = Some(now);
|
b.current = Some(now);
|
||||||
b.resolution
|
b.resolution
|
||||||
};
|
};
|
||||||
|
|
||||||
actix_rt::spawn(delay_for(interval).then(move |_| {
|
actix_rt::spawn(delay_for(interval).then(move |_| {
|
||||||
inner.get_mut().current.take();
|
inner.borrow_mut().current.take();
|
||||||
ready(())
|
ready(())
|
||||||
}));
|
}));
|
||||||
now
|
now
|
||||||
@ -104,7 +104,7 @@ impl Service for LowResTimeService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct SystemTime(Cell<SystemTimeInner>);
|
pub struct SystemTime(Rc<RefCell<SystemTimeInner>>);
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct SystemTimeInner {
|
struct SystemTimeInner {
|
||||||
@ -122,30 +122,30 @@ impl SystemTimeInner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct SystemTimeService(Cell<SystemTimeInner>);
|
pub struct SystemTimeService(Rc<RefCell<SystemTimeInner>>);
|
||||||
|
|
||||||
impl SystemTimeService {
|
impl SystemTimeService {
|
||||||
pub fn with(resolution: Duration) -> SystemTimeService {
|
pub fn with(resolution: Duration) -> SystemTimeService {
|
||||||
SystemTimeService(Cell::new(SystemTimeInner::new(resolution)))
|
SystemTimeService(Rc::new(RefCell::new(SystemTimeInner::new(resolution))))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get current time. This function has to be called from
|
/// Get current time. This function has to be called from
|
||||||
/// future's poll method, otherwise it panics.
|
/// future's poll method, otherwise it panics.
|
||||||
pub fn now(&self) -> time::SystemTime {
|
pub fn now(&self) -> time::SystemTime {
|
||||||
let cur = self.0.get_ref().current;
|
let cur = self.0.borrow().current;
|
||||||
if let Some(cur) = cur {
|
if let Some(cur) = cur {
|
||||||
cur
|
cur
|
||||||
} else {
|
} else {
|
||||||
let now = time::SystemTime::now();
|
let now = time::SystemTime::now();
|
||||||
let mut inner = self.0.clone();
|
let inner = self.0.clone();
|
||||||
let interval = {
|
let interval = {
|
||||||
let mut b = inner.get_mut();
|
let mut b = inner.borrow_mut();
|
||||||
b.current = Some(now);
|
b.current = Some(now);
|
||||||
b.resolution
|
b.resolution
|
||||||
};
|
};
|
||||||
|
|
||||||
actix_rt::spawn(delay_for(interval).then(move |_| {
|
actix_rt::spawn(delay_for(interval).then(move |_| {
|
||||||
inner.get_mut().current.take();
|
inner.borrow_mut().current.take();
|
||||||
ready(())
|
ready(())
|
||||||
}));
|
}));
|
||||||
now
|
now
|
||||||
|
Loading…
Reference in New Issue
Block a user