/*
 * Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "poller.h"

#include <assert.h>
#include <stdlib.h>
#include <sys/epoll.h>
#include <unistd.h>

#include "util.h"

/* Based on https://github.com/elly/elib/blob/master/reactor.c */

struct poller {
  int epoll_fd;
  int num_polled;
};

struct polled {
  struct poller *poller;
  int fd;
  void *priv;
  void (*read)(struct polled *polled);
  void (*write)(struct polled *polled);
  void (*close)(struct polled *polled);
};

struct poller *poller_new(void)
{
  int epoll_fd = epoll_create1(0);
  if (epoll_fd < 0)
    return NULL;
  struct poller *poller = xmalloc(sizeof(*poller));
  poller->epoll_fd = epoll_fd;
  poller->num_polled = 0;
  return poller;
}

void poller_free(struct poller *poller)
{
  assert(poller);
  assert(poller->num_polled == 0);
  close(poller->epoll_fd);
  xfree(poller);
}

int poller_fd(struct poller *poller)
{
  assert(poller);
  return poller->epoll_fd;
}

struct polled *poller_add(struct poller *poller, int fd)
{
  assert(poller);

  struct polled *polled = xmalloc(sizeof(*polled));
  struct epoll_event event;

  polled->poller = poller;
  polled->fd = fd;
  polled->priv = NULL;
  polled->read = NULL;
  polled->write = NULL;
  polled->close = NULL;

  event.events = 0;
  event.data.ptr = polled;

  if (epoll_ctl(poller->epoll_fd, EPOLL_CTL_ADD, fd, &event) < 0) {
    xfree(polled);
    return NULL;
  }

  poller->num_polled++;

  return polled;
}

static int poller_update(struct poller *poller, struct polled *polled)
{
  assert(poller);
  assert(polled);
  assert(polled->poller == poller);

  struct epoll_event event;
  event.events = 0;
  event.data.ptr = polled;

  if (polled->read)
    event.events |= EPOLLIN;
  if (polled->write)
    event.events |= EPOLLOUT;
  if (polled->close)
    event.events |= EPOLLRDHUP;

  return epoll_ctl(poller->epoll_fd, EPOLL_CTL_MOD, polled->fd, &event);
}

static int poller_remove(struct poller *poller, struct polled *polled)
{
  assert(poller);
  assert(polled);
  assert(polled->poller == poller);

  int result = epoll_ctl(poller->epoll_fd, EPOLL_CTL_DEL, polled->fd, NULL);
  if (result)
    return result;

  xfree(polled);
  poller->num_polled--;

  return 0;
}

int poller_poll(struct poller *poller)
{
  struct epoll_event events[16];
  struct polled *polled;
  int n, i;

  n = epoll_wait(poller->epoll_fd,
                 events, sizeof(events) / sizeof(events[0]),
                 0);
  if (n < 0)
    return n;
  for (i = 0; i < n; i++) {
    polled = events[i].data.ptr;
    if (events[i].events & (EPOLLRDHUP | EPOLLERR | EPOLLHUP)) {
      if (polled->close)
        (polled->close)(polled);
      poller_remove(poller, polled);
    } else if ((events[i].events & EPOLLIN) && polled->read) {
      (polled->read)(polled);
    } else if ((events[i].events & EPOLLOUT) && polled->write) {
      (polled->write)(polled);
    }
  }
  return 0;
}

void *polled_priv(struct polled *polled)
{
  assert(polled);
  return polled->priv;
}

void polled_set_priv(struct polled *polled, void *priv)
{
  assert(polled);
  polled->priv = priv;
}

void polled_set_read(struct polled *polled,
         void (*read)(struct polled *polled))
{
  assert(polled);
  polled->read = read;
}

void polled_set_write(struct polled *polled,
          void (*write)(struct polled *polled))
{
  assert(polled);
  polled->write = write;
}

void polled_set_close(struct polled *polled,
          void (*close)(struct polled *polled))
{
  assert(polled);
  polled->close = close;
}

int polled_update(struct polled *polled)
{
  assert(polled);
  return poller_update(polled->poller, polled);
}

int polled_delete(struct polled *polled)
{
  assert(polled);
  return poller_remove(polled->poller, polled);
}
