Skip to content

Commit

Permalink
Fix leaked sock states (#1154)
Browse files Browse the repository at this point in the history
A reference of the sock state Arc is blocked by a pending AFD poll
request, this reference will leak if there's no explicit poll done
before the program terminates. That's why doing an explicit "select"
during inner selector drop ensures all sock state references are freed.

Fixes: #1146

Signed-off-by: Daniel Tacalau <dst4096@gmail.com>
  • Loading branch information
dtacalau authored and Thomasdezeeuw committed Nov 28, 2019
1 parent 5554b23 commit 2b68a4b
Showing 1 changed file with 35 additions and 0 deletions.
35 changes: 35 additions & 0 deletions src/sys/windows/selector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,41 @@ pub struct SelectorInner {
// We have ensured thread safety by introducing lock manually.
unsafe impl Sync for SelectorInner {}

impl Drop for SelectorInner {
fn drop(&mut self) {
loop {
let events_num: usize;
let mut statuses: [CompletionStatus; 1024] = [CompletionStatus::zero(); 1024];

let result = self
.cp
.get_many(&mut statuses, Some(std::time::Duration::from_millis(0)));
match result {
Ok(iocp_events) => {
events_num = iocp_events.iter().len();
for iocp_event in iocp_events.iter() {
if !iocp_event.overlapped().is_null() {
// drain sock state to release memory of Arc reference
let _sock_state = from_overlapped(iocp_event.overlapped());
}
}
}

Err(_) => {
break;
}
}

if events_num < 1024 {
// continue looping until all completion statuses have been drained
break;
}
}

self.afd_group.release_unused_afd();
}
}

impl SelectorInner {
pub fn new() -> io::Result<SelectorInner> {
CompletionPort::new(0).map(|cp| {
Expand Down

0 comments on commit 2b68a4b

Please sign in to comment.