static int __io_uring_disarm(struct lxc_async_descr *descr,
struct mainloop_handler *handler);
-static void delete_handler(struct lxc_async_descr *descr,
- struct mainloop_handler *handler, bool oneshot)
+static int disarm_handler(struct lxc_async_descr *descr,
+ struct mainloop_handler *handler, bool oneshot)
{
int ret = 0;
- struct lxc_list *list;
if (descr->type == LXC_MAINLOOP_IO_URING) {
/*
ret = epoll_ctl(descr->epfd, EPOLL_CTL_DEL, handler->fd, NULL);
}
if (ret < 0)
- SYSWARN("Failed to delete \"%d\" for \"%s\"", handler->fd, handler->handler_name);
+ return syswarn_ret(-1, "Failed to disarm %d for \"%s\" handler",
+ handler->fd, handler->handler_name);
+
+ TRACE("Disarmed %d for \"%s\" handler", handler->fd, handler->handler_name);
+ return 0;
+}
+
+static void delete_handler(struct mainloop_handler *handler)
+{
+ struct lxc_list *list;
if (handler->cleanup) {
+ int ret;
+
ret = handler->cleanup(handler->fd, handler->data);
if (ret < 0)
- SYSWARN("Failed to call cleanup \"%s\" handler", handler->handler_name);
+ SYSWARN("Failed to cleanup %d for \"%s\" handler", handler->fd, handler->handler_name);
}
+ TRACE("Deleted %d for \"%s\" handler", handler->fd, handler->handler_name);
list = move_ptr(handler->list);
lxc_list_del(list);
free(list->elem);
free(list);
}
+static inline void cleanup_handler(struct lxc_async_descr *descr,
+ struct mainloop_handler *handler, bool oneshot)
+{
+ if (disarm_handler(descr, handler, oneshot) == 0)
+ delete_handler(handler);
+}
+
#ifndef HAVE_LIBURING
static inline int __lxc_mainloop_io_uring(struct lxc_async_descr *descr,
int timeout_ms)
for (;;) {
int ret;
- __s32 mask = 0;
+ __s32 res = 0;
bool oneshot = false;
struct io_uring_cqe *cqe = NULL;
struct mainloop_handler *handler = NULL;
ret = LXC_MAINLOOP_CONTINUE;
oneshot = !(cqe->flags & IORING_CQE_F_MORE);
- mask = cqe->res;
+ res = cqe->res;
handler = io_uring_cqe_get_data(cqe);
io_uring_cqe_seen(descr->ring, cqe);
- switch (mask) {
- case -ECANCELED:
- handler->flags |= CANCEL_RECEIVED;
- TRACE("Canceled \"%s\" handler", handler->handler_name);
- goto out;
- case -ENOENT:
- handler->flags = CANCEL_SUCCESS | CANCEL_RECEIVED;
- TRACE("No sqe for \"%s\" handler", handler->handler_name);
- goto out;
- case -EALREADY:
- TRACE("Repeat sqe remove request for \"%s\" handler", handler->handler_name);
- goto out;
- case 0:
- handler->flags |= CANCEL_SUCCESS;
- TRACE("Removed \"%s\" handler", handler->handler_name);
- goto out;
- default:
- /*
- * We need to always remove the handler for a
- * successful oneshot request.
- */
- if (oneshot)
- handler->flags = CANCEL_SUCCESS | CANCEL_RECEIVED;
- }
-
- ret = handler->callback(handler->fd, mask, handler->data, descr);
- switch (ret) {
- case LXC_MAINLOOP_CONTINUE:
- /* We're operating in oneshot mode so we need to rearm. */
- if (oneshot && __io_uring_arm(descr, handler, true))
- return -1;
- break;
- case LXC_MAINLOOP_DISARM:
- if (has_exact_flags(handler->flags, (CANCEL_SUCCESS | CANCEL_RECEIVED)))
- delete_handler(descr, handler, oneshot);
- break;
- case LXC_MAINLOOP_CLOSE:
- return log_trace(0, "Closing from \"%s\"", handler->handler_name);
- case LXC_MAINLOOP_ERROR:
- return syserror_ret(-1, "Closing with error from \"%s\"", handler->handler_name);
+ if (res <= 0) {
+ switch (res) {
+ case 0:
+ TRACE("Removed \"%s\" handler", handler->handler_name);
+ handler->flags |= CANCEL_SUCCESS;
+ if (has_exact_flags(handler->flags, (CANCEL_SUCCESS | CANCEL_RECEIVED)))
+ delete_handler(handler);
+ break;
+ case -EALREADY:
+ TRACE("Repeat sqe remove request for \"%s\" handler", handler->handler_name);
+ break;
+ case -ECANCELED:
+ TRACE("Canceled \"%s\" handler", handler->handler_name);
+ handler->flags |= CANCEL_RECEIVED;
+ if (has_exact_flags(handler->flags, (CANCEL_SUCCESS | CANCEL_RECEIVED)))
+ delete_handler(handler);
+ break;
+ case -ENOENT:
+ TRACE("No sqe for \"%s\" handler", handler->handler_name);
+ break;
+ default:
+ WARN("Received unexpected return value %d in cqe for \"%s\" handler",
+ res, handler->handler_name);
+ break;
+ }
+ } else {
+ ret = handler->callback(handler->fd, res, handler->data, descr);
+ switch (ret) {
+ case LXC_MAINLOOP_CONTINUE:
+ /* We're operating in oneshot mode so we need to rearm. */
+ if (oneshot && __io_uring_arm(descr, handler, true))
+ return -1;
+ break;
+ case LXC_MAINLOOP_DISARM:
+ disarm_handler(descr, handler, oneshot);
+ if (oneshot)
+ delete_handler(handler);
+ break;
+ case LXC_MAINLOOP_CLOSE:
+ return log_trace(0, "Closing from \"%s\"", handler->handler_name);
+ case LXC_MAINLOOP_ERROR:
+ return syserror_ret(-1, "Closing with error from \"%s\"", handler->handler_name);
+ default:
+ WARN("Received unexpected return value %d from \"%s\" handler",
+ ret, handler->handler_name);
+ break;
+ }
}
- out:
if (lxc_list_empty(&descr->handlers))
return error_ret(0, "Closing because there are no more handlers");
}
handler->data, descr);
switch (ret) {
case LXC_MAINLOOP_DISARM:
- delete_handler(descr, handler, false);
+ cleanup_handler(descr, handler, false);
__fallthrough;
case LXC_MAINLOOP_CONTINUE:
break;