1
0
mirror of https://github.com/fafhrd91/actix-web synced 2025-03-20 22:35:17 +01:00

fix awc pool leak (#1626)

This commit is contained in:
fakeshadow 2020-08-10 04:49:43 +08:00 committed by GitHub
parent 187646b2f9
commit 160995b8d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 61 additions and 48 deletions

View File

@ -1,9 +1,13 @@
# Changes # Changes
## Unreleased - 2020-xx-xx ## Unreleased - 2020-xx-xx
### Fixed
* Memory leak of `client::pool::ConnectorPoolSupport`. [#1626]
[#1626]: https://github.com/actix/actix-web/pull/1626
## 2.0.0-beta.2 - 2020-07-21 ## [2.0.0-beta.2] - 2020-07-21
### Fixed ### Fixed
* Potential UB in h1 decoder using uninitialized memory. [#1614] * Potential UB in h1 decoder using uninitialized memory. [#1614]

View File

@ -2,7 +2,7 @@ use std::cell::RefCell;
use std::collections::VecDeque; use std::collections::VecDeque;
use std::future::Future; use std::future::Future;
use std::pin::Pin; use std::pin::Pin;
use std::rc::{Rc, Weak}; use std::rc::Rc;
use std::task::{Context, Poll}; use std::task::{Context, Poll};
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
@ -65,8 +65,8 @@ where
// start support future // start support future
actix_rt::spawn(ConnectorPoolSupport { actix_rt::spawn(ConnectorPoolSupport {
connector: connector_rc.clone(), connector: Rc::clone(&connector_rc),
inner: Rc::downgrade(&inner_rc), inner: Rc::clone(&inner_rc),
}); });
ConnectionPool(connector_rc, inner_rc) ConnectionPool(connector_rc, inner_rc)
@ -82,6 +82,13 @@ where
} }
} }
impl<T, Io> Drop for ConnectionPool<T, Io> {
fn drop(&mut self) {
// wake up the ConnectorPoolSupport when dropping so it can exit properly.
self.1.borrow().waker.wake();
}
}
impl<T, Io> Service for ConnectionPool<T, Io> impl<T, Io> Service for ConnectionPool<T, Io>
where where
Io: AsyncRead + AsyncWrite + Unpin + 'static, Io: AsyncRead + AsyncWrite + Unpin + 'static,
@ -421,7 +428,7 @@ where
Io: AsyncRead + AsyncWrite + Unpin + 'static, Io: AsyncRead + AsyncWrite + Unpin + 'static,
{ {
connector: T, connector: T,
inner: Weak<RefCell<Inner<Io>>>, inner: Rc<RefCell<Inner<Io>>>,
} }
impl<T, Io> Future for ConnectorPoolSupport<T, Io> impl<T, Io> Future for ConnectorPoolSupport<T, Io>
@ -435,8 +442,13 @@ where
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.project(); let this = self.project();
if let Some(this_inner) = this.inner.upgrade() { if Rc::strong_count(this.inner) == 1 {
let mut inner = this_inner.as_ref().borrow_mut(); // If we are last copy of Inner<Io> it means the ConnectionPool is already gone
// and we are safe to exit.
return Poll::Ready(());
}
let mut inner = this.inner.borrow_mut();
inner.waker.register(cx.waker()); inner.waker.register(cx.waker());
// check waiters // check waiters
@ -459,7 +471,7 @@ where
if let Err(conn) = tx.send(Ok(IoConnection::new( if let Err(conn) = tx.send(Ok(IoConnection::new(
io, io,
created, created,
Some(Acquired(key.clone(), Some(this_inner.clone()))), Some(Acquired(key.clone(), Some(this.inner.clone()))),
))) { ))) {
let (io, created) = conn.unwrap().into_inner(); let (io, created) = conn.unwrap().into_inner();
inner.release_conn(&key, io, created); inner.release_conn(&key, io, created);
@ -471,7 +483,7 @@ where
OpenWaitingConnection::spawn( OpenWaitingConnection::spawn(
key.clone(), key.clone(),
tx, tx,
this_inner.clone(), this.inner.clone(),
this.connector.call(connect), this.connector.call(connect),
inner.config.clone(), inner.config.clone(),
); );
@ -481,9 +493,6 @@ where
} }
Poll::Pending Poll::Pending
} else {
Poll::Ready(())
}
} }
} }