Hi All,

Here's a second version of my patch, updated for various comments.

It seems to pass the regression tests, and E still starts up.

This version has lots more #ifdefs (sorry Vincent), to address Gustavo's
comment that the #ifdefs should be inside functions, not outside them.
I think this makes things more messy, but I'm the newcomer round here... :-)

Secondly, I haven't tested GTK integration, but it should work with this version of the patch, as the epoll fd itself is passed to main_loop_select().

Adding a shutdown call to close the epoll_fd is trivial, and I'll do this after
further testing and further comments...

thanks,

Mike
Add support for epoll in ecore_main_loop().

 configure.ac               |    3 +
 src/lib/ecore/ecore_main.c |  134 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 137 insertions(+)

Index: configure.ac
===================================================================
--- configure.ac        (revision 48939)
+++ 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 48939)
+++ 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,114 @@
 static double            t1 = 0.0;
 static double            t2 = 0.0;
 
+#ifdef HAVE_EPOLL
+static int epoll_fd = -1;
+#endif
+
+void _ecore_main_loop_init(void)
+{
+#ifdef HAVE_EPOLL
+   epoll_fd = epoll_create(1);
+   if (epoll_fd < 0)
+     CRIT("Failed to create epoll fd!");
+#endif
+}
+
+static inline int _ecore_poll_events_from_fdh(Ecore_Fd_Handler *fdh)
+{
+   int events = 0;
+#ifdef HAVE_EPOLL
+   if (fdh->flags & ECORE_FD_READ)  events |= EPOLLIN;
+   if (fdh->flags & ECORE_FD_WRITE) events |= EPOLLOUT;
+   if (fdh->flags & ECORE_FD_ERROR) events |= EPOLLERR;
+#endif
+   return events;
+}
+
+static inline int _ecore_main_fdh_epoll_add(Ecore_Fd_Handler *fdh)
+{
+   int r = 0;
+#ifdef HAVE_EPOLL
+   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);
+   r = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fdh->fd, &ev);
+#endif
+   return r;
+}
+
+static inline void _ecore_main_fdh_epoll_del(Ecore_Fd_Handler *fdh)
+{
+#ifdef HAVE_EPOLL
+   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);
+     }
+#endif
+}
+
+static inline int _ecore_main_fdh_epoll_modify(Ecore_Fd_Handler *fdh)
+{
+   int r = 0;
+#ifdef HAVE_EPOLL
+   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);
+   r = epoll_ctl(epoll_fd, EPOLL_CTL_MOD, fdh->fd, &ev);
+#endif
+   return r;
+}
+
+#ifdef HAVE_EPOLL
+static inline int _ecore_main_fdh_epoll_mark_active(void)
+{
+   const int num_epoll_fds = 10;
+   struct epoll_event ev[num_epoll_fds];
+   int i, ret;
+
+   ret = epoll_wait(epoll_fd, ev, num_epoll_fds, 0);
+   if (ret < 0)
+     {
+        if (errno == EINTR) return -1;
+        ERR("epoll_wait failed %d", errno);
+        return -1;
+     }
+
+   for (i=0; i<ret; i++)
+     {
+        Ecore_Fd_Handler *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");
+             continue;
+          }
+        if (ev->events & EPOLLIN)
+          fdh->read_active = 1;
+        if (ev->events & EPOLLOUT)
+          fdh->write_active = 1;
+        if (ev->events & EPOLLERR)
+          fdh->error_active = 1;
+     }
+
+   return 0;
+}
+#endif
+
 /**
  * @defgroup Ecore_Main_Loop_Group Main Loop Functions
  *
@@ -262,6 +374,12 @@
    ECORE_MAGIC_SET(fdh, ECORE_MAGIC_FD_HANDLER);
    fdh->fd = fd;
    fdh->flags = flags;
+   if (0 > _ecore_main_fdh_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 +443,7 @@
      }
    fd_handler->delete_me = 1;
    fd_handlers_delete_me = 1;
+   _ecore_main_fdh_epoll_del(fd_handler);
    return fd_handler->data;
 }
 
@@ -424,6 +543,10 @@
        return;
      }
    fd_handler->flags = flags;
+   if (0 > _ecore_main_fdh_epoll_modify(fd_handler))
+     {
+       ERR("Failed to mod epoll fd %d!", fd_handler->fd);
+     }
 }
 
 void
@@ -510,6 +633,7 @@
          fdh->prep_func (fdh->prep_data, fdh);
          fdh->references--;
        }
+#ifndef HAVE_EPOLL
    EINA_INLIST_FOREACH(fd_handlers, fdh)
      if (!fdh->delete_me)
        {
@@ -529,6 +653,12 @@
               if (fdh->fd > max_fd) max_fd = fdh->fd;
            }
        }
+#else /* HAVE_EPOLL */
+   /* polling on the epoll fd will wake when an fd in the epoll set is active 
*/
+   FD_SET(epoll_fd, &rfds);
+   max_fd = epoll_fd;
+#endif /* HAVE_EPOLL */
+
    if (_ecore_signal_count_get()) return -1;
 
    ret = main_loop_select(max_fd + 1, &rfds, &wfds, &exfds, t);
@@ -544,6 +674,9 @@
      }
    if (ret > 0)
      {
+#ifdef HAVE_EPOLL
+        _ecore_main_fdh_epoll_mark_active();
+#else /* HAVE_EPOLL */
        EINA_INLIST_FOREACH(fd_handlers, fdh)
          if (!fdh->delete_me)
            {
@@ -554,6 +687,7 @@
               if (FD_ISSET(fdh->fd, &exfds))
                 fdh->error_active = 1;
            }
+#endif /* HAVE_EPOLL */
        _ecore_main_fd_handlers_cleanup();
 #ifdef _WIN32
        _ecore_main_win32_handlers_cleanup();
------------------------------------------------------------------------------

_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to