@@ -38,9 +38,22 @@ int iowatcher_cleanup(hloop_t* loop) {
3838 return 0 ;
3939}
4040
41+ static struct io_uring_sqe * io_uring_get_sqe_safe (struct io_uring * ring ) {
42+ struct io_uring_sqe * sqe = io_uring_get_sqe (ring );
43+ if (sqe == NULL ) {
44+ // SQ is full, flush pending submissions and retry
45+ io_uring_submit (ring );
46+ sqe = io_uring_get_sqe (ring );
47+ }
48+ return sqe ;
49+ }
50+
4151int iowatcher_add_event (hloop_t * loop , int fd , int events ) {
4252 if (loop -> iowatcher == NULL ) {
43- iowatcher_init (loop );
53+ int ret = iowatcher_init (loop );
54+ if (ret < 0 ) {
55+ return ret ;
56+ }
4457 }
4558 io_uring_ctx_t * ctx = (io_uring_ctx_t * )loop -> iowatcher ;
4659 hio_t * io = loop -> ios .ptr [fd ];
@@ -64,7 +77,7 @@ int iowatcher_add_event(hloop_t* loop, int fd, int events) {
6477 struct io_uring_sqe * sqe ;
6578 if (io -> events != 0 ) {
6679 // Cancel the existing poll request first
67- sqe = io_uring_get_sqe (& ctx -> ring );
80+ sqe = io_uring_get_sqe_safe (& ctx -> ring );
6881 if (sqe == NULL ) return -1 ;
6982 io_uring_prep_poll_remove (sqe , (uint64_t )fd );
7083 io_uring_sqe_set_data64 (sqe , IO_URING_CANCEL_TAG );
@@ -73,7 +86,7 @@ int iowatcher_add_event(hloop_t* loop, int fd, int events) {
7386 }
7487
7588 // Add poll for the combined events
76- sqe = io_uring_get_sqe (& ctx -> ring );
89+ sqe = io_uring_get_sqe_safe (& ctx -> ring );
7790 if (sqe == NULL ) return -1 ;
7891 io_uring_prep_poll_add (sqe , fd , poll_mask );
7992 io_uring_sqe_set_data64 (sqe , (uint64_t )fd );
@@ -105,7 +118,7 @@ int iowatcher_del_event(hloop_t* loop, int fd, int events) {
105118 }
106119
107120 // Cancel existing poll
108- struct io_uring_sqe * sqe = io_uring_get_sqe (& ctx -> ring );
121+ struct io_uring_sqe * sqe = io_uring_get_sqe_safe (& ctx -> ring );
109122 if (sqe == NULL ) return -1 ;
110123 io_uring_prep_poll_remove (sqe , (uint64_t )fd );
111124 io_uring_sqe_set_data64 (sqe , IO_URING_CANCEL_TAG );
@@ -114,7 +127,7 @@ int iowatcher_del_event(hloop_t* loop, int fd, int events) {
114127 ctx -> nfds -- ;
115128 } else {
116129 // Re-add with remaining events
117- sqe = io_uring_get_sqe (& ctx -> ring );
130+ sqe = io_uring_get_sqe_safe (& ctx -> ring );
118131 if (sqe == NULL ) return -1 ;
119132 io_uring_prep_poll_add (sqe , fd , poll_mask );
120133 io_uring_sqe_set_data64 (sqe , (uint64_t )fd );
@@ -153,6 +166,7 @@ int iowatcher_poll_events(hloop_t* loop, int timeout) {
153166 }
154167
155168 int nevents = 0 ;
169+ int sqe_queued = 0 ;
156170 unsigned head ;
157171 unsigned ncqes = 0 ;
158172 io_uring_for_each_cqe (& ctx -> ring , head , cqe ) {
@@ -168,7 +182,7 @@ int iowatcher_poll_events(hloop_t* loop, int timeout) {
168182 if (io == NULL ) continue ;
169183
170184 if (cqe -> res < 0 ) {
171- io -> revents |= HV_READ ;
185+ io -> revents |= ( io -> events ? io -> events : HV_RDWR ) ;
172186 EVENT_PENDING (io );
173187 ++ nevents ;
174188 } else {
@@ -190,17 +204,18 @@ int iowatcher_poll_events(hloop_t* loop, int timeout) {
190204 if (io -> events & HV_READ ) remask |= POLLIN ;
191205 if (io -> events & HV_WRITE ) remask |= POLLOUT ;
192206 if (remask ) {
193- struct io_uring_sqe * sqe = io_uring_get_sqe (& ctx -> ring );
207+ struct io_uring_sqe * sqe = io_uring_get_sqe_safe (& ctx -> ring );
194208 if (sqe ) {
195209 io_uring_prep_poll_add (sqe , fd , remask );
196210 io_uring_sqe_set_data64 (sqe , (uint64_t )fd );
211+ sqe_queued = 1 ;
197212 }
198213 }
199214 }
200215
201216 io_uring_cq_advance (& ctx -> ring , ncqes );
202217
203- if (nevents > 0 ) {
218+ if (sqe_queued ) {
204219 io_uring_submit (& ctx -> ring );
205220 }
206221
0 commit comments