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

#include "qemu/osdep.h"
#include <sys/epoll.h>
#include "qemu/lockcnt.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];

    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)
{
    bool ok;

    if (ctx->epollfd < 0) {
        return false;
    }

    if (npfd < EPOLL_ENABLE_THRESHOLD) {
        return false;
    }

    /* The list must not change while we add fds to epoll */
    if (!qemu_lockcnt_dec_if_lock(&ctx->list_lock)) {
        return false;
    }

    ok = fdmon_epoll_try_enable(ctx);

    qemu_lockcnt_inc_and_unlock(&ctx->list_lock);

    if (!ok) {
        fdmon_epoll_disable(ctx);
    }
    return ok;
}

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));
    }
}
