mirror of
https://github.com/fafhrd91/actix-net
synced 2024-11-27 18:02:58 +01:00
add custom cell
This commit is contained in:
parent
79b525bc2f
commit
20b03a4780
@ -36,6 +36,8 @@ ssl = ["openssl", "tokio-openssl"]
|
|||||||
# rustls
|
# rustls
|
||||||
rust-tls = ["rustls", "tokio-rustls", "webpki", "webpki-roots"]
|
rust-tls = ["rustls", "tokio-rustls", "webpki", "webpki-roots"]
|
||||||
|
|
||||||
|
cell = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
actix = "0.7.0"
|
actix = "0.7.0"
|
||||||
|
|
||||||
|
62
src/cell.rs
Normal file
62
src/cell.rs
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
//! Custom cell impl
|
||||||
|
|
||||||
|
#[cfg(feature = "cell")]
|
||||||
|
use std::cell::UnsafeCell;
|
||||||
|
#[cfg(not(feature = "cell"))]
|
||||||
|
use std::cell::{Ref, RefCell, RefMut};
|
||||||
|
use std::fmt;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
pub(crate) struct Cell<T> {
|
||||||
|
#[cfg(feature = "cell")]
|
||||||
|
inner: Rc<UnsafeCell<T>>,
|
||||||
|
#[cfg(not(feature = "cell"))]
|
||||||
|
inner: Rc<RefCell<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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "cell")]
|
||||||
|
impl<T> Cell<T> {
|
||||||
|
pub(crate) fn new(inner: T) -> Self {
|
||||||
|
Self {
|
||||||
|
inner: Rc::new(UnsafeCell::new(inner)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn borrow(&self) -> &T {
|
||||||
|
unsafe { &*self.inner.as_ref().get() }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn borrow_mut(&self) -> &mut T {
|
||||||
|
unsafe { &mut *self.inner.as_ref().get() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "cell"))]
|
||||||
|
impl<T> Cell<T> {
|
||||||
|
pub(crate) fn new(inner: T) -> Self {
|
||||||
|
Self {
|
||||||
|
inner: Rc::new(RefCell::new(inner)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn borrow(&self) -> Ref<T> {
|
||||||
|
self.inner.borrow()
|
||||||
|
}
|
||||||
|
pub(crate) fn borrow_mut(&self) -> RefMut<T> {
|
||||||
|
self.inner.borrow_mut()
|
||||||
|
}
|
||||||
|
}
|
@ -1,19 +1,17 @@
|
|||||||
use std::cell::RefCell;
|
|
||||||
use std::rc::Rc;
|
|
||||||
|
|
||||||
use futures::Poll;
|
use futures::Poll;
|
||||||
|
|
||||||
|
use super::cell::Cell;
|
||||||
use super::service::Service;
|
use super::service::Service;
|
||||||
|
|
||||||
/// Service that allows to turn non-clone service to a service with `Clone` impl
|
/// Service that allows to turn non-clone service to a service with `Clone` impl
|
||||||
pub struct CloneableService<S: Service + 'static> {
|
pub struct CloneableService<S: Service + 'static> {
|
||||||
service: Rc<RefCell<S>>,
|
service: Cell<S>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Service + 'static> CloneableService<S> {
|
impl<S: Service + 'static> CloneableService<S> {
|
||||||
pub fn new(service: S) -> Self {
|
pub fn new(service: S) -> Self {
|
||||||
Self {
|
Self {
|
||||||
service: Rc::new(RefCell::new(service)),
|
service: Cell::new(service),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,6 +55,7 @@ extern crate webpki;
|
|||||||
#[cfg(feature = "rust-tls")]
|
#[cfg(feature = "rust-tls")]
|
||||||
extern crate webpki_roots;
|
extern crate webpki_roots;
|
||||||
|
|
||||||
|
mod cell;
|
||||||
pub mod cloneable;
|
pub mod cloneable;
|
||||||
pub mod connector;
|
pub mod connector;
|
||||||
pub mod counter;
|
pub mod counter;
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
use std::cell::RefCell;
|
|
||||||
use std::rc::Rc;
|
|
||||||
|
|
||||||
use futures::{Async, Future, Poll};
|
use futures::{Async, Future, Poll};
|
||||||
|
|
||||||
use super::{IntoNewService, NewService, Service};
|
use super::{IntoNewService, NewService, Service};
|
||||||
|
use cell::Cell;
|
||||||
|
|
||||||
/// Service for the `and_then` combinator, chaining a computation onto the end
|
/// Service for the `and_then` combinator, chaining a computation onto the end
|
||||||
/// of another service which completes successfully.
|
/// of another service which completes successfully.
|
||||||
@ -11,7 +9,7 @@ use super::{IntoNewService, NewService, Service};
|
|||||||
/// This is created by the `ServiceExt::and_then` method.
|
/// This is created by the `ServiceExt::and_then` method.
|
||||||
pub struct AndThen<A, B> {
|
pub struct AndThen<A, B> {
|
||||||
a: A,
|
a: A,
|
||||||
b: Rc<RefCell<B>>,
|
b: Cell<B>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B> AndThen<A, B>
|
impl<A, B> AndThen<A, B>
|
||||||
@ -21,10 +19,7 @@ where
|
|||||||
{
|
{
|
||||||
/// Create new `AndThen` combinator
|
/// Create new `AndThen` combinator
|
||||||
pub fn new(a: A, b: B) -> Self {
|
pub fn new(a: A, b: B) -> Self {
|
||||||
Self {
|
Self { a, b: Cell::new(b) }
|
||||||
a,
|
|
||||||
b: Rc::new(RefCell::new(b)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,7 +61,7 @@ where
|
|||||||
A: Service,
|
A: Service,
|
||||||
B: Service<Request = A::Response, Error = A::Error>,
|
B: Service<Request = A::Response, Error = A::Error>,
|
||||||
{
|
{
|
||||||
b: Rc<RefCell<B>>,
|
b: Cell<B>,
|
||||||
fut_b: Option<B::Future>,
|
fut_b: Option<B::Future>,
|
||||||
fut_a: A::Future,
|
fut_a: A::Future,
|
||||||
}
|
}
|
||||||
@ -76,7 +71,7 @@ where
|
|||||||
A: Service,
|
A: Service,
|
||||||
B: Service<Request = A::Response, Error = A::Error>,
|
B: Service<Request = A::Response, Error = A::Error>,
|
||||||
{
|
{
|
||||||
fn new(fut_a: A::Future, b: Rc<RefCell<B>>) -> Self {
|
fn new(fut_a: A::Future, b: Cell<B>) -> Self {
|
||||||
AndThenFuture {
|
AndThenFuture {
|
||||||
b,
|
b,
|
||||||
fut_a,
|
fut_a,
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
use std::cell::RefCell;
|
|
||||||
use std::rc::Rc;
|
|
||||||
|
|
||||||
use futures::{Async, Future, Poll};
|
use futures::{Async, Future, Poll};
|
||||||
|
|
||||||
use super::{IntoNewService, NewService, Service};
|
use super::{IntoNewService, NewService, Service};
|
||||||
|
use cell::Cell;
|
||||||
|
|
||||||
/// Service for the `then` combinator, chaining a computation onto the end of
|
/// Service for the `then` combinator, chaining a computation onto the end of
|
||||||
/// another service.
|
/// another service.
|
||||||
@ -11,7 +9,7 @@ use super::{IntoNewService, NewService, Service};
|
|||||||
/// This is created by the `ServiceExt::then` method.
|
/// This is created by the `ServiceExt::then` method.
|
||||||
pub struct Then<A, B> {
|
pub struct Then<A, B> {
|
||||||
a: A,
|
a: A,
|
||||||
b: Rc<RefCell<B>>,
|
b: Cell<B>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B> Then<A, B>
|
impl<A, B> Then<A, B>
|
||||||
@ -21,10 +19,7 @@ where
|
|||||||
{
|
{
|
||||||
/// Create new `Then` combinator
|
/// Create new `Then` combinator
|
||||||
pub fn new(a: A, b: B) -> Then<A, B> {
|
pub fn new(a: A, b: B) -> Then<A, B> {
|
||||||
Then {
|
Then { a, b: Cell::new(b) }
|
||||||
a,
|
|
||||||
b: Rc::new(RefCell::new(b)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,7 +61,7 @@ where
|
|||||||
A: Service,
|
A: Service,
|
||||||
B: Service<Request = Result<A::Response, A::Error>>,
|
B: Service<Request = Result<A::Response, A::Error>>,
|
||||||
{
|
{
|
||||||
b: Rc<RefCell<B>>,
|
b: Cell<B>,
|
||||||
fut_b: Option<B::Future>,
|
fut_b: Option<B::Future>,
|
||||||
fut_a: A::Future,
|
fut_a: A::Future,
|
||||||
}
|
}
|
||||||
@ -76,7 +71,7 @@ where
|
|||||||
A: Service,
|
A: Service,
|
||||||
B: Service<Request = Result<A::Response, A::Error>>,
|
B: Service<Request = Result<A::Response, A::Error>>,
|
||||||
{
|
{
|
||||||
fn new(fut_a: A::Future, b: Rc<RefCell<B>>) -> Self {
|
fn new(fut_a: A::Future, b: Cell<B>) -> Self {
|
||||||
ThenFuture {
|
ThenFuture {
|
||||||
b,
|
b,
|
||||||
fut_a,
|
fut_a,
|
||||||
@ -243,6 +238,7 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use service::{NewServiceExt, ServiceExt};
|
use service::{NewServiceExt, ServiceExt};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
struct Srv1(Rc<Cell<usize>>);
|
struct Srv1(Rc<Cell<usize>>);
|
||||||
impl Service for Srv1 {
|
impl Service for Srv1 {
|
||||||
type Request = Result<&'static str, &'static str>;
|
type Request = Result<&'static str, &'static str>;
|
||||||
@ -263,7 +259,6 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
struct Srv2(Rc<Cell<usize>>);
|
struct Srv2(Rc<Cell<usize>>);
|
||||||
|
|
||||||
impl Service for Srv2 {
|
impl Service for Srv2 {
|
||||||
@ -298,7 +293,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_call() {
|
fn test_call() {
|
||||||
let cnt = Rc::new(Cell::new(0));
|
let cnt = Rc::new(Cell::new(0));
|
||||||
let mut srv = Srv1(cnt.clone()).then(Srv2(cnt));
|
let mut srv = Srv1(cnt.clone()).then(Srv2(cnt)).clone();
|
||||||
|
|
||||||
let res = srv.call(Ok("srv1")).poll();
|
let res = srv.call(Ok("srv1")).poll();
|
||||||
assert!(res.is_ok());
|
assert!(res.is_ok());
|
||||||
@ -315,7 +310,7 @@ mod tests {
|
|||||||
let cnt2 = cnt.clone();
|
let cnt2 = cnt.clone();
|
||||||
let blank = move || Ok::<_, ()>(Srv1(cnt2.clone()));
|
let blank = move || Ok::<_, ()>(Srv1(cnt2.clone()));
|
||||||
let new_srv = blank.into_new_service().then(move || Ok(Srv2(cnt.clone())));
|
let new_srv = blank.into_new_service().then(move || Ok(Srv2(cnt.clone())));
|
||||||
if let Async::Ready(mut srv) = new_srv.new_service().poll().unwrap() {
|
if let Async::Ready(mut srv) = new_srv.clone().new_service().poll().unwrap() {
|
||||||
let res = srv.call(Ok("srv1")).poll();
|
let res = srv.call(Ok("srv1")).poll();
|
||||||
assert!(res.is_ok());
|
assert!(res.is_ok());
|
||||||
assert_eq!(res.unwrap(), Async::Ready(("srv1", "ok")));
|
assert_eq!(res.unwrap(), Async::Ready(("srv1", "ok")));
|
||||||
|
13
src/timer.rs
13
src/timer.rs
@ -1,5 +1,3 @@
|
|||||||
use std::cell::RefCell;
|
|
||||||
use std::rc::Rc;
|
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
use futures::future::{ok, FutureResult};
|
use futures::future::{ok, FutureResult};
|
||||||
@ -7,11 +5,12 @@ use futures::{Async, Future, Poll};
|
|||||||
use tokio_current_thread::spawn;
|
use tokio_current_thread::spawn;
|
||||||
use tokio_timer::sleep;
|
use tokio_timer::sleep;
|
||||||
|
|
||||||
|
use super::cell::Cell;
|
||||||
use super::service::{NewService, Service};
|
use super::service::{NewService, Service};
|
||||||
use super::Never;
|
use super::Never;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct LowResTimer(Rc<RefCell<Inner>>);
|
pub struct LowResTimer(Cell<Inner>);
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Inner {
|
struct Inner {
|
||||||
@ -30,7 +29,7 @@ impl Inner {
|
|||||||
|
|
||||||
impl LowResTimer {
|
impl LowResTimer {
|
||||||
pub fn with_interval(interval: Duration) -> LowResTimer {
|
pub fn with_interval(interval: Duration) -> LowResTimer {
|
||||||
LowResTimer(Rc::new(RefCell::new(Inner::new(interval))))
|
LowResTimer(Cell::new(Inner::new(interval)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn timer(&self) -> LowResTimerService {
|
pub fn timer(&self) -> LowResTimerService {
|
||||||
@ -40,7 +39,7 @@ impl LowResTimer {
|
|||||||
|
|
||||||
impl Default for LowResTimer {
|
impl Default for LowResTimer {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
LowResTimer(Rc::new(RefCell::new(Inner::new(Duration::from_secs(1)))))
|
LowResTimer(Cell::new(Inner::new(Duration::from_secs(1))))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,11 +57,11 @@ impl NewService for LowResTimer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct LowResTimerService(Rc<RefCell<Inner>>);
|
pub struct LowResTimerService(Cell<Inner>);
|
||||||
|
|
||||||
impl LowResTimerService {
|
impl LowResTimerService {
|
||||||
pub fn with_resolution(resolution: Duration) -> LowResTimerService {
|
pub fn with_resolution(resolution: Duration) -> LowResTimerService {
|
||||||
LowResTimerService(Rc::new(RefCell::new(Inner::new(resolution))))
|
LowResTimerService(Cell::new(Inner::new(resolution)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get current time. This function has to be called from
|
/// Get current time. This function has to be called from
|
||||||
|
Loading…
Reference in New Issue
Block a user