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

Reply via email to