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:
parent
65ca563579
commit
c9069e9a3c
4 changed files with 33 additions and 78 deletions
11
src/route.rs
11
src/route.rs
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
17
src/scope.rs
17
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<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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
/// }
|
||||
/// ```
|
||||
|
|
79
src/with.rs
79
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>,
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue