/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 * epoll(7) file descriptor monitoring
 */

#include "qemu/osdep.h"
#include <sys/epoll.h>
#include "qemu/rcu_queue.h"
#include "aio-posix.h"

/* The fd number threshold to switch to epoll */
#define EPOLL_ENABLE_THRESHOLD 64

void fdmon_epoll_disable(AioContext *ctx)
{
    if (ctx->epollfd >= 0) {
        close(ctx->epollfd);
        ctx->epollfd = -1;
    }

    /* Switch back */
    ctx->fdmon_ops = &fdmon_poll_ops;
}

static inline int epoll_events_from_pfd(int pfd_events)
{
    return (pfd_events & G_IO_IN ? EPOLLIN : 0) |
           (pfd_events & G_IO_OUT ? EPOLLOUT : 0) |
           (pfd_events & G_IO_HUP ? EPOLLHUP : 0) |
           (pfd_events & G_IO_ERR ? EPOLLERR : 0);
}

static void fdmon_epoll_update(AioContext *ctx,
                               AioHandler *old_node,
                               AioHandler *new_node)
{
    struct epoll_event event = {
        .data.ptr = new_node,
        .events = new_node ? epoll_events_from_pfd(new_node->pfd.events) : 0,
    };
    int r;

    if (!new_node) {
        r = epoll_ctl(ctx->epollfd, EPOLL_CTL_DEL, old_node->pfd.fd, &event);
    } else if (!old_node) {
        r = epoll_ctl(ctx->epollfd, EPOLL_CTL_ADD, new_node->pfd.fd, &event);
    } else {
        r = epoll_ctl(ctx->epollfd, EPOLL_CTL_MOD, new_node->pfd.fd, &event);
    }

    if (r) {
        fdmon_epoll_disable(ctx);
    }
}

static int fdmon_epoll_wait(AioContext *ctx, AioHandlerList *ready_list,
                            int64_t timeout)
{
    GPollFD pfd = {
        .fd = ctx->epollfd,
        .events = G_IO_IN | G_IO_OUT | G_IO_HUP | G_IO_ERR,
    };
    AioHandler *node;
    int i, ret = 0;
    struct epoll_event events[128];

    /* Fall back while external clients are disabled */
    if (atomic_read(&ctx->external_disable_cnt)) {
        return fdmon_poll_ops.wait(ctx, ready_list, timeout);
    }

    if (timeout > 0) {
        ret = qemu_poll_ns(&pfd, 1, timeout);
        if (ret > 0) {
            timeout = 0;
        }
    }
    if (timeout <= 0 || ret > 0) {
        ret = epoll_wait(ctx->epollfd, events,
                         ARRAY_SIZE(events),
                         timeout);
        if (ret <= 0) {
            goto out;
        }
        for (i = 0; i < ret; i++) {
            int ev = events[i].events;
            int revents = (ev & EPOLLIN ? G_IO_IN : 0) |
                          (ev & EPOLLOUT ? G_IO_OUT : 0) |
                          (ev & EPOLLHUP ? G_IO_HUP : 0) |
                          (ev & EPOLLERR ? G_IO_ERR : 0);

            node = events[i].data.ptr;
            aio_add_ready_handler(ready_list, node, revents);
        }
    }
out:
    return ret;
}

static const FDMonOps fdmon_epoll_ops = {
    .update = fdmon_epoll_update,
    .wait = fdmon_epoll_wait,
    .need_wait = aio_poll_disabled,
};

static bool fdmon_epoll_try_enable(AioContext *ctx)
{
    AioHandler *node;
    struct epoll_event event;

    QLIST_FOREACH_RCU(node, &ctx->aio_handlers, node) {
        int r;
        if (QLIST_IS_INSERTED(node, node_deleted) || !node->pfd.events) {
            continue;
        }
        event.events = epoll_events_from_pfd(node->pfd.events);
        event.data.ptr = node;
        r = epoll_ctl(ctx->epollfd, EPOLL_CTL_ADD, node->pfd.fd, &event);
        if (r) {
            return false;
        }
    }

    ctx->fdmon_ops = &fdmon_epoll_ops;
    return true;
}

bool fdmon_epoll_try_upgrade(AioContext *ctx, unsigned npfd)
{
    if (ctx->epollfd < 0) {
        return false;
    }

    /* Do not upgrade while external clients are disabled */
    if (atomic_read(&ctx->external_disable_cnt)) {
        return false;
    }

    if (npfd >= EPOLL_ENABLE_THRESHOLD) {
        if (fdmon_epoll_try_enable(ctx)) {
            return true;
        } else {
            fdmon_epoll_disable(ctx);
        }
    }
    return false;
}

void fdmon_epoll_setup(AioContext *ctx)
{
    ctx->epollfd = epoll_create1(EPOLL_CLOEXEC);
    if (ctx->epollfd == -1) {
        fprintf(stderr, "Failed to create epoll instance: %s", strerror(errno));
    }
}
