Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce allocations in poll(2) implementation #1705

Closed
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Reuse alloction for closed_raw_fds in poll(2) Selector
Thomasdezeeuw committed Aug 4, 2023

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
commit 02c5a2a23d0751d31a597fe4c1b882a499a0e462
29 changes: 19 additions & 10 deletions src/sys/unix/selector/poll.rs
Original file line number Diff line number Diff line change
@@ -25,6 +25,8 @@ pub struct Selector {
/// Whether this selector currently has an associated waker.
#[cfg(debug_assertions)]
has_waker: AtomicBool,
/// Buffer used in [`SelectorState::select`].
fd_bufs: Vec<RawFd>,
}

impl Selector {
@@ -35,6 +37,7 @@ impl Selector {
state: Arc::new(state),
#[cfg(debug_assertions)]
has_waker: AtomicBool::new(false),
fd_bufs: Vec::new(),
})
}

@@ -48,11 +51,12 @@ impl Selector {
state,
#[cfg(debug_assertions)]
has_waker: AtomicBool::new(self.has_waker.load(Ordering::Acquire)),
fd_bufs: Vec::new(),
})
}

pub fn select(&self, events: &mut Events, timeout: Option<Duration>) -> io::Result<()> {
self.state.select(events, timeout)
pub fn select(&mut self, events: &mut Events, timeout: Option<Duration>) -> io::Result<()> {
self.state.select(events, timeout, &mut self.fd_bufs)
}

pub fn register(&self, fd: RawFd, token: Token, interests: Interest) -> io::Result<()> {
@@ -194,17 +198,17 @@ impl SelectorState {
})
}

pub fn select(&self, events: &mut Events, timeout: Option<Duration>) -> io::Result<()> {
pub fn select(
&self,
events: &mut Events,
timeout: Option<Duration>,
closed_raw_fds: &mut Vec<RawFd>,
) -> io::Result<()> {
events.clear();
closed_raw_fds.clear();

let mut fds = self.fds.lock().unwrap();

// Keep track of fds that receive POLLHUP or POLLERR (i.e. won't receive further
// events) and internally deregister them before they are externally deregister'd. See
// IoSourceState below to track how the external deregister call will be handled
// when this state occurs.
let mut closed_raw_fds = Vec::new();

loop {
// Complete all current operations.
loop {
@@ -272,6 +276,12 @@ impl SelectorState {
events: poll_fd.revents,
});

// Keep track of fds that receive POLLHUP or POLLERR
// (i.e. won't receive further events) and internally
// deregister them before they are externally
// deregistered. See IoSourceState below to track how
// the external deregister call will be handled when
// this state occurs.
if poll_fd.revents & (libc::POLLHUP | libc::POLLERR) != 0 {
pending_removal.push(poll_fd.fd);
closed_raw_fds.push(poll_fd.fd);
@@ -299,7 +309,6 @@ impl SelectorState {

drop(fds);
let _ = self.deregister_all(&closed_raw_fds);

Ok(())
}