fix dealloc issues
This commit is contained in:
27
src/pool.rs
27
src/pool.rs
@@ -89,19 +89,18 @@ impl<R: Read + Sized> PoolReturnRead<R> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let state = &mut unit.agent.lock().unwrap();
|
let state = &mut unit.agent.lock().unwrap();
|
||||||
|
// bring back stream here to either go into pool or dealloc
|
||||||
|
let stream = unsafe { *Box::from_raw(self.stream) };
|
||||||
|
self.stream = ::std::ptr::null_mut();
|
||||||
if let Some(agent) = state.as_mut() {
|
if let Some(agent) = state.as_mut() {
|
||||||
unsafe {
|
if !stream.is_poolable() {
|
||||||
let stream = *Box::from_raw(self.stream);
|
// just let it deallocate
|
||||||
self.stream = ::std::ptr::null_mut();
|
return;
|
||||||
if !stream.is_poolable() {
|
|
||||||
// just let it deallocate
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// insert back into pool
|
|
||||||
let key = PoolKey::new(&unit.url);
|
|
||||||
agent.pool().recycle.insert(key, stream);
|
|
||||||
}
|
}
|
||||||
};
|
// insert back into pool
|
||||||
|
let key = PoolKey::new(&unit.url);
|
||||||
|
agent.pool().recycle.insert(key, stream);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,3 +123,9 @@ impl<R: Read + Sized> Read for PoolReturnRead<R> {
|
|||||||
Ok(amount)
|
Ok(amount)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<R: Read + Sized> Drop for PoolReturnRead<R> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
self.return_connection();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -276,7 +276,7 @@ impl Response {
|
|||||||
|
|
||||||
let stream = Box::new(self.stream.expect("No reader in response?!"));
|
let stream = Box::new(self.stream.expect("No reader in response?!"));
|
||||||
let stream_ptr = Box::into_raw(stream);
|
let stream_ptr = Box::into_raw(stream);
|
||||||
let yolo = YoloRead { stream: stream_ptr };
|
let mut yolo = YoloRead { stream: stream_ptr, dealloc: false };
|
||||||
let unit = self.unit;
|
let unit = self.unit;
|
||||||
|
|
||||||
match (use_chunked, limit_bytes) {
|
match (use_chunked, limit_bytes) {
|
||||||
@@ -290,7 +290,10 @@ impl Response {
|
|||||||
stream_ptr,
|
stream_ptr,
|
||||||
LimitedRead::new(yolo, len),
|
LimitedRead::new(yolo, len),
|
||||||
)),
|
)),
|
||||||
(false, None) => Box::new(yolo),
|
(false, None) => {
|
||||||
|
yolo.dealloc = true; // dealloc when read drops.
|
||||||
|
Box::new(yolo)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -521,6 +524,7 @@ fn read_next_line<R: Read>(reader: &mut R) -> IoResult<AsciiString> {
|
|||||||
/// *Internal API*
|
/// *Internal API*
|
||||||
struct YoloRead {
|
struct YoloRead {
|
||||||
stream: *mut Stream,
|
stream: *mut Stream,
|
||||||
|
dealloc: bool, // whether we are to dealloc stream on drop
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Read for YoloRead {
|
impl Read for YoloRead {
|
||||||
@@ -531,6 +535,9 @@ impl Read for YoloRead {
|
|||||||
}
|
}
|
||||||
let amount = (*self.stream).read(buf)?;
|
let amount = (*self.stream).read(buf)?;
|
||||||
if amount == 0 {
|
if amount == 0 {
|
||||||
|
if self.dealloc {
|
||||||
|
let _stream = Box::from_raw(self.stream);
|
||||||
|
}
|
||||||
self.stream = ::std::ptr::null_mut();
|
self.stream = ::std::ptr::null_mut();
|
||||||
}
|
}
|
||||||
Ok(amount)
|
Ok(amount)
|
||||||
@@ -538,6 +545,16 @@ impl Read for YoloRead {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Drop for YoloRead {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
if self.dealloc && !self.stream.is_null() {
|
||||||
|
unsafe {
|
||||||
|
let _stream = Box::from_raw(self.stream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Limits a YoloRead to a content size (as set by a "Content-Length" header).
|
/// Limits a YoloRead to a content size (as set by a "Content-Length" header).
|
||||||
///
|
///
|
||||||
/// *Internal API*
|
/// *Internal API*
|
||||||
|
|||||||
@@ -18,16 +18,6 @@ pub enum Stream {
|
|||||||
Test(Box<dyn Read + Send>, Vec<u8>),
|
Test(Box<dyn Read + Send>, Vec<u8>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for Stream {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
match self {
|
|
||||||
#[cfg(feature = "tls")]
|
|
||||||
Stream::Https(s) => { s.shutdown().ok(); },
|
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ::std::fmt::Debug for Stream {
|
impl ::std::fmt::Debug for Stream {
|
||||||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::result::Result<(), ::std::fmt::Error> {
|
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::result::Result<(), ::std::fmt::Error> {
|
||||||
write!(
|
write!(
|
||||||
|
|||||||
Reference in New Issue
Block a user