1
0
mirror of https://github.com/actix/actix-extras.git synced 2024-11-30 18:34:36 +01:00

simplify Message type

This commit is contained in:
Nikolay Kim 2019-02-09 10:33:49 -08:00
parent f3ed1b601e
commit 6a343fae06

View File

@ -45,6 +45,7 @@ pub struct RequestHead {
pub version: Version, pub version: Version,
pub headers: HeaderMap, pub headers: HeaderMap,
pub ctype: Option<ConnectionType>, pub ctype: Option<ConnectionType>,
pub extensions: RefCell<Extensions>,
} }
impl Default for RequestHead { impl Default for RequestHead {
@ -55,6 +56,7 @@ impl Default for RequestHead {
version: Version::HTTP_11, version: Version::HTTP_11,
headers: HeaderMap::with_capacity(16), headers: HeaderMap::with_capacity(16),
ctype: None, ctype: None,
extensions: RefCell::new(Extensions::new()),
} }
} }
} }
@ -63,6 +65,7 @@ impl Head for RequestHead {
fn clear(&mut self) { fn clear(&mut self) {
self.ctype = None; self.ctype = None;
self.headers.clear(); self.headers.clear();
self.extensions.borrow_mut().clear();
} }
fn set_connection_type(&mut self, ctype: ConnectionType) { fn set_connection_type(&mut self, ctype: ConnectionType) {
@ -84,6 +87,20 @@ impl Head for RequestHead {
} }
} }
impl RequestHead {
/// Message extensions
#[inline]
pub fn extensions(&self) -> Ref<Extensions> {
self.extensions.borrow()
}
/// Mutable reference to a the message's extensions
#[inline]
pub fn extensions_mut(&self) -> RefMut<Extensions> {
self.extensions.borrow_mut()
}
}
#[derive(Debug)] #[derive(Debug)]
pub struct ResponseHead { pub struct ResponseHead {
pub version: Version, pub version: Version,
@ -146,7 +163,7 @@ impl ResponseHead {
} }
pub struct Message<T: Head> { pub struct Message<T: Head> {
inner: Rc<MessageInner<T>>, head: Rc<T>,
pool: &'static MessagePool<T>, pool: &'static MessagePool<T>,
} }
@ -155,24 +172,12 @@ impl<T: Head> Message<T> {
pub fn new() -> Self { pub fn new() -> Self {
T::pool().get_message() T::pool().get_message()
} }
/// Message extensions
#[inline]
pub fn extensions(&self) -> Ref<Extensions> {
self.inner.as_ref().extensions.borrow()
}
/// Mutable reference to a the message's extensions
#[inline]
pub fn extensions_mut(&self) -> RefMut<Extensions> {
self.inner.as_ref().extensions.borrow_mut()
}
} }
impl<T: Head> Clone for Message<T> { impl<T: Head> Clone for Message<T> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
Message { Message {
inner: self.inner.clone(), head: self.head.clone(),
pool: self.pool, pool: self.pool,
} }
} }
@ -182,52 +187,27 @@ impl<T: Head> std::ops::Deref for Message<T> {
type Target = T; type Target = T;
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
&self.inner.as_ref().head &self.head.as_ref()
} }
} }
impl<T: Head> std::ops::DerefMut for Message<T> { impl<T: Head> std::ops::DerefMut for Message<T> {
fn deref_mut(&mut self) -> &mut Self::Target { fn deref_mut(&mut self) -> &mut Self::Target {
&mut Rc::get_mut(&mut self.inner) Rc::get_mut(&mut self.head).expect("Multiple copies exist")
.expect("Multiple copies exist")
.head
} }
} }
impl<T: Head> Drop for Message<T> { impl<T: Head> Drop for Message<T> {
fn drop(&mut self) { fn drop(&mut self) {
if Rc::strong_count(&self.inner) == 1 { if Rc::strong_count(&self.head) == 1 {
self.pool.release(self.inner.clone()); self.pool.release(self.head.clone());
}
}
}
struct MessageInner<T: Head> {
head: T,
extensions: RefCell<Extensions>,
}
impl<T: Head> MessageInner<T> {
#[inline]
/// Reset request instance
pub fn reset(&mut self) {
self.head.clear();
self.extensions.borrow_mut().clear();
}
}
impl<T: Head> Default for MessageInner<T> {
fn default() -> Self {
MessageInner {
head: T::default(),
extensions: RefCell::new(Extensions::new()),
} }
} }
} }
#[doc(hidden)] #[doc(hidden)]
/// Request's objects pool /// Request's objects pool
pub struct MessagePool<T: Head>(RefCell<VecDeque<Rc<MessageInner<T>>>>); pub struct MessagePool<T: Head>(RefCell<VecDeque<Rc<T>>>);
thread_local!(static REQUEST_POOL: &'static MessagePool<RequestHead> = MessagePool::<RequestHead>::create()); thread_local!(static REQUEST_POOL: &'static MessagePool<RequestHead> = MessagePool::<RequestHead>::create());
thread_local!(static RESPONSE_POOL: &'static MessagePool<ResponseHead> = MessagePool::<ResponseHead>::create()); thread_local!(static RESPONSE_POOL: &'static MessagePool<ResponseHead> = MessagePool::<ResponseHead>::create());
@ -243,15 +223,15 @@ impl<T: Head> MessagePool<T> {
fn get_message(&'static self) -> Message<T> { fn get_message(&'static self) -> Message<T> {
if let Some(mut msg) = self.0.borrow_mut().pop_front() { if let Some(mut msg) = self.0.borrow_mut().pop_front() {
if let Some(r) = Rc::get_mut(&mut msg) { if let Some(r) = Rc::get_mut(&mut msg) {
r.reset(); r.clear();
} }
Message { Message {
inner: msg, head: msg,
pool: self, pool: self,
} }
} else { } else {
Message { Message {
inner: Rc::new(MessageInner::default()), head: Rc::new(T::default()),
pool: self, pool: self,
} }
} }
@ -259,7 +239,7 @@ impl<T: Head> MessagePool<T> {
#[inline] #[inline]
/// Release request instance /// Release request instance
fn release(&self, msg: Rc<MessageInner<T>>) { fn release(&self, msg: Rc<T>) {
let v = &mut self.0.borrow_mut(); let v = &mut self.0.borrow_mut();
if v.len() < 128 { if v.len() < 128 {
v.push_front(msg); v.push_front(msg);