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);
#define NULL
A null pointer, defined appropriately for C or C++.
void dbus_free(void *memory)
Frees a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
#define _dbus_assert(condition)
Aborts with an error message if the condition is false.
#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.
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().
As in POLLERR (can't watch for this, but can be present in current state passed to dbus_watch_handle(...
#define TRUE
Expands to "1".
As in POLLHUP (can't watch for it, but can be present in current state passed to dbus_watch_handle())...
#define FALSE
Expands to "0".
#define _DBUS_ZERO(object)
Sets all bits in an object to zero.