diff --git a/src/route.rs b/src/route.rs index 80fb17d7c..fed4deb56 100644 --- a/src/route.rs +++ b/src/route.rs @@ -1,4 +1,3 @@ -use std::cell::UnsafeCell; use std::marker::PhantomData; use std::rc::Rc; @@ -297,12 +296,12 @@ impl Route { /// `RouteHandler` wrapper. This struct is required because it needs to be /// shared for resource level middlewares. -struct InnerHandler(Rc>>>); +struct InnerHandler(Rc>>); impl InnerHandler { #[inline] fn new>(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 InnerHandler { R: Responder + 'static, E: Into + '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) -> AsyncResult { - // 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) } } diff --git a/src/scope.rs b/src/scope.rs index a56d753b6..c9e7dfb93 100644 --- a/src/scope.rs +++ b/src/scope.rs @@ -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 = Rc>; -type Route = UnsafeCell>>; +type Route = Box>; type ScopeResources = Rc)>>; type NestedInfo = (Resource, Route, Vec>>); @@ -145,7 +144,7 @@ impl Scope { 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 Scope { 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 RouteHandler for Scope { 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); } } diff --git a/src/test.rs b/src/test.rs index 58790f6d4..b7ed4e79d 100644 --- a/src/test.rs +++ b/src/test.rs @@ -394,11 +394,11 @@ impl Iterator for TestApp { /// /// 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); /// } /// ``` diff --git a/src/with.rs b/src/with.rs index ac220958b..c475ca011 100644 --- a/src/with.rs +++ b/src/with.rs @@ -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: 'static, { - hnd: Rc>, + hnd: Rc, cfg: Rc, -} - -pub struct WithHnd -where - F: Fn(T) -> R, - T: FromRequest, - S: 'static, -{ - hnd: Rc>, - _t: PhantomData, _s: PhantomData, } @@ -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>, + hnd: Rc, cfg: Rc, req: HttpRequest, fut1: Option>>, @@ -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: 'static, { - hnd: Rc>, + hnd: Rc, cfg: Rc, + _s: PhantomData, } impl WithAsync @@ -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>, + hnd: Rc, cfg: Rc, req: HttpRequest, fut1: Option>>, @@ -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() } }