26 #include "dbus-socket-set.h" 
   28 #include <dbus/dbus-internals.h> 
   29 #include <dbus/dbus-sysdeps.h> 
   32 # error This file is for Linux epoll(4) 
   37 #include <sys/epoll.h> 
   40 #ifndef DOXYGEN_SHOULD_SKIP_THIS 
   47 static inline DBusSocketSetEpoll *
 
   48 socket_set_epoll_cast (DBusSocketSet *set)
 
   50   _dbus_assert (set->cls == &_dbus_socket_set_epoll_class);
 
   51   return (DBusSocketSetEpoll *) set;
 
   56 socket_set_epoll_free (DBusSocketSet *set)
 
   58   DBusSocketSetEpoll *
self = socket_set_epoll_cast (set);
 
   70 _dbus_socket_set_epoll_new (
void)
 
   72   DBusSocketSetEpoll *
self;
 
   79   self->parent.cls = &_dbus_socket_set_epoll_class;
 
   81   self->epfd = epoll_create1 (EPOLL_CLOEXEC);
 
   90       self->epfd = epoll_create (42);
 
   92       flags = fcntl (self->epfd, F_GETFD, 0);
 
   95         fcntl (self->epfd, F_SETFD, flags | FD_CLOEXEC);
 
  100       socket_set_epoll_free ((DBusSocketSet *) 
self);
 
  104   return (DBusSocketSet *) 
self;
 
  108 watch_flags_to_epoll_events (
unsigned int flags)
 
  121 epoll_events_to_watch_flags (uint32_t events)
 
  125   if (events & EPOLLIN)
 
  127   if (events & EPOLLOUT)
 
  129   if (events & EPOLLHUP)
 
  131   if (events & EPOLLERR)
 
  138 socket_set_epoll_add (DBusSocketSet  *set,
 
  143   DBusSocketSetEpoll *
self = socket_set_epoll_cast (set);
 
  144   struct epoll_event event;
 
  152       event.events = watch_flags_to_epoll_events (flags);
 
  158       event.events = EPOLLET;
 
  161   if (epoll_ctl (self->epfd, EPOLL_CTL_ADD, fd, &event) == 0)
 
  179         _dbus_warn (
"fd %d added and then added again", fd);
 
  183         _dbus_warn (
"Misc error when trying to watch fd %d: %s", fd,
 
  192 socket_set_epoll_enable (DBusSocketSet  *set,
 
  196   DBusSocketSetEpoll *
self = socket_set_epoll_cast (set);
 
  197   struct epoll_event event;
 
  202   event.events = watch_flags_to_epoll_events (flags);
 
  204   if (epoll_ctl (self->epfd, EPOLL_CTL_MOD, fd, &event) == 0)
 
  218         _dbus_warn (
"fd %d enabled before it was added", fd);
 
  222         _dbus_warn (
"Insufficient memory to change watch for fd %d", fd);
 
  226         _dbus_warn (
"Misc error when trying to watch fd %d: %s", fd,
 
  233 socket_set_epoll_disable (DBusSocketSet  *set,
 
  236   DBusSocketSetEpoll *
self = socket_set_epoll_cast (set);
 
  237   struct epoll_event event;
 
  258   event.events = EPOLLET;
 
  260   if (epoll_ctl (self->epfd, EPOLL_CTL_MOD, fd, &event) == 0)
 
  264   _dbus_warn (
"Error when trying to watch fd %d: %s", fd,
 
  269 socket_set_epoll_remove (DBusSocketSet  *set,
 
  272   DBusSocketSetEpoll *
self = socket_set_epoll_cast (set);
 
  276   struct epoll_event dummy;
 
  279   if (epoll_ctl (self->epfd, EPOLL_CTL_DEL, fd, &dummy) == 0)
 
  283   _dbus_warn (
"Error when trying to remove fd %d: %s", fd, strerror (err));
 
  289 #define N_STACK_DESCRIPTORS 64 
  292 socket_set_epoll_poll (DBusSocketSet   *set,
 
  293                        DBusSocketEvent *revents,
 
  297   DBusSocketSetEpoll *
self = socket_set_epoll_cast (set);
 
  298   struct epoll_event events[N_STACK_DESCRIPTORS];
 
  304   n_ready = epoll_wait (self->epfd, events,
 
  311   for (i = 0; i < n_ready; i++)
 
  313       revents[i].fd = events[i].data.fd;
 
  314       revents[i].flags = epoll_events_to_watch_flags (events[i].events);
 
  320 DBusSocketSetClass _dbus_socket_set_epoll_class = {
 
  321     socket_set_epoll_free,
 
  322     socket_set_epoll_add,
 
  323     socket_set_epoll_remove,
 
  324     socket_set_epoll_enable,
 
  325     socket_set_epoll_disable,
 
  326     socket_set_epoll_poll
 
  329 #ifdef TEST_BEHAVIOUR_OF_EPOLLET 
  340 #include <sys/epoll.h> 
  347   struct epoll_event input;
 
  348   struct epoll_event output;
 
  349   int epfd = epoll_create1 (EPOLL_CLOEXEC);
 
  355   input.events = EPOLLHUP | EPOLLET;
 
  356   ret = epoll_ctl (epfd, EPOLL_CTL_ADD, fd, &input);
 
  357   printf (
"ctl ADD: %d\n", ret);
 
  359   ret = epoll_wait (epfd, &output, 1, -1);
 
  360   printf (
"wait for HUP, edge-triggered: %d\n", ret);
 
  362   ret = epoll_wait (epfd, &output, 1, 1);
 
  363   printf (
"wait for HUP again: %d\n", ret);
 
  365   input.events = EPOLLHUP;
 
  366   ret = epoll_ctl (epfd, EPOLL_CTL_MOD, fd, &input);
 
  367   printf (
"ctl MOD: %d\n", ret);
 
  369   ret = epoll_wait (epfd, &output, 1, -1);
 
  370   printf (
"wait for HUP: %d\n", ret);