More cleanup
This commit is contained in:
@@ -99,7 +99,7 @@ pub struct Driver {
|
||||
pending_wakes: Cell<u64>,
|
||||
pending_timers: Cell<u64>,
|
||||
next_fd_token: Cell<u64>,
|
||||
fd_waiters: RefCell<HashMap<FdKey, Vec<FdWaiter>>>,
|
||||
fd_waiters: RefCell<HashMap<FdKey, FdWaiter>>,
|
||||
}
|
||||
|
||||
/// Creates a new driver and its paired [`ThreadNotifier`].
|
||||
@@ -241,17 +241,31 @@ impl Driver {
|
||||
completion: FdCompletion,
|
||||
) -> io::Result<FdReadinessToken> {
|
||||
let key = FdKey { fd, interest };
|
||||
let should_register = !self.fd_waiters.borrow().contains_key(&key);
|
||||
if should_register {
|
||||
self.update_fd_interest(key, libc::EV_ADD | libc::EV_ENABLE)?;
|
||||
let removed_stale_waiter = {
|
||||
let mut waiters = self.fd_waiters.borrow_mut();
|
||||
match waiters.get(&key) {
|
||||
Some(waiter) if !waiter.completion.is_interested() => {
|
||||
waiters.remove(&key);
|
||||
true
|
||||
}
|
||||
Some(_) => {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::AlreadyExists,
|
||||
"fd readiness already has a waiter for this interest",
|
||||
));
|
||||
}
|
||||
None => false,
|
||||
}
|
||||
};
|
||||
if removed_stale_waiter {
|
||||
let _ = self.update_fd_interest(key, libc::EV_DELETE);
|
||||
}
|
||||
|
||||
let token = self.allocate_fd_token();
|
||||
self.update_fd_interest(key, libc::EV_ADD | libc::EV_ENABLE | libc::EV_ONESHOT)?;
|
||||
self.fd_waiters
|
||||
.borrow_mut()
|
||||
.entry(key)
|
||||
.or_default()
|
||||
.push(FdWaiter { token, completion });
|
||||
.insert(key, FdWaiter { token, completion });
|
||||
Ok(token)
|
||||
}
|
||||
|
||||
@@ -259,12 +273,9 @@ impl Driver {
|
||||
let mut empty_key = None;
|
||||
{
|
||||
let mut waiters = self.fd_waiters.borrow_mut();
|
||||
for (key, entries) in waiters.iter_mut() {
|
||||
if let Some(index) = entries.iter().position(|entry| entry.token == token) {
|
||||
entries.swap_remove(index);
|
||||
if entries.is_empty() {
|
||||
empty_key = Some(*key);
|
||||
}
|
||||
for (key, entry) in waiters.iter() {
|
||||
if entry.token == token {
|
||||
empty_key = Some(*key);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -372,19 +383,13 @@ impl Driver {
|
||||
|
||||
fn complete_fd_waiters(&self, fd: RawFd, interest: FdInterest, event: &libc::kevent) {
|
||||
let key = FdKey { fd, interest };
|
||||
let waiters = self.fd_waiters.borrow_mut().remove(&key);
|
||||
let Some(waiters) = waiters else {
|
||||
let waiter = self.fd_waiters.borrow_mut().remove(&key);
|
||||
let Some(waiter) = waiter else {
|
||||
return;
|
||||
};
|
||||
|
||||
let _ = self.update_fd_interest(key, libc::EV_DELETE);
|
||||
let result = fd_event_result(event);
|
||||
for waiter in waiters {
|
||||
waiter.completion.complete(match &result {
|
||||
Ok(()) => Ok(()),
|
||||
Err(error) => Err(io::Error::new(error.kind(), error.to_string())),
|
||||
});
|
||||
}
|
||||
let result = fd_event_result(event, interest);
|
||||
waiter.completion.complete(result);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -436,9 +441,14 @@ fn interest_from_filter(filter: i16) -> Option<FdInterest> {
|
||||
}
|
||||
}
|
||||
|
||||
fn fd_event_result(event: &libc::kevent) -> io::Result<()> {
|
||||
fn fd_event_result(event: &libc::kevent, interest: FdInterest) -> io::Result<()> {
|
||||
if event.flags & libc::EV_ERROR != 0 && event.data != 0 {
|
||||
Err(io::Error::from_raw_os_error(event.data as i32))
|
||||
} else if event.flags & libc::EV_EOF != 0 && interest == FdInterest::Writable {
|
||||
Err(io::Error::new(
|
||||
io::ErrorKind::BrokenPipe,
|
||||
"fd write side reached EOF",
|
||||
))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user