/* Copyright (C) 2010 The Android Open Source Project
**
** This software is licensed under the terms of the GNU General Public
** License version 2, as published by the Free Software Foundation, and
** may be copied, distributed, and modified under those terms.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
*/

/* Implement the Looper interface on top of the QEMU main event loop */

#include <android/looper.h>
#include <android/utils/panic.h>
#include "qemu-common.h"
#include "qemu/timer.h"
#include "sysemu/char.h"
#include "android/sockets.h"  /* for socket_set_nonblock() */

/**********************************************************************
 **********************************************************************
 *****
 *****  T I M E R S
 *****
 **********************************************************************
 **********************************************************************/

/* Model a timer simple as a QEMUTimer for the host_clock */

static void
qlooptimer_startRelative(void* impl, Duration timeout_ms)
{
    QEMUTimer* tt = impl;
    if (timeout_ms == DURATION_INFINITE)
        timer_del(tt);
    else
        timer_mod(tt, qemu_clock_get_ms(QEMU_CLOCK_HOST) + timeout_ms);
}

static void
qlooptimer_startAbsolute(void* impl, Duration deadline_ms)
{
    QEMUTimer* tt = impl;
    if (deadline_ms == DURATION_INFINITE)
        timer_del(tt);
    else
        timer_mod(tt, deadline_ms);
}

static void
qlooptimer_stop(void* impl)
{
    QEMUTimer* tt = impl;
    timer_del(tt);
}

static int
qlooptimer_isActive(void* impl)
{
    QEMUTimer* tt = impl;
    return timer_pending(tt);
}

static void
qlooptimer_free(void* impl)
{
    QEMUTimer* tt = impl;
    timer_free(tt);
}

static const LoopTimerClass  qlooptimer_class = {
    qlooptimer_startRelative,
    qlooptimer_startAbsolute,
    qlooptimer_stop,
    qlooptimer_isActive,
    qlooptimer_free
};

static void
qlooper_timer_init(Looper*        looper,
                   LoopTimer*     timer,
                   LoopTimerFunc  callback,
                   void*          opaque)
{
    timer->clazz = (LoopTimerClass*) &qlooptimer_class;
    timer->impl  = timer_new(QEMU_CLOCK_HOST, SCALE_MS, callback, opaque);
}

/**********************************************************************
 **********************************************************************
 *****
 *****  F I L E   D E S C R I P T O R S
 *****
 **********************************************************************
 **********************************************************************/

/* Modeling the LoopIo is a bit more complex because the main event loop
 * will call different functions for read and write readiness, while our
 * users expect a single call with a mask of ready events.
 *
 * Since the QEMU main event loop looks like the following:
 *
 *    1/ perform select()
 *    2/ for each file descriptor:
 *         if readReady:
 *             call readHandler()
 *         if writeReady:
 *             call writeHandler()
 *    3/ run timers
 *    4/ run bottom-half handlers
 *
 * We're going to provide simple read and write handlers that only mark
 * the file descriptor for readiness, and put it on a "pending list".
 *
 * Then, we're going to schedule a bottom-half handler when such a pending
 * i/o event occurs, in order to call the user callback with the correct
 * flags.
 */

typedef struct QLoopIo QLoopIo;

typedef struct QLooper  QLooper;

struct QLoopIo {
    int         fd;
    LoopIoFunc  user_callback;
    void*       user_opaque;
    unsigned    wanted;
    unsigned    ready;
    QLooper*    looper;
    QLoopIo*    pendingNext;
    QLoopIo*    next;
};

static void qlooper_addIo(QLooper*  looper, QLoopIo* io);
static void qlooper_delIo(QLooper*  looper, QLoopIo* io);

static QLoopIo*
qloopio_new(int fd, LoopIoFunc callback, void* opaque, QLooper* qlooper)
{
    QLoopIo*  io = g_malloc(sizeof(*io));

    io->fd = fd;
    io->user_callback = callback;
    io->user_opaque   = opaque;
    io->wanted        = 0;
    io->ready         = 0;
    io->looper        = qlooper;
    io->pendingNext   = NULL;

    qlooper_addIo(qlooper, io);

    return io;
}

static void qlooper_addPendingIo(QLooper* qlooper, QLoopIo* io);
static void qlooper_delPendingIo(QLooper* qlooper, QLoopIo*  io);

static void
qloopio_removePending(QLoopIo* io)
{
    if (io->ready != 0) {
        qlooper_delPendingIo(io->looper, io);
        io->ready = 0;
    }
}

static void
qloopio_setReady(QLoopIo* io, unsigned flag)
{
    if (io->ready == 0) {
        qlooper_addPendingIo(io->looper, io);
    }
    io->ready |= flag;
}

static void
qloopio_handleRead(void* opaque)
{
    QLoopIo* io = opaque;
    qloopio_setReady(io, LOOP_IO_READ);
}

static void
qloopio_handleWrite(void* opaque)
{
    QLoopIo* io = opaque;
    qloopio_setReady(io, LOOP_IO_WRITE);
}

static void
qloopio_modify(QLoopIo* io, unsigned wanted)
{
    /* no change, don't bother */
    if (wanted == io->wanted)
        return;

    /* if we're pending, but the new mask doesn't care about
     * out state, remove from pending list */
    if (io->ready && (io->ready & wanted) == 0) {
        qloopio_removePending(io);
    }

    /* recompute read/write handlers for QEMU */
    IOHandler* fd_read  = (wanted & LOOP_IO_READ)  ? qloopio_handleRead  : NULL;
    IOHandler* fd_write = (wanted & LOOP_IO_WRITE) ? qloopio_handleWrite : NULL;
    qemu_set_fd_handler(io->fd, fd_read, fd_write, io);
    io->wanted = wanted;
}

