io_uring: add sqe prep methods for epoll_ctl, poll_add, and poll_remove

Implement io_uring submission queue entry preparation methods for
epoll_ctl, poll_add and poll_remove.

Poll masks are designated as 32-bit little-endian integers as
specified in liburing's definitions.

Updated io_uring_prep_rw to take in an unsigned 64-bit address instead
of an anytype. io_uring_sqe by default assumes that the address
specified in a submission queue entry is an unsigned 64-bit integer.
This commit is contained in:
Kenta Iwasaki
2021-07-09 07:10:10 +09:00
committed by Isaac Freund
parent 75d1b113aa
commit aa2a31612f

View File

@@ -457,6 +457,22 @@ pub const IO_Uring = struct {
return sqe;
}
/// Queues (but does not submit) an SQE to perform a `epoll_ctl(2)`.
/// Returns a pointer to the SQE.
pub fn epoll_ctl(
self: *IO_Uring,
user_data: u64,
epfd: os.fd_t,
fd: os.fd_t,
op: u32,
ev: ?*linux.epoll_event,
) !*io_uring_sqe {
const sqe = try self.get_sqe();
io_uring_prep_epoll_ctl(sqe, epfd, fd, op, ev);
sqe.user_data = user_data;
return sqe;
}
/// Queues (but does not submit) an SQE to perform a `recv(2)`.
/// Returns a pointer to the SQE.
pub fn recv(
@@ -558,6 +574,33 @@ pub const IO_Uring = struct {
return sqe;
}
/// Queues (but does not submit) an SQE to perform a `poll(2)`.
/// Returns a pointer to the SQE.
pub fn poll_add(
self: *IO_Uring,
user_data: u64,
fd: os.fd_t,
poll_mask: u32,
) !*io_uring_sqe {
const sqe = try self.get_sqe();
io_uring_prep_poll_add(sqe, fd, poll_mask);
sqe.user_data = user_data;
return sqe;
}
/// Queues (but does not submit) an SQE to remove an existing poll operation.
/// Returns a pointer to the SQE.
pub fn poll_remove(
self: *IO_Uring,
user_data: u64,
target_user_data: u64,
) !*io_uring_sqe {
const sqe = try self.get_sqe();
io_uring_prep_poll_remove(sqe, target_user_data);
sqe.user_data = user_data;
return sqe;
}
/// Queues (but does not submit) an SQE to perform an `fallocate(2)`.
/// Returns a pointer to the SQE.
pub fn fallocate(
@@ -776,7 +819,7 @@ pub fn io_uring_prep_rw(
op: linux.IORING_OP,
sqe: *io_uring_sqe,
fd: os.fd_t,
addr: anytype,
addr: u64,
len: usize,
offset: u64,
) void {
@@ -786,7 +829,7 @@ pub fn io_uring_prep_rw(
.ioprio = 0,
.fd = fd,
.off = offset,
.addr = @ptrToInt(addr),
.addr = addr,
.len = @intCast(u32, len),
.rw_flags = 0,
.user_data = 0,
@@ -798,11 +841,11 @@ pub fn io_uring_prep_rw(
}
pub fn io_uring_prep_read(sqe: *io_uring_sqe, fd: os.fd_t, buffer: []u8, offset: u64) void {
io_uring_prep_rw(.READ, sqe, fd, buffer.ptr, buffer.len, offset);
io_uring_prep_rw(.READ, sqe, fd, @ptrToInt(buffer.ptr), buffer.len, offset);
}
pub fn io_uring_prep_write(sqe: *io_uring_sqe, fd: os.fd_t, buffer: []const u8, offset: u64) void {
io_uring_prep_rw(.WRITE, sqe, fd, buffer.ptr, buffer.len, offset);
io_uring_prep_rw(.WRITE, sqe, fd, @ptrToInt(buffer.ptr), buffer.len, offset);
}
pub fn io_uring_prep_readv(
@@ -811,7 +854,7 @@ pub fn io_uring_prep_readv(
iovecs: []const os.iovec,
offset: u64,
) void {
io_uring_prep_rw(.READV, sqe, fd, iovecs.ptr, iovecs.len, offset);
io_uring_prep_rw(.READV, sqe, fd, @ptrToInt(iovecs.ptr), iovecs.len, offset);
}
pub fn io_uring_prep_writev(
@@ -820,7 +863,7 @@ pub fn io_uring_prep_writev(
iovecs: []const os.iovec_const,
offset: u64,
) void {
io_uring_prep_rw(.WRITEV, sqe, fd, iovecs.ptr, iovecs.len, offset);
io_uring_prep_rw(.WRITEV, sqe, fd, @ptrToInt(iovecs.ptr), iovecs.len, offset);
}
pub fn io_uring_prep_accept(
@@ -832,7 +875,7 @@ pub fn io_uring_prep_accept(
) void {
// `addr` holds a pointer to `sockaddr`, and `addr2` holds a pointer to socklen_t`.
// `addr2` maps to `sqe.off` (u64) instead of `sqe.len` (which is only a u32).
io_uring_prep_rw(.ACCEPT, sqe, fd, addr, 0, @ptrToInt(addrlen));
io_uring_prep_rw(.ACCEPT, sqe, fd, @ptrToInt(addr), 0, @ptrToInt(addrlen));
sqe.rw_flags = flags;
}
@@ -843,16 +886,26 @@ pub fn io_uring_prep_connect(
addrlen: os.socklen_t,
) void {
// `addrlen` maps to `sqe.off` (u64) instead of `sqe.len` (which is only a u32).
io_uring_prep_rw(.CONNECT, sqe, fd, addr, 0, addrlen);
io_uring_prep_rw(.CONNECT, sqe, fd, @ptrToInt(addr), 0, addrlen);
}
pub fn io_uring_prep_epoll_ctl(
sqe: *io_uring_sqe,
epfd: os.fd_t,
fd: os.fd_t,
op: u32,
ev: ?*linux.epoll_event,
) void {
io_uring_prep_rw(.EPOLL_CTL, sqe, epfd, @ptrToInt(ev), op, @intCast(u64, fd));
}
pub fn io_uring_prep_recv(sqe: *io_uring_sqe, fd: os.fd_t, buffer: []u8, flags: u32) void {
io_uring_prep_rw(.RECV, sqe, fd, buffer.ptr, buffer.len, 0);
io_uring_prep_rw(.RECV, sqe, fd, @ptrToInt(buffer.ptr), buffer.len, 0);
sqe.rw_flags = flags;
}
pub fn io_uring_prep_send(sqe: *io_uring_sqe, fd: os.fd_t, buffer: []const u8, flags: u32) void {
io_uring_prep_rw(.SEND, sqe, fd, buffer.ptr, buffer.len, 0);
io_uring_prep_rw(.SEND, sqe, fd, @ptrToInt(buffer.ptr), buffer.len, 0);
sqe.rw_flags = flags;
}
@@ -863,7 +916,7 @@ pub fn io_uring_prep_openat(
flags: u32,
mode: os.mode_t,
) void {
io_uring_prep_rw(.OPENAT, sqe, fd, path, mode, 0);
io_uring_prep_rw(.OPENAT, sqe, fd, @ptrToInt(path), mode, 0);
sqe.rw_flags = flags;
}
@@ -891,7 +944,7 @@ pub fn io_uring_prep_timeout(
count: u32,
flags: u32,
) void {
io_uring_prep_rw(.TIMEOUT, sqe, -1, ts, 1, count);
io_uring_prep_rw(.TIMEOUT, sqe, -1, @ptrToInt(ts), 1, count);
sqe.rw_flags = flags;
}
@@ -913,6 +966,22 @@ pub fn io_uring_prep_timeout_remove(sqe: *io_uring_sqe, timeout_user_data: u64,
};
}
pub fn io_uring_prep_poll_add(
sqe: *io_uring_sqe,
fd: os.fd_t,
poll_mask: u32,
) void {
io_uring_prep_rw(.POLL_ADD, sqe, fd, @ptrToInt(@as(?*c_void, null)), 0, 0);
sqe.rw_flags = std.mem.nativeToLittle(u32, poll_mask);
}
pub fn io_uring_prep_poll_remove(
sqe: *io_uring_sqe,
target_user_data: u64,
) void {
io_uring_prep_rw(.POLL_REMOVE, sqe, -1, target_user_data, 0, 0);
}
pub fn io_uring_prep_fallocate(
sqe: *io_uring_sqe,
fd: os.fd_t,