mirror of
https://github.com/fafhrd91/actix-web
synced 2025-03-20 14:25:18 +01:00
remove leaked box in REQUEST_POOL and RESPONSE_POOL (#1896)
This commit is contained in:
parent
6575ee93f2
commit
f6cc829758
@ -34,7 +34,9 @@ bitflags! {
|
|||||||
pub trait Head: Default + 'static {
|
pub trait Head: Default + 'static {
|
||||||
fn clear(&mut self);
|
fn clear(&mut self);
|
||||||
|
|
||||||
fn pool() -> &'static MessagePool<Self>;
|
fn with_pool<F, R>(f: F) -> R
|
||||||
|
where
|
||||||
|
F: FnOnce(&MessagePool<Self>) -> R;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -69,8 +71,11 @@ impl Head for RequestHead {
|
|||||||
self.extensions.get_mut().clear();
|
self.extensions.get_mut().clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pool() -> &'static MessagePool<Self> {
|
fn with_pool<F, R>(f: F) -> R
|
||||||
REQUEST_POOL.with(|p| *p)
|
where
|
||||||
|
F: FnOnce(&MessagePool<Self>) -> R,
|
||||||
|
{
|
||||||
|
REQUEST_POOL.with(|p| f(p))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -344,7 +349,7 @@ pub struct Message<T: Head> {
|
|||||||
impl<T: Head> Message<T> {
|
impl<T: Head> Message<T> {
|
||||||
/// Get new message from the pool of objects
|
/// Get new message from the pool of objects
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
T::pool().get_message()
|
T::with_pool(|p| p.get_message())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -373,7 +378,7 @@ impl<T: Head> std::ops::DerefMut for Message<T> {
|
|||||||
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.head) == 1 {
|
if Rc::strong_count(&self.head) == 1 {
|
||||||
T::pool().release(self.head.clone());
|
T::with_pool(|p| p.release(self.head.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -426,18 +431,17 @@ pub struct MessagePool<T: Head>(RefCell<Vec<Rc<T>>>);
|
|||||||
/// Request's objects pool
|
/// Request's objects pool
|
||||||
pub struct BoxedResponsePool(RefCell<Vec<Box<ResponseHead>>>);
|
pub struct BoxedResponsePool(RefCell<Vec<Box<ResponseHead>>>);
|
||||||
|
|
||||||
thread_local!(static REQUEST_POOL: &'static MessagePool<RequestHead> = MessagePool::<RequestHead>::create());
|
thread_local!(static REQUEST_POOL: MessagePool<RequestHead> = MessagePool::<RequestHead>::create());
|
||||||
thread_local!(static RESPONSE_POOL: &'static BoxedResponsePool = BoxedResponsePool::create());
|
thread_local!(static RESPONSE_POOL: BoxedResponsePool = BoxedResponsePool::create());
|
||||||
|
|
||||||
impl<T: Head> MessagePool<T> {
|
impl<T: Head> MessagePool<T> {
|
||||||
fn create() -> &'static MessagePool<T> {
|
fn create() -> MessagePool<T> {
|
||||||
let pool = MessagePool(RefCell::new(Vec::with_capacity(128)));
|
MessagePool(RefCell::new(Vec::with_capacity(128)))
|
||||||
Box::leak(Box::new(pool))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get message from the pool
|
/// Get message from the pool
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_message(&'static self) -> Message<T> {
|
fn get_message(&self) -> Message<T> {
|
||||||
if let Some(mut msg) = self.0.borrow_mut().pop() {
|
if let Some(mut msg) = self.0.borrow_mut().pop() {
|
||||||
// Message is put in pool only when it's the last copy.
|
// Message is put in pool only when it's the last copy.
|
||||||
// which means it's guaranteed to be unique when popped out.
|
// which means it's guaranteed to be unique when popped out.
|
||||||
@ -463,14 +467,13 @@ impl<T: Head> MessagePool<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl BoxedResponsePool {
|
impl BoxedResponsePool {
|
||||||
fn create() -> &'static BoxedResponsePool {
|
fn create() -> BoxedResponsePool {
|
||||||
let pool = BoxedResponsePool(RefCell::new(Vec::with_capacity(128)));
|
BoxedResponsePool(RefCell::new(Vec::with_capacity(128)))
|
||||||
Box::leak(Box::new(pool))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get message from the pool
|
/// Get message from the pool
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_message(&'static self, status: StatusCode) -> BoxedResponseHead {
|
fn get_message(&self, status: StatusCode) -> BoxedResponseHead {
|
||||||
if let Some(mut head) = self.0.borrow_mut().pop() {
|
if let Some(mut head) = self.0.borrow_mut().pop() {
|
||||||
head.reason = None;
|
head.reason = None;
|
||||||
head.status = status;
|
head.status = status;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user