Skip to content

Commit 0dca1a7

Browse files
authored
actix-utils: Remove unsound custom Cell as well (#161)
1 parent 5d6d309 commit 0dca1a7

File tree

9 files changed

+86
-124
lines changed

9 files changed

+86
-124
lines changed

actix-utils/CHANGES.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
# Changes
22

33
## Unreleased - 2020-xx-xx
4+
45
* Upgrade `tokio-util` to `0.3`.
6+
* Remove unsound custom Cell and use `std::cell::RefCell` instead, as well as `actix-service`.
57

68
## [1.0.6] - 2020-01-08
79

actix-utils/src/cell.rs

Lines changed: 0 additions & 48 deletions
This file was deleted.

actix-utils/src/condition.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
1+
use std::cell::RefCell;
12
use std::future::Future;
23
use std::pin::Pin;
4+
use std::rc::Rc;
35
use std::task::{Context, Poll};
46

57
use slab::Slab;
68

7-
use crate::cell::Cell;
89
use crate::task::LocalWaker;
910

1011
/// Condition allows to notify multiple receivers at the same time
11-
pub struct Condition(Cell<Inner>);
12+
pub struct Condition(Rc<RefCell<Inner>>);
1213

1314
struct Inner {
1415
data: Slab<Option<LocalWaker>>,
@@ -22,12 +23,12 @@ impl Default for Condition {
2223

2324
impl Condition {
2425
pub fn new() -> Condition {
25-
Condition(Cell::new(Inner { data: Slab::new() }))
26+
Condition(Rc::new(RefCell::new(Inner { data: Slab::new() })))
2627
}
2728

2829
/// Get condition waiter
2930
pub fn wait(&mut self) -> Waiter {
30-
let token = self.0.get_mut().data.insert(None);
31+
let token = self.0.borrow_mut().data.insert(None);
3132
Waiter {
3233
token,
3334
inner: self.0.clone(),
@@ -36,7 +37,7 @@ impl Condition {
3637

3738
/// Notify all waiters
3839
pub fn notify(&self) {
39-
let inner = self.0.get_ref();
40+
let inner = self.0.borrow();
4041
for item in inner.data.iter() {
4142
if let Some(waker) = item.1 {
4243
waker.wake();
@@ -54,12 +55,12 @@ impl Drop for Condition {
5455
#[must_use = "Waiter do nothing unless polled"]
5556
pub struct Waiter {
5657
token: usize,
57-
inner: Cell<Inner>,
58+
inner: Rc<RefCell<Inner>>,
5859
}
5960

6061
impl Clone for Waiter {
6162
fn clone(&self) -> Self {
62-
let token = unsafe { self.inner.get_mut_unsafe() }.data.insert(None);
63+
let token = self.inner.borrow_mut().data.insert(None);
6364
Waiter {
6465
token,
6566
inner: self.inner.clone(),
@@ -73,7 +74,8 @@ impl Future for Waiter {
7374
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
7475
let this = self.get_mut();
7576

76-
let inner = unsafe { this.inner.get_mut().data.get_unchecked_mut(this.token) };
77+
let mut inner = this.inner.borrow_mut();
78+
let inner = unsafe { inner.data.get_unchecked_mut(this.token) };
7779
if inner.is_none() {
7880
let waker = LocalWaker::default();
7981
waker.register(cx.waker());
@@ -89,7 +91,7 @@ impl Future for Waiter {
8991

9092
impl Drop for Waiter {
9193
fn drop(&mut self) {
92-
self.inner.get_mut().data.remove(self.token);
94+
self.inner.borrow_mut().data.remove(self.token);
9395
}
9496
}
9597

actix-utils/src/either.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::pin::Pin;
33
use std::task::{Context, Poll};
44

55
use actix_service::{Service, ServiceFactory};
6-
use futures_util::{future, ready, future::Future};
6+
use futures_util::{future, future::Future, ready};
77

88
/// Combine two different service types into a single type.
99
///

actix-utils/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
#![deny(rust_2018_idioms)]
33
#![allow(clippy::type_complexity)]
44

5-
mod cell;
65
pub mod condition;
76
pub mod counter;
87
pub mod either;

actix-utils/src/mpsc.rs

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,25 @@
11
//! A multi-producer, single-consumer, futures-aware, FIFO queue.
22
use std::any::Any;
3+
use std::cell::RefCell;
34
use std::collections::VecDeque;
45
use std::error::Error;
56
use std::fmt;
67
use std::pin::Pin;
8+
use std::rc::Rc;
79
use std::task::{Context, Poll};
810

911
use futures_sink::Sink;
1012
use futures_util::stream::Stream;
1113

12-
use crate::cell::Cell;
1314
use crate::task::LocalWaker;
1415

1516
/// Creates a unbounded in-memory channel with buffered storage.
1617
pub fn channel<T>() -> (Sender<T>, Receiver<T>) {
17-
let shared = Cell::new(Shared {
18+
let shared = Rc::new(RefCell::new(Shared {
1819
has_receiver: true,
1920
buffer: VecDeque::new(),
2021
blocked_recv: LocalWaker::new(),
21-
});
22+
}));
2223
let sender = Sender {
2324
shared: shared.clone(),
2425
};
@@ -38,15 +39,15 @@ struct Shared<T> {
3839
/// This is created by the `channel` function.
3940
#[derive(Debug)]
4041
pub struct Sender<T> {
41-
shared: Cell<Shared<T>>,
42+
shared: Rc<RefCell<Shared<T>>>,
4243
}
4344

4445
impl<T> Unpin for Sender<T> {}
4546

4647
impl<T> Sender<T> {
4748
/// Sends the provided message along this channel.
4849
pub fn send(&self, item: T) -> Result<(), SendError<T>> {
49-
let shared = unsafe { self.shared.get_mut_unsafe() };
50+
let mut shared = self.shared.borrow_mut();
5051
if !shared.has_receiver {
5152
return Err(SendError(item)); // receiver was dropped
5253
};
@@ -60,7 +61,7 @@ impl<T> Sender<T> {
6061
/// This prevents any further messages from being sent on the channel while
6162
/// still enabling the receiver to drain messages that are buffered.
6263
pub fn close(&mut self) {
63-
self.shared.get_mut().has_receiver = false;
64+
self.shared.borrow_mut().has_receiver = false;
6465
}
6566
}
6667

@@ -94,8 +95,8 @@ impl<T> Sink<T> for Sender<T> {
9495

9596
impl<T> Drop for Sender<T> {
9697
fn drop(&mut self) {
97-
let count = self.shared.strong_count();
98-
let shared = self.shared.get_mut();
98+
let count = Rc::strong_count(&self.shared);
99+
let shared = self.shared.borrow_mut();
99100

100101
// check is last sender is about to drop
101102
if shared.has_receiver && count == 2 {
@@ -110,7 +111,7 @@ impl<T> Drop for Sender<T> {
110111
/// This is created by the `channel` function.
111112
#[derive(Debug)]
112113
pub struct Receiver<T> {
113-
shared: Cell<Shared<T>>,
114+
shared: Rc<RefCell<Shared<T>>>,
114115
}
115116

116117
impl<T> Receiver<T> {
@@ -127,23 +128,24 @@ impl<T> Unpin for Receiver<T> {}
127128
impl<T> Stream for Receiver<T> {
128129
type Item = T;
129130

130-
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
131-
if self.shared.strong_count() == 1 {
131+
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
132+
let mut shared = self.shared.borrow_mut();
133+
if Rc::strong_count(&self.shared) == 1 {
132134
// All senders have been dropped, so drain the buffer and end the
133135
// stream.
134-
Poll::Ready(self.shared.get_mut().buffer.pop_front())
135-
} else if let Some(msg) = self.shared.get_mut().buffer.pop_front() {
136+
Poll::Ready(shared.buffer.pop_front())
137+
} else if let Some(msg) = shared.buffer.pop_front() {
136138
Poll::Ready(Some(msg))
137139
} else {
138-
self.shared.get_mut().blocked_recv.register(cx.waker());
140+
shared.blocked_recv.register(cx.waker());
139141
Poll::Pending
140142
}
141143
}
142144
}
143145

144146
impl<T> Drop for Receiver<T> {
145147
fn drop(&mut self) {
146-
let shared = self.shared.get_mut();
148+
let mut shared = self.shared.borrow_mut();
147149
shared.buffer.clear();
148150
shared.has_receiver = false;
149151
}

0 commit comments

Comments
 (0)