Created
January 16, 2020 12:17
-
-
Save Nemo157/b495b84b5b2f3134d19ad71ba5002066 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From cb60e8590835718eedc3d14d3ad6527a42c588ce Mon Sep 17 00:00:00 2001 | |
From: Wim Looman <[email protected]> | |
Date: Thu, 16 Jan 2020 13:17:13 +0100 | |
Subject: [PATCH] Replace actix-service::cell::Cell<_> with Rc<RefCell<_>> | |
--- | |
actix-service/src/and_then.rs | 17 ++++---- | |
actix-service/src/and_then_apply_fn.rs | 19 +++++---- | |
actix-service/src/apply_cfg.rs | 28 +++++++------ | |
actix-service/src/cell.rs | 57 -------------------------- | |
actix-service/src/lib.rs | 1 - | |
actix-service/src/then.rs | 15 +++---- | |
6 files changed, 42 insertions(+), 95 deletions(-) | |
delete mode 100644 actix-service/src/cell.rs | |
diff --git a/actix-service/src/and_then.rs b/actix-service/src/and_then.rs | |
index 07ddc01..1ae183a 100644 | |
--- a/actix-service/src/and_then.rs | |
+++ b/actix-service/src/and_then.rs | |
@@ -1,15 +1,16 @@ | |
use std::future::Future; | |
use std::pin::Pin; | |
use std::task::{Context, Poll}; | |
+use std::rc::Rc; | |
+use std::cell::RefCell; | |
use super::{Service, ServiceFactory}; | |
-use crate::cell::Cell; | |
/// Service for the `and_then` combinator, chaining a computation onto the end | |
/// of another service which completes successfully. | |
/// | |
/// This is created by the `ServiceExt::and_then` method. | |
-pub struct AndThenService<A, B>(Cell<A>, Cell<B>); | |
+pub struct AndThenService<A, B>(Rc<RefCell<A>>, Rc<RefCell<B>>); | |
impl<A, B> AndThenService<A, B> { | |
/// Create new `AndThen` combinator | |
@@ -18,7 +19,7 @@ impl<A, B> AndThenService<A, B> { | |
A: Service, | |
B: Service<Request = A::Response, Error = A::Error>, | |
{ | |
- Self(Cell::new(a), Cell::new(b)) | |
+ Self(Rc::new(RefCell::new(a)), Rc::new(RefCell::new(b))) | |
} | |
} | |
@@ -39,7 +40,7 @@ where | |
type Future = AndThenServiceResponse<A, B>; | |
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { | |
- let not_ready = { !self.0.get_mut().poll_ready(cx)?.is_ready() }; | |
+ let not_ready = { !self.0.borrow_mut().poll_ready(cx)?.is_ready() }; | |
if !self.1.poll_ready(cx)?.is_ready() || not_ready { | |
Poll::Pending | |
} else { | |
@@ -49,7 +50,7 @@ where | |
fn call(&mut self, req: A::Request) -> Self::Future { | |
AndThenServiceResponse { | |
- state: State::A(self.0.get_mut().call(req), Some(self.1.clone())), | |
+ state: State::A(self.0.borrow_mut().call(req), Some(self.1.clone())), | |
} | |
} | |
} | |
@@ -70,7 +71,7 @@ where | |
A: Service, | |
B: Service<Request = A::Response, Error = A::Error>, | |
{ | |
- A(#[pin] A::Future, Option<Cell<B>>), | |
+ A(#[pin] A::Future, Option<Rc<RefCell<B>>>), | |
B(#[pin] B::Future), | |
Empty, | |
} | |
@@ -90,9 +91,9 @@ where | |
match this.state.as_mut().project() { | |
State::A(fut, b) => match fut.poll(cx)? { | |
Poll::Ready(res) => { | |
- let mut b = b.take().unwrap(); | |
+ let b = b.take().unwrap(); | |
this.state.set(State::Empty); // drop fut A | |
- let fut = b.get_mut().call(res); | |
+ let fut = b.borrow_mut().call(res); | |
this.state.set(State::B(fut)); | |
self.poll(cx) | |
} | |
diff --git a/actix-service/src/and_then_apply_fn.rs b/actix-service/src/and_then_apply_fn.rs | |
index b0aba07..ea2fe00 100644 | |
--- a/actix-service/src/and_then_apply_fn.rs | |
+++ b/actix-service/src/and_then_apply_fn.rs | |
@@ -2,8 +2,9 @@ use std::future::Future; | |
use std::marker::PhantomData; | |
use std::pin::Pin; | |
use std::task::{Context, Poll}; | |
+use std::rc::Rc; | |
+use std::cell::RefCell; | |
-use crate::cell::Cell; | |
use crate::{Service, ServiceFactory}; | |
/// `Apply` service combinator | |
@@ -16,7 +17,7 @@ where | |
Err: From<A::Error> + From<B::Error>, | |
{ | |
a: A, | |
- b: Cell<(B, F)>, | |
+ b: Rc<RefCell<(B, F)>>, | |
r: PhantomData<(Fut, Res, Err)>, | |
} | |
@@ -32,7 +33,7 @@ where | |
pub(crate) fn new(a: A, b: B, f: F) -> Self { | |
Self { | |
a, | |
- b: Cell::new((b, f)), | |
+ b: Rc::new(RefCell::new((b, f))), | |
r: PhantomData, | |
} | |
} | |
@@ -70,7 +71,7 @@ where | |
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { | |
let not_ready = self.a.poll_ready(cx)?.is_pending(); | |
- if self.b.get_mut().0.poll_ready(cx)?.is_pending() || not_ready { | |
+ if self.b.borrow_mut().0.poll_ready(cx)?.is_pending() || not_ready { | |
Poll::Pending | |
} else { | |
Poll::Ready(Ok(())) | |
@@ -108,7 +109,7 @@ where | |
Err: From<A::Error>, | |
Err: From<B::Error>, | |
{ | |
- A(#[pin] A::Future, Option<Cell<(B, F)>>), | |
+ A(#[pin] A::Future, Option<Rc<RefCell<(B, F)>>>), | |
B(#[pin] Fut), | |
Empty, | |
} | |
@@ -131,10 +132,10 @@ where | |
match this.state.as_mut().project() { | |
State::A(fut, b) => match fut.poll(cx)? { | |
Poll::Ready(res) => { | |
- let mut b = b.take().unwrap(); | |
+ let b = b.take().unwrap(); | |
this.state.set(State::Empty); | |
- let b = b.get_mut(); | |
- let fut = (&mut b.1)(res, &mut b.0); | |
+ let (b, f) = &mut *b.borrow_mut(); | |
+ let fut = f(res, b); | |
this.state.set(State::B(fut)); | |
self.poll(cx) | |
} | |
@@ -268,7 +269,7 @@ where | |
if this.a.is_some() && this.b.is_some() { | |
Poll::Ready(Ok(AndThenApplyFn { | |
a: this.a.take().unwrap(), | |
- b: Cell::new((this.b.take().unwrap(), this.f.clone())), | |
+ b: Rc::new(RefCell::new((this.b.take().unwrap(), this.f.clone()))), | |
r: PhantomData, | |
})) | |
} else { | |
diff --git a/actix-service/src/apply_cfg.rs b/actix-service/src/apply_cfg.rs | |
index a295639..d127ba8 100644 | |
--- a/actix-service/src/apply_cfg.rs | |
+++ b/actix-service/src/apply_cfg.rs | |
@@ -2,8 +2,9 @@ use std::future::Future; | |
use std::marker::PhantomData; | |
use std::pin::Pin; | |
use std::task::{Context, Poll}; | |
+use std::rc::Rc; | |
+use std::cell::RefCell; | |
-use crate::cell::Cell; | |
use crate::{Service, ServiceFactory}; | |
/// Convert `Fn(Config, &mut Service1) -> Future<Service2>` fn to a service factory | |
@@ -15,7 +16,7 @@ where | |
S: Service, | |
{ | |
ApplyConfigService { | |
- srv: Cell::new((srv, f)), | |
+ srv: Rc::new(RefCell::new((srv, f))), | |
_t: PhantomData, | |
} | |
} | |
@@ -35,7 +36,7 @@ where | |
S: Service, | |
{ | |
ApplyConfigServiceFactory { | |
- srv: Cell::new((factory, f)), | |
+ srv: Rc::new(RefCell::new((factory, f))), | |
_t: PhantomData, | |
} | |
} | |
@@ -48,7 +49,7 @@ where | |
R: Future<Output = Result<S, E>>, | |
S: Service, | |
{ | |
- srv: Cell<(T, F)>, | |
+ srv: Rc<RefCell<(T, F)>>, | |
_t: PhantomData<(C, R, S)>, | |
} | |
@@ -84,10 +85,8 @@ where | |
type Future = R; | |
fn new_service(&self, cfg: C) -> Self::Future { | |
- unsafe { | |
- let srv = self.srv.get_mut_unsafe(); | |
- (srv.1)(cfg, &mut srv.0) | |
- } | |
+ let (t, f) = &mut *self.srv.borrow_mut(); | |
+ f(cfg, t) | |
} | |
} | |
@@ -99,7 +98,7 @@ where | |
R: Future<Output = Result<S, T::InitError>>, | |
S: Service, | |
{ | |
- srv: Cell<(T, F)>, | |
+ srv: Rc<RefCell<(T, F)>>, | |
_t: PhantomData<(C, R, S)>, | |
} | |
@@ -139,7 +138,7 @@ where | |
ApplyConfigServiceFactoryResponse { | |
cfg: Some(cfg), | |
store: self.srv.clone(), | |
- state: State::A(self.srv.get_ref().0.new_service(())), | |
+ state: State::A(self.srv.borrow().0.new_service(())), | |
} | |
} | |
} | |
@@ -154,7 +153,7 @@ where | |
S: Service, | |
{ | |
cfg: Option<C>, | |
- store: Cell<(T, F)>, | |
+ store: Rc<RefCell<(T, F)>>, | |
#[pin] | |
state: State<T, R, S>, | |
} | |
@@ -197,8 +196,11 @@ where | |
}, | |
State::B(srv) => match srv.poll_ready(cx)? { | |
Poll::Ready(_) => { | |
- let fut = (this.store.get_mut().1)(this.cfg.take().unwrap(), srv); | |
- this.state.set(State::C(fut)); | |
+ { | |
+ let (_, f) = &mut *this.store.borrow_mut(); | |
+ let fut = f(this.cfg.take().unwrap(), srv); | |
+ this.state.set(State::C(fut)); | |
+ } | |
self.poll(cx) | |
} | |
Poll::Pending => Poll::Pending, | |
diff --git a/actix-service/src/cell.rs b/actix-service/src/cell.rs | |
deleted file mode 100644 | |
index 3bcac0b..0000000 | |
--- a/actix-service/src/cell.rs | |
+++ /dev/null | |
@@ -1,57 +0,0 @@ | |
-//! Custom cell impl, internal use only | |
-use std::task::{Context, Poll}; | |
-use std::{cell::UnsafeCell, fmt, rc::Rc}; | |
- | |
-pub(crate) struct Cell<T> { | |
- 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 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() | |
- } | |
-} | |
- | |
-impl<T: crate::Service> crate::Service for Cell<T> { | |
- type Request = T::Request; | |
- type Response = T::Response; | |
- type Error = T::Error; | |
- type Future = T::Future; | |
- | |
- fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { | |
- self.get_mut().poll_ready(cx) | |
- } | |
- | |
- fn call(&mut self, req: Self::Request) -> Self::Future { | |
- self.get_mut().call(req) | |
- } | |
-} | |
diff --git a/actix-service/src/lib.rs b/actix-service/src/lib.rs | |
index d018e0e..0c52f53 100644 | |
--- a/actix-service/src/lib.rs | |
+++ b/actix-service/src/lib.rs | |
@@ -12,7 +12,6 @@ mod and_then_apply_fn; | |
mod apply; | |
mod apply_cfg; | |
pub mod boxed; | |
-mod cell; | |
mod fn_service; | |
mod map; | |
mod map_config; | |
diff --git a/actix-service/src/then.rs b/actix-service/src/then.rs | |
index 7cd5987..dd7620b 100644 | |
--- a/actix-service/src/then.rs | |
+++ b/actix-service/src/then.rs | |
@@ -1,9 +1,10 @@ | |
use std::future::Future; | |
use std::pin::Pin; | |
use std::task::{Context, Poll}; | |
+use std::rc::Rc; | |
+use std::cell::RefCell; | |
use super::{Service, ServiceFactory}; | |
-use crate::cell::Cell; | |
/// Service for the `then` combinator, chaining a computation onto the end of | |
/// another service. | |
@@ -11,7 +12,7 @@ use crate::cell::Cell; | |
/// This is created by the `ServiceExt::then` method. | |
pub struct ThenService<A, B> { | |
a: A, | |
- b: Cell<B>, | |
+ b: Rc<RefCell<B>>, | |
} | |
impl<A, B> ThenService<A, B> { | |
@@ -21,7 +22,7 @@ impl<A, B> ThenService<A, B> { | |
A: Service, | |
B: Service<Request = Result<A::Response, A::Error>, Error = A::Error>, | |
{ | |
- Self { a, b: Cell::new(b) } | |
+ Self { a, b: Rc::new(RefCell::new(b)) } | |
} | |
} | |
@@ -49,7 +50,7 @@ where | |
fn poll_ready(&mut self, ctx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { | |
let not_ready = !self.a.poll_ready(ctx)?.is_ready(); | |
- if !self.b.get_mut().poll_ready(ctx)?.is_ready() || not_ready { | |
+ if !self.b.borrow_mut().poll_ready(ctx)?.is_ready() || not_ready { | |
Poll::Pending | |
} else { | |
Poll::Ready(Ok(())) | |
@@ -79,7 +80,7 @@ where | |
A: Service, | |
B: Service<Request = Result<A::Response, A::Error>>, | |
{ | |
- A(#[pin] A::Future, Option<Cell<B>>), | |
+ A(#[pin] A::Future, Option<Rc<RefCell<B>>>), | |
B(#[pin] B::Future), | |
Empty, | |
} | |
@@ -99,9 +100,9 @@ where | |
match this.state.as_mut().project() { | |
State::A(fut, b) => match fut.poll(cx) { | |
Poll::Ready(res) => { | |
- let mut b = b.take().unwrap(); | |
+ let b = b.take().unwrap(); | |
this.state.set(State::Empty); // drop fut A | |
- let fut = b.get_mut().call(res); | |
+ let fut = b.borrow_mut().call(res); | |
this.state.set(State::B(fut)); | |
self.poll(cx) | |
} | |
-- | |
2.24.1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment