Skip to content

Commit

Permalink
fix(poll): simplify push_blocking loop
Browse files Browse the repository at this point in the history
  • Loading branch information
Berrysoft committed Nov 21, 2024
1 parent 62d0ec1 commit 0a16c93
Showing 1 changed file with 29 additions and 27 deletions.
56 changes: 29 additions & 27 deletions compio-driver/src/poll/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,13 +244,7 @@ impl Driver {
Poll::Pending
}
Decision::Completed(res) => Poll::Ready(Ok(res)),
Decision::Blocking => loop {
if self.push_blocking(user_data) {
break Poll::Pending;
} else {
self.poll_blocking();
}
},
Decision::Blocking => self.push_blocking(user_data),
#[cfg(aio)]
Decision::Aio(AioControl { mut aiocbp, submit }) => {
let aiocb = unsafe { aiocbp.as_mut() };
Expand All @@ -273,41 +267,49 @@ impl Driver {
}
match syscall!(submit(aiocbp.as_ptr())) {
Ok(_) => Poll::Pending,
// FreeBSD:
// * EOPNOTSUPP: It's on a filesystem without AIO support. Just fallback to
// blocking IO.
// * EAGAIN: The process-wide queue is full. No safe way to remove the (maybe)
// dead entries.
// Solarish:
// * EAGAIN: Allocation failed.
Err(e)
if matches!(
e.raw_os_error(),
Some(libc::EOPNOTSUPP) | Some(libc::EAGAIN)
) =>
{
loop {
if self.push_blocking(user_data) {
return Poll::Pending;
} else {
self.poll_blocking();
}
}
self.push_blocking(user_data)
}
Err(e) => Poll::Ready(Err(e)),
}
}
}
}

fn push_blocking(&mut self, user_data: usize) -> bool {
fn push_blocking(&mut self, user_data: usize) -> Poll<io::Result<usize>> {
let poll = self.poll.clone();
let completed = self.pool_completed.clone();
self.pool
.dispatch(move || {
let mut op = unsafe { Key::<dyn crate::sys::OpCode>::new_unchecked(user_data) };
let op_pin = op.as_op_pin();
let res = match op_pin.operate() {
Poll::Pending => unreachable!("this operation is not non-blocking"),
Poll::Ready(res) => res,
};
completed.push(Entry::new(user_data, res));
poll.notify().ok();
})
.is_ok()
let mut closure = move || {
let mut op = unsafe { Key::<dyn crate::sys::OpCode>::new_unchecked(user_data) };
let op_pin = op.as_op_pin();
let res = match op_pin.operate() {
Poll::Pending => unreachable!("this operation is not non-blocking"),
Poll::Ready(res) => res,
};
completed.push(Entry::new(user_data, res));
poll.notify().ok();
};
loop {
match self.pool.dispatch(closure) {
Ok(()) => return Poll::Pending,
Err(e) => {
closure = e.0;
self.poll_blocking();
}
}
}
}

fn poll_blocking(&mut self) {
Expand Down

0 comments on commit 0a16c93

Please sign in to comment.