Hey Guys,
Here's a patch to support epoll in ecore.
Probably needs a bit more testing, but let me know what you think.
thanks,
Mike
Use epoll (efficient poll) in ecore when it's available.
configure.ac | 3
src/lib/ecore/ecore.c | 1
src/lib/ecore/ecore_main.c | 136 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 140 insertions(+)
Index: configure.ac
===================================================================
--- configure.ac (revision 48932)
+++ configure.ac (working copy)
@@ -891,6 +891,9 @@
])
AC_SUBST(cocoa_ldflags)
+# check for epoll support
+AC_CHECK_HEADERS([sys/epoll.h])
+
# basic pthread support
EFL_CHECK_PTHREAD([no], [have_pthread="yes"], [have_pthread="no"])
Index: src/lib/ecore/ecore_main.c
===================================================================
--- src/lib/ecore/ecore_main.c (revision 48932)
+++ src/lib/ecore/ecore_main.c (working copy)
@@ -52,6 +52,10 @@
#include "Ecore.h"
#include "ecore_private.h"
+#ifdef HAVE_SYS_EPOLL_H
+# define HAVE_EPOLL
+# include <sys/epoll.h>
+#endif
struct _Ecore_Fd_Handler
{
@@ -121,6 +125,78 @@
static double t1 = 0.0;
static double t2 = 0.0;
+#ifdef HAVE_EPOLL
+static int epoll_fd = -1;
+
+void _ecore_main_loop_init(void)
+{
+ epoll_fd = epoll_create(1);
+ if (epoll_fd < 0)
+ ERR("Failed to create epoll fd!");
+ INF("epoll_fd = %d", epoll_fd);
+}
+
+static inline int _ecore_poll_events_from_fdh(Ecore_Fd_Handler *fdh)
+{
+ int events = 0;
+ if (fdh->flags & ECORE_FD_READ) events |= EPOLLIN;
+ if (fdh->flags & ECORE_FD_WRITE) events |= EPOLLOUT;
+ if (fdh->flags & ECORE_FD_ERROR) events |= EPOLLERR;
+ return events;
+}
+
+static inline int _ecore_epoll_add(Ecore_Fd_Handler *fdh)
+{
+ struct epoll_event ev;
+
+ ev.events = _ecore_poll_events_from_fdh(fdh);
+ ev.data.ptr = fdh;
+ INF("adding poll on %d %08x", fdh->fd, ev.events);
+ return epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fdh->fd, &ev);
+}
+
+static inline void _ecore_epoll_remove(Ecore_Fd_Handler *fdh)
+{
+ struct epoll_event ev;
+ INF("removing poll on %d", fdh->fd);
+ /* could get an EBADF if somebody closed the FD before removing it */
+ if (0 > epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fdh->fd, &ev) &&
+ errno != EBADF)
+ {
+ ERR("Failed to delete epoll fd %d! (errno=%d)", fdh->fd, errno);
+ }
+}
+
+static inline int ecore_epoll_modify(Ecore_Fd_Handler *fdh)
+{
+ struct epoll_event ev;
+
+ ev.events = _ecore_poll_events_from_fdh(fdh);
+ ev.data.ptr = fdh;
+ INF("modifing epoll on %d to %08x", fdh->fd, ev.events);
+ return epoll_ctl(epoll_fd, EPOLL_CTL_MOD, fdh->fd, &ev);
+}
+
+#else
+void _ecore_main_loop_init(void)
+{
+}
+
+static inline int _ecore_epoll_add(Ecore_Fd_Handler *fdh)
+{
+ return 0;
+}
+
+static inline void _ecore_epoll_remove(Ecore_Fd_Handler *fd_handler)
+{
+}
+
+static inline int ecore_epoll_modify(Ecore_Fd_Handler *fd_handler)
+{
+}
+
+#endif
+
/**
* @defgroup Ecore_Main_Loop_Group Main Loop Functions
*
@@ -262,6 +338,12 @@
ECORE_MAGIC_SET(fdh, ECORE_MAGIC_FD_HANDLER);
fdh->fd = fd;
fdh->flags = flags;
+ if (0 > _ecore_epoll_add(fdh))
+ {
+ ERR("Failed to add epoll fd %d!", fd);
+ free(fdh);
+ return NULL;
+ }
fdh->read_active = 0;
fdh->write_active = 0;
fdh->error_active = 0;
@@ -325,6 +407,7 @@
}
fd_handler->delete_me = 1;
fd_handlers_delete_me = 1;
+ _ecore_epoll_remove(fd_handler);
return fd_handler->data;
}
@@ -424,6 +507,10 @@
return;
}
fd_handler->flags = flags;
+ if (0 > ecore_epoll_modify(fd_handler))
+ {
+ ERR("Failed to mod epoll fd %d!", fd_handler->fd);
+ }
}
void
@@ -510,6 +597,7 @@
fdh->prep_func (fdh->prep_data, fdh);
fdh->references--;
}
+#ifndef HAVE_EPOLL
EINA_INLIST_FOREACH(fd_handlers, fdh)
if (!fdh->delete_me)
{
@@ -560,6 +648,54 @@
#endif
return 1;
}
+#else /* HAVE_EPOLL */
+ if (_ecore_signal_count_get()) return -1;
+
+ do
+ {
+ const int num_epoll_fds = 10;
+ struct epoll_event ev[num_epoll_fds];
+ int i, timeout;
+
+ if (t)
+ timeout = t->tv_sec*1000 + t->tv_usec/1000;
+ else
+ timeout = -1;
+ ret = epoll_wait(epoll_fd, ev, num_epoll_fds, timeout);
+ _ecore_loop_time = ecore_time_get();
+ if (ret < 0)
+ {
+ if (errno == EINTR) return -1;
+ ERR("epoll_wait failed %d", errno);
+ return -1;
+ }
+
+ for (i=0; i<ret; i++)
+ {
+ fdh = ev[i].data.ptr;
+ if (!ECORE_MAGIC_CHECK(fdh, ECORE_MAGIC_FD_HANDLER))
+ {
+ ECORE_MAGIC_FAIL(fdh, ECORE_MAGIC_FD_HANDLER,
+ "_ecore_main_select");
+ continue;
+ }
+ if (fdh->delete_me)
+ {
+ ERR("deleted fd in epoll");
+ return -1;
+ }
+ if (ev->events & EPOLLIN)
+ fdh->read_active = 1;
+ if (ev->events & EPOLLOUT)
+ fdh->write_active = 1;
+ if (ev->events & EPOLLERR)
+ fdh->error_active = 1;
+ }
+ }
+ while (0);
+ _ecore_main_fd_handlers_cleanup();
+
+#endif
return 0;
}
Index: src/lib/ecore/ecore.c
===================================================================
--- src/lib/ecore/ecore.c (revision 48932)
+++ src/lib/ecore/ecore.c (working copy)
@@ -118,6 +118,7 @@
_ecore_glib_init();
_ecore_job_init();
_ecore_loop_time = ecore_time_get();
+ _ecore_main_loop_init();
#if HAVE_MALLINFO
if (getenv("ECORE_MEM_STAT"))
------------------------------------------------------------------------------
_______________________________________________
enlightenment-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel