use crate::io_uring::IoUringData;
use crate::io_uring::IoUringTaskId;
use crate::io_uring::Task;
use crate::io_uring::sys::IORING_OP_ASYNC_CANCEL;
use crate::io_uring::sys::io_uring_cqe;
use crate::io_uring::sys::io_uring_sqe;
use crate::utils::errorfmt::ErrorFmt;
use uapi::c;
#[derive(Default)]
pub struct AsyncCancelTask {
id: IoUringTaskId,
target: IoUringTaskId,
}
impl IoUringData {
pub fn cancel_task_in_kernel(&self, target: IoUringTaskId) {
let id = self.id_raw();
let mut task = self.cached_cancels.pop().unwrap_or_default();
task.id = id;
task.target = target;
self.schedule(task);
}
}
unsafe impl Task for AsyncCancelTask {
fn id(&self) -> IoUringTaskId {
self.id
}
fn complete(self: Box<Self>, ring: &IoUringData, cqe: &io_uring_cqe) {
let res = cqe.res;
if let Err(e) = map_err!(res) {
if e.0 != c::ENOENT {
log::debug!("Could not cancel task: {}", ErrorFmt(e));
}
}
ring.cached_cancels.push(self);
}
fn encode(&self, sqe: &mut io_uring_sqe) {
sqe.opcode = IORING_OP_ASYNC_CANCEL;
sqe.u2.addr = self.target.raw();
}
fn is_cancel(&self) -> bool {
true
}
}