mirror of
https://github.com/fafhrd91/actix-net
synced 2024-11-24 00:01:11 +01:00
add custom cell
This commit is contained in:
parent
79b525bc2f
commit
20b03a4780
@ -36,6 +36,8 @@ ssl = ["openssl", "tokio-openssl"]
|
||||
# rustls
|
||||
rust-tls = ["rustls", "tokio-rustls", "webpki", "webpki-roots"]
|
||||
|
||||
cell = []
|
||||
|
||||
[dependencies]
|
||||
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 super::cell::Cell;
|
||||
use super::service::Service;
|
||||
|
||||
/// Service that allows to turn non-clone service to a service with `Clone` impl
|
||||
pub struct CloneableService<S: Service + 'static> {
|
||||
service: Rc<RefCell<S>>,
|
||||
service: Cell<S>,
|
||||
}
|
||||
|
||||
impl<S: Service + 'static> CloneableService<S> {
|
||||
pub fn new(service: S) -> Self {
|
||||
Self {
|
||||
service: Rc::new(RefCell::new(service)),
|
||||
service: Cell::new(service),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -55,6 +55,7 @@ extern crate webpki;
|
||||
#[cfg(feature = "rust-tls")]
|
||||
extern crate webpki_roots;
|
||||
|
||||
mod cell;
|
||||
pub mod cloneable;
|
||||
pub mod connector;
|
||||
pub mod counter;
|
||||
|
@ -1,9 +1,7 @@
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
|
||||
use futures::{Async, Future, Poll};
|
||||
|
||||
use super::{IntoNewService, NewService, Service};
|
||||
use cell::Cell;
|
||||
|
||||
/// Service for the `and_then` combinator, chaining a computation onto the end
|
||||
/// of another service which completes successfully.
|
||||
@ -11,7 +9,7 @@ use super::{IntoNewService, NewService, Service};
|
||||
/// This is created by the `ServiceExt::and_then` method.
|
||||
pub struct AndThen<A, B> {
|
||||
a: A,
|
||||
b: Rc<RefCell<B>>,
|
||||
b: Cell<B>,
|
||||
}
|
||||
|
||||
impl<A, B> AndThen<A, B>
|
||||
@ -21,10 +19,7 @@ where
|
||||
{
|
||||
/// Create new `AndThen` combinator
|
||||
pub fn new(a: A, b: B) -> Self {
|
||||
Self {
|
||||
a,
|
||||
b: Rc::new(RefCell::new(b)),
|
||||
}
|
||||
Self { a, b: Cell::new(b) }
|
||||
}
|
||||
}
|
||||
|
||||
@ -66,7 +61,7 @@ where
|
||||
A: Service,
|
||||
B: Service<Request = A::Response, Error = A::Error>,
|
||||
{
|
||||
b: Rc<RefCell<B>>,
|
||||
b: Cell<B>,
|
||||
fut_b: Option<B::Future>,
|
||||
fut_a: A::Future,
|
||||
}
|
||||
@ -76,7 +71,7 @@ where
|
||||
A: Service,
|
||||
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 {
|
||||
b,
|
||||
fut_a,
|
||||
|
@ -1,9 +1,7 @@
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
|
||||
use futures::{Async, Future, Poll};
|
||||
|
||||
use super::{IntoNewService, NewService, Service};
|
||||
use cell::Cell;
|
||||
|
||||
/// Service for the `then` combinator, chaining a computation onto the end of
|
||||
/// another service.
|
||||
@ -11,7 +9,7 @@ use super::{IntoNewService, NewService, Service};
|
||||
/// This is created by the `ServiceExt::then` method.
|
||||
pub struct Then<A, B> {
|
||||
a: A,
|
||||
b: Rc<RefCell<B>>,
|
||||
b: Cell<B>,
|
||||
}
|
||||
|
||||
impl<A, B> Then<A, B>
|
||||
@ -21,10 +19,7 @@ where
|
||||
{
|
||||
/// Create new `Then` combinator
|
||||
pub fn new(a: A, b: B) -> Then<A, B> {
|
||||
Then {
|
||||
a,
|
||||
b: Rc::new(RefCell::new(b)),
|
||||
}
|
||||
Then { a, b: Cell::new(b) }
|
||||
}
|
||||
}
|
||||
|
||||
@ -66,7 +61,7 @@ where
|
||||
A: Service,
|
||||
B: Service<Request = Result<A::Response, A::Error>>,
|
||||
{
|
||||
b: Rc<RefCell<B>>,
|
||||
b: Cell<B>,
|
||||
fut_b: Option<B::Future>,
|
||||
fut_a: A::Future,
|
||||
}
|
||||
@ -76,7 +71,7 @@ where
|
||||
A: Service,
|
||||
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 {
|
||||
b,
|
||||
fut_a,
|
||||
@ -243,6 +238,7 @@ mod tests {
|
||||
use super::*;
|
||||
use service::{NewServiceExt, ServiceExt};
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Srv1(Rc<Cell<usize>>);
|
||||
impl Service for Srv1 {
|
||||
type Request = Result<&'static str, &'static str>;
|
||||
@ -263,7 +259,6 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Srv2(Rc<Cell<usize>>);
|
||||
|
||||
impl Service for Srv2 {
|
||||
@ -298,7 +293,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_call() {
|
||||
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();
|
||||
assert!(res.is_ok());
|
||||
@ -315,7 +310,7 @@ mod tests {
|
||||
let cnt2 = cnt.clone();
|
||||
let blank = move || Ok::<_, ()>(Srv1(cnt2.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();
|
||||
assert!(res.is_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 futures::future::{ok, FutureResult};
|
||||
@ -7,11 +5,12 @@ use futures::{Async, Future, Poll};
|
||||
use tokio_current_thread::spawn;
|
||||
use tokio_timer::sleep;
|
||||
|
||||
use super::cell::Cell;
|
||||
use super::service::{NewService, Service};
|
||||
use super::Never;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct LowResTimer(Rc<RefCell<Inner>>);
|
||||
pub struct LowResTimer(Cell<Inner>);
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Inner {
|
||||
@ -30,7 +29,7 @@ impl Inner {
|
||||
|
||||
impl 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 {
|
||||
@ -40,7 +39,7 @@ impl LowResTimer {
|
||||
|
||||
impl Default for LowResTimer {
|
||||
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)]
|
||||
pub struct LowResTimerService(Rc<RefCell<Inner>>);
|
||||
pub struct LowResTimerService(Cell<Inner>);
|
||||
|
||||
impl 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
|
||||
|
Loading…
Reference in New Issue
Block a user