1
0
Fork 0
mirror of https://github.com/actix/actix-web.git synced 2024-12-28 02:50:39 +00:00

remove unneeded UnsafeCell

This commit is contained in:
Nikolay Kim 2018-06-21 23:21:28 +06:00
parent 65ca563579
commit c9069e9a3c
4 changed files with 33 additions and 78 deletions

View file

@ -1,4 +1,3 @@
use std::cell::UnsafeCell;
use std::marker::PhantomData;
use std::rc::Rc;
@ -297,12 +296,12 @@ impl<S: 'static> Route<S> {
/// `RouteHandler` wrapper. This struct is required because it needs to be
/// shared for resource level middlewares.
struct InnerHandler<S>(Rc<UnsafeCell<Box<RouteHandler<S>>>>);
struct InnerHandler<S>(Rc<Box<RouteHandler<S>>>);
impl<S: 'static> InnerHandler<S> {
#[inline]
fn new<H: Handler<S>>(h: H) -> Self {
InnerHandler(Rc::new(UnsafeCell::new(Box::new(WrapHandler::new(h)))))
InnerHandler(Rc::new(Box::new(WrapHandler::new(h))))
}
#[inline]
@ -313,14 +312,12 @@ impl<S: 'static> InnerHandler<S> {
R: Responder + 'static,
E: Into<Error> + 'static,
{
InnerHandler(Rc::new(UnsafeCell::new(Box::new(AsyncHandler::new(h)))))
InnerHandler(Rc::new(Box::new(AsyncHandler::new(h))))
}
#[inline]
pub fn handle(&self, req: HttpRequest<S>) -> AsyncResult<HttpResponse> {
// reason: handler is unique per thread, handler get called from sync code only
let h = unsafe { &mut *self.0.as_ref().get() };
h.handle(req)
self.0.handle(req)
}
}

View file

@ -1,4 +1,3 @@
use std::cell::UnsafeCell;
use std::marker::PhantomData;
use std::mem;
use std::rc::Rc;
@ -19,7 +18,7 @@ use resource::ResourceHandler;
use router::Resource;
type ScopeResource<S> = Rc<ResourceHandler<S>>;
type Route<S> = UnsafeCell<Box<RouteHandler<S>>>;
type Route<S> = Box<RouteHandler<S>>;
type ScopeResources<S> = Rc<Vec<(Resource, ScopeResource<S>)>>;
type NestedInfo<S> = (Resource, Route<S>, Vec<Box<Predicate<S>>>);
@ -145,7 +144,7 @@ impl<S: 'static> Scope<S> {
state: Rc::clone(&state),
filters: scope.take_filters(),
})];
let handler = UnsafeCell::new(Box::new(Wrapper { scope, state }));
let handler = Box::new(Wrapper { scope, state });
self.nested
.push((Resource::prefix("", &path), handler, filters));
@ -184,11 +183,8 @@ impl<S: 'static> Scope<S> {
let mut scope = f(scope);
let filters = scope.take_filters();
self.nested.push((
Resource::prefix("", &path),
UnsafeCell::new(Box::new(scope)),
filters,
));
self.nested
.push((Resource::prefix("", &path), Box::new(scope), filters));
self
}
@ -384,10 +380,7 @@ impl<S: 'static> RouteHandler<S> for Scope<S> {
req.set_prefix_len(prefix_len);
req.match_info_mut().set_tail(prefix_len);
req.match_info_mut().set_url(url);
let hnd: &mut RouteHandler<_> =
unsafe { (&mut *(handler.get())).as_mut() };
return hnd.handle(req);
return handler.handle(req);
}
}

View file

@ -394,11 +394,11 @@ impl<S: 'static> Iterator for TestApp<S> {
///
/// fn main() {
/// let resp = TestRequest::with_header("content-type", "text/plain")
/// .run(index)
/// .run(&index)
/// .unwrap();
/// assert_eq!(resp.status(), StatusCode::OK);
///
/// let resp = TestRequest::default().run(index).unwrap();
/// let resp = TestRequest::default().run(&index).unwrap();
/// assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
/// }
/// ```

View file

