28#include "dbus-pollable-set.h" 
   30#include <dbus/dbus-internals.h> 
   31#include <dbus/dbus-sysdeps.h> 
   34# error This file is for Linux epoll(4) 
   42#ifndef DOXYGEN_SHOULD_SKIP_THIS 
   45    DBusPollableSet parent;
 
   47} DBusPollableSetEpoll;
 
   49static inline DBusPollableSetEpoll *
 
   50socket_set_epoll_cast (DBusPollableSet *set)
 
   52  _dbus_assert (set->cls == &_dbus_pollable_set_epoll_class);
 
   53  return (DBusPollableSetEpoll *) set;
 
   58socket_set_epoll_free (DBusPollableSet *set)
 
   60  DBusPollableSetEpoll *self = socket_set_epoll_cast (set);
 
   72_dbus_pollable_set_epoll_new (
void)
 
   74  DBusPollableSetEpoll *self;
 
   76  self = 
dbus_new0 (DBusPollableSetEpoll, 1);
 
   81  self->parent.cls = &_dbus_pollable_set_epoll_class;
 
   83  self->epfd = epoll_create1 (EPOLL_CLOEXEC);
 
   92      self->epfd = epoll_create (42);
 
   94      flags = fcntl (self->epfd, F_GETFD, 0);
 
   97        fcntl (self->epfd, F_SETFD, flags | FD_CLOEXEC);
 
  100  if (self->epfd == -1)
 
  102      socket_set_epoll_free ((DBusPollableSet *) self);
 
  106  return (DBusPollableSet *) self;
 
  110watch_flags_to_epoll_events (
unsigned int flags)
 
  123epoll_events_to_watch_flags (uint32_t events)
 
  127  if (events & EPOLLIN)
 
  129  if (events & EPOLLOUT)
 
  131  if (events & EPOLLHUP)
 
  133  if (events & EPOLLERR)
 
  140socket_set_epoll_add (DBusPollableSet  *set,
 
  145  DBusPollableSetEpoll *self = socket_set_epoll_cast (set);
 
  146  struct epoll_event event;
 
  154      event.events = watch_flags_to_epoll_events (flags);
 
  160      event.events = EPOLLET;
 
  163  if (epoll_ctl (self->epfd, EPOLL_CTL_ADD, fd, &event) == 0)
 
  181        _dbus_warn (
"fd %d added and then added again", fd);
 
  185        _dbus_warn (
"Misc error when trying to watch fd %d: %s", fd,
 
  194socket_set_epoll_enable (DBusPollableSet  *set,
 
  198  DBusPollableSetEpoll *self = socket_set_epoll_cast (set);
 
  199  struct epoll_event event;
 
  204  event.events = watch_flags_to_epoll_events (flags);
 
  206  if (epoll_ctl (self->epfd, EPOLL_CTL_MOD, fd, &event) == 0)
 
  220        _dbus_warn (
"fd %d enabled before it was added", fd);
 
  224        _dbus_warn (
"Insufficient memory to change watch for fd %d", fd);
 
  228        _dbus_warn (
"Misc error when trying to watch fd %d: %s", fd,
 
  235socket_set_epoll_disable (DBusPollableSet  *set,
 
  238  DBusPollableSetEpoll *self = socket_set_epoll_cast (set);
 
  239  struct epoll_event event;
 
  260  event.events = EPOLLET;
 
  262  if (epoll_ctl (self->epfd, EPOLL_CTL_MOD, fd, &event) == 0)
 
  266  _dbus_warn (
"Error when trying to watch fd %d: %s", fd,
 
  271socket_set_epoll_remove (DBusPollableSet  *set,
 
  274  DBusPollableSetEpoll *self = socket_set_epoll_cast (set);
 
  278  struct epoll_event dummy;
 
  281  if (epoll_ctl (self->epfd, EPOLL_CTL_DEL, fd, &dummy) == 0)
 
  285  _dbus_warn (
"Error when trying to remove fd %d: %s", fd, strerror (err));
 
  291#define N_STACK_DESCRIPTORS 64 
  294socket_set_epoll_poll (DBusPollableSet   *set,
 
  295                       DBusPollableEvent *revents,
 
  299  DBusPollableSetEpoll *self = socket_set_epoll_cast (set);
 
  300  struct epoll_event events[N_STACK_DESCRIPTORS];
 
  306  n_ready = epoll_wait (self->epfd, events,
 
  313  for (i = 0; i < n_ready; i++)
 
  315      revents[i].fd = events[i].data.fd;
 
  316      revents[i].flags = epoll_events_to_watch_flags (events[i].events);
 
  322DBusPollableSetClass _dbus_pollable_set_epoll_class = {
 
  323    socket_set_epoll_free,
 
  324    socket_set_epoll_add,
 
  325    socket_set_epoll_remove,
 
  326    socket_set_epoll_enable,
 
  327    socket_set_epoll_disable,
 
  328    socket_set_epoll_poll
 
  331#ifdef TEST_BEHAVIOUR_OF_EPOLLET 
  342#include <sys/epoll.h> 
  349  struct epoll_event input;
 
  350  struct epoll_event output;
 
  351  int epfd = epoll_create1 (EPOLL_CLOEXEC);
 
  357  input.events = EPOLLHUP | EPOLLET;
 
  358  ret = epoll_ctl (epfd, EPOLL_CTL_ADD, fd, &input);
 
  359  printf (
"ctl ADD: %d\n", ret);
 
  361  ret = epoll_wait (epfd, &output, 1, -1);
 
  362  printf (
"wait for HUP, edge-triggered: %d\n", ret);
 
  364  ret = epoll_wait (epfd, &output, 1, 1);
 
  365  printf (
"wait for HUP again: %d\n", ret);
 
  367  input.events = EPOLLHUP;
 
  368  ret = epoll_ctl (epfd, EPOLL_CTL_MOD, fd, &input);
 
  369  printf (
"ctl MOD: %d\n", ret);
 
  371  ret = epoll_wait (epfd, &output, 1, -1);
 
  372  printf (
"wait for HUP: %d\n", ret);
 
@ DBUS_WATCH_READABLE
As in POLLIN.
@ DBUS_WATCH_WRITABLE
As in POLLOUT.
@ DBUS_WATCH_HANGUP
As in POLLHUP (can't watch for it, but can be present in current state passed to dbus_watch_handle())...
@ DBUS_WATCH_ERROR
As in POLLERR (can't watch for this, but can be present in current state passed to dbus_watch_handle(...
#define _dbus_assert(condition)
Aborts with an error message if the condition is false.
void _dbus_warn(const char *format,...)
Prints a warning message to stderr.
#define _DBUS_N_ELEMENTS(array)
Computes the number of elements in a fixed-size array using sizeof().
#define _DBUS_ZERO(object)
Sets all bits in an object to zero.
#define NULL
A null pointer, defined appropriately for C or C++.
#define TRUE
Expands to "1".
#define FALSE
Expands to "0".
void dbus_free(void *memory)
Frees a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
#define dbus_new0(type, count)
Safe macro for using dbus_malloc0().
dbus_uint32_t dbus_bool_t
A boolean, valid values are TRUE and FALSE.