@@ -14,6 +14,7 @@ fd: posix.fd_t = -1,
1414sq : SubmissionQueue ,
1515cq : CompletionQueue ,
1616flags : u32 ,
17+ int_flags : u8 ,
1718features : u32 ,
1819
1920/// A friendly way to setup an io_uring, with default linux.io_uring_params.
@@ -113,6 +114,8 @@ pub fn init_params(entries: u16, p: *linux.io_uring_params) !IoUring {
113114 .sq = sq ,
114115 .cq = cq ,
115116 .flags = p .flags ,
117+ // TODO set int_flags according to p.flags
118+ .int_flags = 0 ,
116119 .features = p .features ,
117120 };
118121}
@@ -126,6 +129,21 @@ pub fn deinit(self: *IoUring) void {
126129 self .fd = -1 ;
127130}
128131
132+ pub fn io_uring_set_io_wait (self : * IoUring , enable_iowait : bool ) ! void {
133+ if ((self .features & linux .IORING_FEAT_NO_IOWAIT ) == 0 ) {
134+ return error .SystemOutdated ;
135+ }
136+ if (enable_iowait ) {
137+ self .int_flags &= ~ @as (u8 , linux .IORING_INT_FLAG_NO_IOWAIT );
138+ } else {
139+ self .int_flags |= linux .IORING_INT_FLAG_NO_IOWAIT ;
140+ }
141+ }
142+
143+ pub fn ring_enter_flags (self : * IoUring ) u32 {
144+ return self .int_flags & linux .IORING_INT_FLAGS_MASK ;
145+ }
146+
129147/// Returns a pointer to a vacant SQE, or an error if the submission queue is full.
130148/// We follow the implementation (and atomics) of liburing's `io_uring_get_sqe()` exactly.
131149/// However, instead of a null we return an error to force safe handling.
@@ -160,7 +178,7 @@ pub fn submit(self: *IoUring) !u32 {
160178/// Matches the implementation of io_uring_submit_and_wait() in liburing.
161179pub fn submit_and_wait (self : * IoUring , wait_nr : u32 ) ! u32 {
162180 const submitted = self .flush_sq ();
163- var flags : u32 = 0 ;
181+ var flags : u32 = self . ring_enter_flags () ;
164182 if (self .sq_ring_needs_enter (& flags ) or wait_nr > 0 ) {
165183 if (wait_nr > 0 or (self .flags & linux .IORING_SETUP_IOPOLL ) != 0 ) {
166184 flags |= linux .IORING_ENTER_GETEVENTS ;
@@ -233,7 +251,7 @@ pub fn flush_sq(self: *IoUring) u32 {
233251/// For the latter case, we set the SQ thread wakeup flag.
234252/// Matches the implementation of sq_ring_needs_enter() in liburing.
235253pub fn sq_ring_needs_enter (self : * IoUring , flags : * u32 ) bool {
236- assert (flags .* == 0 );
254+ assert (flags .* & ( ~ @as ( u8 , linux . IORING_INT_FLAGS_MASK )) == 0 );
237255 if ((self .flags & linux .IORING_SETUP_SQPOLL ) == 0 ) return true ;
238256 if ((@atomicLoad (u32 , self .sq .flags , .unordered ) & linux .IORING_SQ_NEED_WAKEUP ) != 0 ) {
239257 flags .* |= linux .IORING_ENTER_SQ_WAKEUP ;
@@ -273,7 +291,8 @@ pub fn copy_cqes(self: *IoUring, cqes: []linux.io_uring_cqe, wait_nr: u32) !u32
273291 const count = self .copy_cqes_ready (cqes );
274292 if (count > 0 ) return count ;
275293 if (self .cq_ring_needs_flush () or wait_nr > 0 ) {
276- _ = try self .enter (0 , wait_nr , linux .IORING_ENTER_GETEVENTS );
294+ const flags = self .ring_enter_flags () | linux .IORING_ENTER_GETEVENTS ;
295+ _ = try self .enter (0 , wait_nr , flags );
277296 return self .copy_cqes_ready (cqes );
278297 }
279298 return 0 ;
0 commit comments