@@ -256,22 +256,22 @@ class Crystal::System::IoUring
256256 # make new tail and previous writes visible to the kernel threads
257257 Atomic ::Ops .store(@sq_ktail , @sq_tail , :sequentially_consistent , volatile: true )
258258
259- if sq_poll?
260- if wait
261- flags |= LibC ::IORING_ENTER_SQ_WAIT
262- elsif sq_need_wakeup?
263- flags |= LibC ::IORING_ENTER_SQ_WAKEUP
264- else
265- return
259+ loop do
260+ if sq_poll?
261+ if wait
262+ flags |= LibC ::IORING_ENTER_SQ_WAIT
263+ elsif sq_need_wakeup?
264+ flags |= LibC ::IORING_ENTER_SQ_WAKEUP
265+ else
266+ return
267+ end
266268 end
267- end
268269
269- loop do
270270 head = Atomic ::Ops .load(@sq_khead , :monotonic , volatile: true )
271271 to_submit = @sq_tail &- head
272272
273273 ret = enter(to_submit, flags: flags)
274- break unless ret == - LibC ::EINTR && (!sq_poll? || sq_need_wakeup?)
274+ break unless ret == - LibC ::EINTR
275275 end
276276 end
277277
@@ -286,9 +286,18 @@ class Crystal::System::IoUring
286286 flags: ENTERS .new(flags).to_s
287287
288288 ret = Syscall .io_uring_enter(@fd , to_submit, min_complete, flags, Pointer (Void ).null, LibC ::SizeT .zero)
289- if ret >= 0 || ret == - LibC ::EINTR || ret == - LibC ::EBUSY
289+ return ret if ret >= 0
290+
291+ case ret
292+ when - LibC ::EINTR
293+ # interrupted by signal (caller shall retry)
294+ ret
295+ when - LibC ::EBUSY
296+ # the CQ ring is full and the kernel has overflow CQE waiting
297+ # TODO: set a boolean so the next evloop run can process has many CQEs as
298+ # possible until max iterations or the CQ ring is emptied
290299 ret
291- elsif ret == - LibC ::EBADR
300+ when - LibC ::EBADR
292301 # CQE ring buffer overflowed, the system is running low on memory and
293302 # completion entries got dropped despite of IORING_FEAT_NODROP and we
294303 # can't recover from lost completions as fibers would never be resumed!
0 commit comments