/*****************************************************************************\
* Copyright (c) 2004 Pelle Johansson.                                         *
* All rights reserved.                                                        *
*                                                                             *
* This file is part of the moftpd package. Use and distribution of            *
* this software is governed by the terms in the file LICENCE, which           *
* should have come with this package.                                         *
\*****************************************************************************/

/* $moftpd: events_epoll.c 1251 2005-03-06 22:24:29Z morth $ */

/*
 * This won't work if you call add_read_fd() and add_write_fd() on the same fd
 * but we don't do that unless we call remove_read_fd() first.
 */

#include "system.h"

#include "events.h"

static int pollFd = -1;

void events_einit ()
{
  if (pollFd != -1)
    close (pollFd);
  
  pollFd = epoll_create (4);
}

int events_earf (int fd, void *data)
{
  struct epoll_event ev;
  
  ev.events = EPOLLIN | EPOLLPRI;
  ev.data.ptr = data;
  
  if (epoll_ctl (pollFd, EPOLL_CTL_ADD, fd, &ev))
  {
    if (errno != EEXIST)
      return -1;
  }
  return 0;
}

int events_eawf (int fd, void *data)
{
  struct epoll_event ev;
  
  ev.events = EPOLLOUT | EPOLLPRI;
  ev.data.ptr = data;
  
  if (epoll_ctl (pollFd, EPOLL_CTL_ADD, fd, &ev))
  {
    if (errno != EEXIST)
      return -1;
  }
  return 0;
}

void events_errf (int fd)
{
  epoll_ctl (pollFd, EPOLL_CTL_DEL, fd, NULL);
}

void events_erwf (int fd)
{
  epoll_ctl (pollFd, EPOLL_CTL_DEL, fd, NULL);
}

int run_events (void)
{
  struct epoll_event evs[10];
  int res, i;
  
  res = epoll_wait (pollFd, evs, 10, 10000);
  if (res < 0)
  {
    if (errno == EINTR)
      return 0;
    return res;
  }
  
  for (i = 0; i < res; i++)
  {
    if (events_run_data (evs[i].data.ptr, 0)) // TODO urgent?
      break;
  }
  return 0;
}


syntax highlighted by Code2HTML, v. 0.9.1