static void
qloopio_wantRead(void* impl)
{
    QLoopIo* io = impl;
    qloopio_modify(io, io->wanted | LOOP_IO_READ);
}

static void
qloopio_wantWrite(void* impl)
{
    QLoopIo* io = impl;
    qloopio_modify(io, io->wanted | LOOP_IO_WRITE);
}

static void
qloopio_dontWantRead(void* impl)
{
    QLoopIo* io = impl;
    qloopio_modify(io, io->wanted & ~LOOP_IO_READ);
}

static void
qloopio_dontWantWrite(void* impl)
{
    QLoopIo* io = impl;
    qloopio_modify(io, io->wanted & ~LOOP_IO_WRITE);
}

static void
qloopio_free(void* impl)
{
    QLoopIo* io = impl;
    if (io->ready)
        qloopio_removePending(io);

    /* remove from global list */
    qlooper_delIo(io->looper, io);

    /* make QEMU forget about this fd */
    qemu_set_fd_handler(io->fd, NULL, NULL, NULL);
    io->fd = -1;
    g_free(io);
}

static unsigned
qloopio_poll(void* impl)
{
    QLoopIo* io = impl;
    return io->ready;
}

static const LoopIoClass  qlooper_io_class = {
    qloopio_wantRead,
    qloopio_wantWrite,
    qloopio_dontWantRead,
    qloopio_dontWantWrite,
    qloopio_poll,
    qloopio_free
};

static void
qlooper_io_init(Looper*     looper,
                LoopIo*     loopio,
                int         fd,
                LoopIoFunc  callback,
                void*       opaque)
{
    QLoopIo* io = qloopio_new(fd, callback, opaque, (QLooper*)looper);

    socket_set_nonblock(fd);

    loopio->clazz = (LoopIoClass*) &qlooper_io_class;
    loopio->impl  = io;
}

struct QLooper {
    Looper    looper;
    QLoopIo*  io_list;
    QLoopIo*  io_pending;
    QEMUBH*   io_bh;
};

static void
qlooper_addIo(QLooper* looper, QLoopIo* io)
{
    io->next        = looper->io_list;
    looper->io_list = io;
}

static void
qlooper_delIo(QLooper* looper, QLoopIo* io)
{
    QLoopIo** pnode = &looper->io_list;
    for (;;) {
        if (*pnode == NULL)
            break;
        if (*pnode == io) {
            *pnode = io->next;
            io->next = NULL;
            break;
        }
        pnode = &(*pnode)->next;
    }
}

static void
qlooper_addPendingIo(QLooper* looper, QLoopIo* io)
{
    if (looper->io_pending == NULL) {
        qemu_bh_schedule(looper->io_bh);
    }
    io->pendingNext    = looper->io_pending;
    looper->io_pending = io;
}

static void
qlooper_delPendingIo(QLooper* looper, QLoopIo* io)
{
    QLoopIo** pnode = &looper->io_pending;
    for (;;) {
        if (*pnode == NULL)
            break;
        if (*pnode == io) {
            *pnode = io->pendingNext;
            break;
        }
        pnode = &(*pnode)->pendingNext;
    }
    io->pendingNext = NULL;
}

/* This function is called by the main event loop when pending i/o
 * events were registered with qlooper_addPendingIo(). It will parse
 * the list of pending QLoopIo and call the user callback with the
 * appropriate flags.
 */
static void
qlooper_handle_io_bh(void* opaque)
{
    QLooper*  looper = opaque;
    QLoopIo*  io;

    while ((io = looper->io_pending) != NULL) {
        unsigned ready;
        /* extract from list */
        looper->io_pending = io->pendingNext;
        io->pendingNext    = NULL;
        /* call the user callback, clear io->ready before to
         * indicate that the item is not on the pending list
         * anymore.
         */
        ready     = io->ready;
        io->ready = 0;
        io->user_callback(io->user_opaque, io->fd, ready);
    }
}

static Duration
qlooper_now(Looper* ll)
{
    return qemu_clock_get_ms(QEMU_CLOCK_HOST);
}

extern void qemu_system_shutdown_request(void);

static void
qlooper_forceQuit(Looper* ll)
{
    qemu_system_shutdown_request();
}

/* The user cannot call looper_run on the core event loop, because it
 * is started by qemu_main() explicitely instead, so just panic. */
int
qlooper_run(Looper* ll, Duration deadline_ms)
{
    APANIC("Trying to run the QEMU main event loop explicitely!");
    return EINVAL;
}

static void
qlooper_destroy(Looper* ll)
{
    QLooper*  looper = (QLooper*)ll;
    QLoopIo*  io;

    while ((io = looper->io_list) != NULL)
        qloopio_free(io);

    qemu_bh_delete(looper->io_bh);
    g_free(looper);
}

Looper*
looper_newCore(void)
{
    QLooper*  looper = g_malloc0(sizeof(*looper));

    looper->io_list    = NULL;
    looper->io_pending = NULL;
    looper->io_bh      = qemu_bh_new(qlooper_handle_io_bh, looper);

    looper->looper.now        = qlooper_now;
    looper->looper.timer_init = qlooper_timer_init;
    looper->looper.io_init    = qlooper_io_init;
    looper->looper.run        = qlooper_run;
    looper->looper.forceQuit  = qlooper_forceQuit;
    looper->looper.destroy    = qlooper_destroy;

    return &looper->looper;
}
