diff --git a/actix-http/src/cloneable.rs b/actix-http/src/cloneable.rs index 65c6bec21..c1dbfa430 100644 --- a/actix-http/src/cloneable.rs +++ b/actix-http/src/cloneable.rs @@ -1,4 +1,4 @@ -use std::cell::UnsafeCell; +use std::cell::RefCell; use std::rc::Rc; use std::task::{Context, Poll}; @@ -6,11 +6,15 @@ use actix_service::Service; #[doc(hidden)] /// Service that allows to turn non-clone service to a service with `Clone` impl -pub(crate) struct CloneableService(Rc>); +/// +/// # Panics +/// CloneableService might panic with some creative use of thread local storage. +/// See https://github.com/actix/actix-web/issues/1295 for example +pub(crate) struct CloneableService(Rc>); impl CloneableService { pub(crate) fn new(service: T) -> Self { - Self(Rc::new(UnsafeCell::new(service))) + Self(Rc::new(RefCell::new(service))) } } @@ -27,10 +31,10 @@ impl Service for CloneableService { type Future = T::Future; fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { - unsafe { &mut *self.0.as_ref().get() }.poll_ready(cx) + self.0.borrow_mut().poll_ready(cx) } fn call(&mut self, req: T::Request) -> Self::Future { - unsafe { &mut *self.0.as_ref().get() }.call(req) + self.0.borrow_mut().call(req) } }