Skip to content

Commit 5132430

Browse files
authored
fix(poll): cancel in the fd queue (#346)
* fix(poll): cancel in the fd queue * fix(poll): use retain instead of position - remove * fix(poll): make renew safe
1 parent c248bf6 commit 5132430

File tree

1 file changed

+70
-34
lines changed

1 file changed

+70
-34
lines changed

compio-driver/src/poll/mod.rs

Lines changed: 70 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ pub use std::os::fd::{AsRawFd, OwnedFd, RawFd};
44
#[cfg(aio)]
55
use std::ptr::NonNull;
66
use std::{
7-
collections::{HashMap, HashSet, VecDeque},
7+
collections::{HashMap, VecDeque},
88
io,
99
num::NonZeroUsize,
1010
os::fd::BorrowedFd,
@@ -123,6 +123,11 @@ impl FdQueue {
123123
}
124124
}
125125

126+
pub fn remove(&mut self, user_data: usize) {
127+
self.read_queue.retain(|&k| k != user_data);
128+
self.write_queue.retain(|&k| k != user_data);
129+
}
130+
126131
pub fn event(&self) -> Event {
127132
let mut event = Event::none(0);
128133
if let Some(&key) = self.read_queue.front() {
@@ -167,7 +172,6 @@ pub(crate) struct Driver {
167172
events: Events,
168173
poll: Arc<Poller>,
169174
registry: HashMap<RawFd, FdQueue>,
170-
cancelled: HashSet<usize>,
171175
pool: AsyncifyPool,
172176
pool_completed: Arc<SegQueue<Entry>>,
173177
}
@@ -189,7 +193,6 @@ impl Driver {
189193
events,
190194
poll,
191195
registry: HashMap::new(),
192-
cancelled: HashSet::new(),
193196
pool: builder.create_or_get_thread_pool(),
194197
pool_completed: Arc::new(SegQueue::new()),
195198
})
@@ -215,16 +218,49 @@ impl Driver {
215218
Ok(())
216219
}
217220

221+
fn renew(
222+
poll: &Poller,
223+
registry: &mut HashMap<RawFd, FdQueue>,
224+
fd: BorrowedFd,
225+
renew_event: Event,
226+
) -> io::Result<()> {
227+
if !renew_event.readable && !renew_event.writable {
228+
poll.delete(fd)?;
229+
registry.remove(&fd.as_raw_fd());
230+
} else {
231+
poll.modify(fd, renew_event)?;
232+
}
233+
Ok(())
234+
}
235+
218236
pub fn attach(&mut self, _fd: RawFd) -> io::Result<()> {
219237
Ok(())
220238
}
221239

222240
pub fn cancel(&mut self, op: &mut Key<dyn crate::sys::OpCode>) {
223-
self.cancelled.insert(op.user_data());
224-
#[cfg(aio)]
225-
{
226-
let op = op.as_op_pin();
227-
if let Some(OpType::Aio(aiocbp)) = op.op_type() {
241+
let op_pin = op.as_op_pin();
242+
match op_pin.op_type() {
243+
None => {}
244+
Some(OpType::Fd(fd)) => {
245+
let queue = self
246+
.registry
247+
.get_mut(&fd)
248+
.expect("the fd should be attached");
249+
queue.remove(op.user_data());
250+
let renew_event = queue.event();
251+
if Self::renew(
252+
&self.poll,
253+
&mut self.registry,
254+
unsafe { BorrowedFd::borrow_raw(fd) },
255+
renew_event,
256+
)
257+
.is_ok()
258+
{
259+
self.pool_completed.push(entry_cancelled(op.user_data()));
260+
}
261+
}
262+
#[cfg(aio)]
263+
Some(OpType::Aio(aiocbp)) => {
228264
let aiocb = unsafe { aiocbp.as_ref() };
229265
let fd = aiocb.aio_fildes;
230266
syscall!(libc::aio_cancel(fd, aiocbp.as_ptr())).ok();
@@ -314,21 +350,27 @@ impl Driver {
314350
}
315351
}
316352

317-
fn poll_blocking(&mut self) {
353+
fn poll_blocking(&mut self) -> bool {
354+
if self.pool_completed.is_empty() {
355+
return false;
356+
}
318357
while let Some(entry) = self.pool_completed.pop() {
319358
unsafe {
320359
entry.notify();
321360
}
322361
}
362+
true
323363
}
324364

325365
pub unsafe fn poll(&mut self, timeout: Option<Duration>) -> io::Result<()> {
326366
instrument!(compio_log::Level::TRACE, "poll", ?timeout);
367+
if self.poll_blocking() {
368+
return Ok(());
369+
}
327370
self.poll.wait(&mut self.events, timeout)?;
328-
if self.events.is_empty() && self.pool_completed.is_empty() && timeout.is_some() {
371+
if self.events.is_empty() && timeout.is_some() {
329372
return Err(io::Error::from_raw_os_error(libc::ETIMEDOUT));
330373
}
331-
self.poll_blocking();
332374
for event in self.events.iter() {
333375
let user_data = event.key;
334376
trace!("receive {} for {:?}", user_data, event);
@@ -348,32 +390,27 @@ impl Driver {
348390
.get_mut(&fd)
349391
.expect("the fd should be attached");
350392
if let Some((user_data, interest)) = queue.pop_interest(&event) {
351-
if self.cancelled.remove(&user_data) {
352-
entry_cancelled(user_data).notify();
353-
} else {
354-
let mut op = Key::<dyn crate::sys::OpCode>::new_unchecked(user_data);
355-
let op = op.as_op_pin();
356-
let res = match op.operate() {
357-
Poll::Pending => {
358-
// The operation should go back to the front.
359-
queue.push_front_interest(user_data, interest);
360-
None
361-
}
362-
Poll::Ready(res) => Some(res),
363-
};
364-
if let Some(res) = res {
365-
Entry::new(user_data, res).notify();
393+
let mut op = Key::<dyn crate::sys::OpCode>::new_unchecked(user_data);
394+
let op = op.as_op_pin();
395+
let res = match op.operate() {
396+
Poll::Pending => {
397+
// The operation should go back to the front.
398+
queue.push_front_interest(user_data, interest);
399+
None
366400
}
401+
Poll::Ready(res) => Some(res),
402+
};
403+
if let Some(res) = res {
404+
Entry::new(user_data, res).notify();
367405
}
368406
}
369407
let renew_event = queue.event();
370-
let borrowed_fd = BorrowedFd::borrow_raw(fd);
371-
if !renew_event.readable && !renew_event.writable {
372-
self.poll.delete(borrowed_fd)?;
373-
self.registry.remove(&fd);
374-
} else {
375-
self.poll.modify(borrowed_fd, renew_event)?;
376-
}
408+
Self::renew(
409+
&self.poll,
410+
&mut self.registry,
411+
BorrowedFd::borrow_raw(fd),
412+
renew_event,
413+
)?;
377414
}
378415
#[cfg(aio)]
379416
Some(OpType::Aio(aiocbp)) => {
@@ -388,7 +425,6 @@ impl Driver {
388425
continue;
389426
}
390427
libc::ECANCELED => {
391-
self.cancelled.remove(&user_data);
392428
// Remove the aiocb from kqueue.
393429
libc::aio_return(aiocbp.as_ptr());
394430
Err(io::Error::from_raw_os_error(libc::ETIMEDOUT))

0 commit comments

Comments
 (0)