commit be711231f7827774db2aed915800f50deb3625d1
parent fca24717bd6ad632f19cfebb435005d9658fcd47
Author: Drew DeVault <sir@cmpwn.com>
Date: Tue, 18 May 2021 17:42:22 -0400
linux::io_uring: add polling SQEs
Signed-off-by: Drew DeVault <sir@cmpwn.com>
Diffstat:
1 file changed, 30 insertions(+), 0 deletions(-)
diff --git a/linux/io_uring/sqe.ha b/linux/io_uring/sqe.ha
@@ -1,3 +1,4 @@
+use endian;
use rt;
use types;
@@ -25,6 +26,13 @@ fn preprw(
sqe.off = offs;
};
+// Sets the user data field of an [[sqe]]. This is copied to the [[cqe]] and can
+// be used to correlate a completion event with the original SQE.
+export fn setuser(sqe: *sqe, user_data: *void) void = {
+ static assert(size(uintptr) <= size(u64));
+ sqe.user_data = user_data: uintptr: u64;
+};
+
// Prepares a no-op "operation" for an [[sqe]].
export fn nop(sqe: *sqe, flags: sqe_flags...) void = {
prep(sqe, op::NOP, flags...);
@@ -123,3 +131,25 @@ export fn fsync(
preprw(sqe, op::FSYNC, fd, null, 0, 0, flags...);
sqe.fsync_flags = fsync_flags;
};
+
+// Adds a request to poll a file descriptor for the given set of poll events.
+// This will only happen once, the poll request must be submitted with a new SQE
+// to re-poll the file descriptor later. The caller must call [[setuser]] to
+// provide a user data field in order to use [[poll_remove]] to remove this poll
+// request later.
+export fn poll_add(
+ sqe: *sqe,
+ fd: int,
+ poll_mask: uint,
+ flags: sqe_flags...
+) void = {
+ preprw(sqe, op::POLL_ADD, fd, null, 0, 0, flags...);
+ assert(endian::host == &endian::little); // TODO?
+ sqe.poll32_events = poll_mask: u32;
+};
+
+// Removes an existing poll request by matching the SQE's user_data field.
+export fn poll_remove(sqe: *sqe, user_data: *void, flags: sqe_flags...) void = {
+ preprw(sqe, op::POLL_REMOVE, -1, null, 0, 0, flags...);
+ setuser(sqe, user_data);
+};