@ -1,5 +1,4 @@
use futures::{Async, Future, Poll};
use std::cell::UnsafeCell;
use std::marker::PhantomData;
use std::rc::Rc;
@ -14,18 +13,8 @@ where
T: FromRequest<S>,
S: 'static,
{
hnd: Rc<WithHnd<T, S, F, R>>,
hnd: Rc<F>,
cfg: Rc<T::Config>,
}
pub struct WithHnd<T, S, F, R>
where
F: Fn(T) -> R,
T: FromRequest<S>,
S: 'static,
{
hnd: Rc<UnsafeCell<F>>,
_t: PhantomData<T>,
_s: PhantomData<S>,
}
@ -38,11 +27,8 @@ where
pub fn new(f: F, cfg: T::Config) -> Self {
With {
cfg: Rc::new(cfg),
hnd: Rc::new(WithHnd {
hnd: Rc::new(UnsafeCell::new(f)),
_t: PhantomData,
_s: PhantomData,
}),
hnd: Rc::new(f),
_s: PhantomData,
}
}
}
@ -82,7 +68,7 @@ where
S: 'static,
{
started: bool,
hnd: Rc<WithHnd<T, S, F, R>>,
hnd: Rc<F>,
cfg: Rc<T::Config>,
req: HttpRequest<S>,
fut1: Option<Box<Future<Item = T, Error = Error>>>,
@ -122,28 +108,19 @@ where
}
};
let fut = {
// clone handler, inicrease ref counter
let h = self.hnd.as_ref().hnd.clone();
// Enforce invariants before entering unsafe code.
// Only two references could exists With struct owns one, and line above
if Rc::weak_count(&h) != 0 || Rc::strong_count(&h) != 2 {
panic!("Multiple copies of handler are in use")
}
let hnd: &mut F = unsafe { &mut *h.as_ref().get() };
let item = match (*hnd)(item).respond_to(&self.req) {
Ok(item) => item.into(),
Err(e) => return Err(e.into()),
};
match item.into() {
AsyncResultItem::Err(err) => return Err(err),
AsyncResultItem::Ok(resp) => return Ok(Async::Ready(resp)),
AsyncResultItem::Future(fut) => fut,
}
let item = match (*self.hnd)(item).respond_to(&self.req) {
Ok(item) => item.into(),
Err(e) => return Err(e.into()),
};
self.fut2 = Some(fut);
self.poll()
match item.into() {
AsyncResultItem::Err(err) => Err(err),
AsyncResultItem::Ok(resp) => Ok(Async::Ready(resp)),
AsyncResultItem::Future(fut) => {
self.fut2 = Some(fut);
self.poll()
}
}
}
}
@ -156,8 +133,9 @@ where
T: FromRequest<S>,
S: 'static,
{
hnd: Rc<WithHnd<T, S, F, R>>,
hnd: Rc<F>,
cfg: Rc<T::Config>,
_s: PhantomData<S>,
}
impl<T, S, F, R, I, E> WithAsync<T, S, F, R, I, E>
@ -172,11 +150,8 @@ where
pub fn new(f: F, cfg: T::Config) -> Self {
WithAsync {
cfg: Rc::new(cfg),
hnd: Rc::new(WithHnd {
hnd: Rc::new(UnsafeCell::new(f)),
_s: PhantomData,
_t: PhantomData,
}),
hnd: Rc::new(f),
_s: PhantomData,
}
}
}
@ -221,7 +196,7 @@ where
S: 'static,
{
started: bool,
hnd: Rc<WithHnd<T, S, F, R>>,
hnd: Rc<F>,
cfg: Rc<T::Config>,
req: HttpRequest<S>,
fut1: Option<Box<Future<Item = T, Error = Error>>>,
@ -282,17 +257,7 @@ where
}
};
self.fut2 = {
// clone handler, inicrease ref counter
let h = self.hnd.as_ref().hnd.clone();
// Enforce invariants before entering unsafe code.
// Only two references could exists With struct owns one, and line above
if Rc::weak_count(&h) != 0 || Rc::strong_count(&h) != 2 {
panic!("Multiple copies of handler are in use")
}
let hnd: &mut F = unsafe { &mut *h.as_ref().get() };
Some((*hnd)(item))
};
self.fut2 = Some((*self.hnd)(item));
self.poll()
}
}