On Wed, Apr 23, 2008 at 4:45 PM, The Rasterman Carsten Haitzler
<[EMAIL PROTECTED]> wrote:
> On Tue, 15 Apr 2008 13:15:13 -0300 "Gustavo Sverzut Barbieri"
>  <[EMAIL PROTECTED]> babbled:
>  > For simplicity, I would just process one message per callback from
>  > ecore_fd_main... but we can also use a poll/select inside this
>  > function and do what you want, without the need to fcntl to
>  > NONBLOCKING.
>
>  just read a buffer of messages - if we don't get a complete message, store 
> the
>  partial one and keep it until the next call to process events then complete 
> the
>  message fetch.

Ok. Here is an updated patch. The fd is still nonblocking and on
partial read, it should be able to just restart cleany at a later
time. You will now pass a function pointer so that you can call
whatever kind of code you want (I doubt we really need something else
than evas_object_event_callback). I also make it optional. Some more
comments ?

-- 
Cedric BAIL
diff --git a/configure.in b/configure.in
index a08df81..a0bc60f 100644
--- a/configure.in
+++ b/configure.in
@@ -1173,6 +1173,30 @@ AC_ARG_ENABLE(pthreads,
 )
 
 #######################################
+## Async events
+build_async="no"
+AC_MSG_CHECKING(whether to build Async events support)
+AC_ARG_ENABLE(async-events,
+  AC_HELP_STRING([--enable-async-events], [enable async events support]),
+  [
+    if test "x$enableval" = "xyes" ; then
+      AC_MSG_RESULT(yes)
+      AC_DEFINE(BUILD_ASYNC_EVENTS, 1, [Build async events support])
+      build_async="yes"
+    else
+      AC_MSG_RESULT(no)
+    fi
+  ],
+  [
+    AC_MSG_RESULT($build_pthreads)
+    if test "x$build_pthreads" = "xyes" ; then
+      AC_DEFINE(BUILD_ASYNC_EVENTS, 1, [Build async events support])
+      build_async="yes"
+    fi
+  ]
+)
+
+#######################################
 ## MMX
 build_cpu_mmx="no"
 case $host_cpu in
@@ -1760,6 +1784,8 @@ echo "  SSE.....................: $build_cpu_sse"
 echo "  ALTIVEC.................: $build_cpu_altivec"
 echo "  Thread Support..........: $build_pthreads"
 echo
+echo "Async Events..............: $build_async"
+echo
 echo "ARGB Software Engine Options:"
 echo "  Sampling Scaler.........: $scaler_sample"
 echo "  Smooth Scaler...........: $scaler_smooth"
diff --git a/src/lib/Evas.h b/src/lib/Evas.h
index 3d9b1a4..a427188 100644
--- a/src/lib/Evas.h
+++ b/src/lib/Evas.h
@@ -823,6 +823,10 @@ extern "C" {
    EAPI void              evas_object_event_callback_add    (Evas_Object *obj, Evas_Callback_Type type, void (*func) (void *data, Evas *e, Evas_Object *obj, void *event_info), const void *data);
    EAPI void             *evas_object_event_callback_del    (Evas_Object *obj, Evas_Callback_Type type, void (*func) (void *data, Evas *e, Evas_Object *obj, void *event_info));
 
+   EAPI int		  evas_async_events_fd_get          (void);
+   EAPI int		  evas_async_events_process	    (void);
+   EAPI Evas_Bool	  evas_async_events_put             (void *target, Evas_Callback_Type type, void *event_info, void (*func)(void *target, Evas_Callback_Type type, void *event_info));
+
    EAPI void              evas_object_intercept_show_callback_add        (Evas_Object *obj, void (*func) (void *data, Evas_Object *obj), const void *data);
    EAPI void             *evas_object_intercept_show_callback_del        (Evas_Object *obj, void (*func) (void *data, Evas_Object *obj));
    EAPI void              evas_object_intercept_hide_callback_add        (Evas_Object *obj, void (*func) (void *data, Evas_Object *obj), const void *data);
diff --git a/src/lib/canvas/Makefile.am b/src/lib/canvas/Makefile.am
index 9dda0e1..db66ba6 100644
--- a/src/lib/canvas/Makefile.am
+++ b/src/lib/canvas/Makefile.am
@@ -37,6 +37,7 @@ evas_font_dir.c \
 evas_rectangle.c \
 evas_render.c \
 evas_smart.c \
-evas_stack.c
+evas_stack.c \
+evas_async_events.c
 
 libevas_canvas_la_DEPENDENCIES = $(top_builddir)/config.h
diff --git a/src/lib/canvas/evas_async_events.c b/src/lib/canvas/evas_async_events.c
new file mode 100644
index 0000000..d8756b6
--- /dev/null
+++ b/src/lib/canvas/evas_async_events.c
@@ -0,0 +1,165 @@
+#include "config.h"
+#include "evas_common.h"
+#include "evas_private.h"
+
+#ifdef BUILD_ASYNC_EVENTS
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <errno.h>
+
+static int _fd_write = -1;
+static int _fd_read = -1;
+
+static int _init_evas_event = 0;
+static pthread_mutex_t _mutex;
+
+typedef struct _Evas_Event_Async	Evas_Event_Async;
+struct _Evas_Event_Async
+{
+   void			(*func)(void *target, Evas_Callback_Type type, void *event_info);
+   void			 *target;
+   Evas_Callback_Type	  type;
+   void			 *event_info;
+};
+
+#endif
+
+int
+evas_async_events_init(void)
+{
+#ifdef BUILD_ASYNC_EVENTS
+   int filedes[2];
+
+   _init_evas_event++;
+   if (_init_evas_event > 1) return _init_evas_event;
+
+   if (pipe(filedes) == -1)
+     {
+	_init_evas_event = 0;
+	return 0;
+     }
+
+   _fd_read = filedes[0];
+   _fd_write = filedes[1];
+
+   fcntl(_fd_read, F_SETFL, O_NONBLOCK);
+
+   pthread_mutex_init(&_mutex, NULL);
+
+   return _init_evas_event;
+#else
+   return 0;
+#endif
+}
+
+int
+evas_async_events_shutdown(void)
+{
+#ifdef BUILD_ASYNC_EVENTS
+   _init_evas_event--;
+   if (_init_evas_event > 0) return _init_evas_event;
+
+   close(_fd_read);
+   close(_fd_write);
+   _fd_read = -1;
+   _fd_write = -1;
+
+   pthread_mutex_destroy(&_mutex);
+
+   return _init_evas_event;
+#else
+   return 0;
+#endif
+}
+
+EAPI int
+evas_async_events_fd_get(void)
+{
+#ifdef BUILD_ASYNC_EVENTS
+   return _fd_read;
+#else
+   return -1;
+#endif
+}
+
+EAPI int
+evas_async_events_process(void)
+{
+#ifdef BUILD_ASYNC_EVENTS
+   static Evas_Event_Async current;
+   static int size = 0;
+   int check;
+   int count = 0;
+
+   if (_fd_read != -1)
+     do
+       {
+	  check = read(_fd_read, ((char*) &current) + size, sizeof(current) - size);
+
+	  if (check > 0)
+	    {
+	       size += check;
+	       if (size == sizeof(current))
+		 {
+		    if (current.func) current.func(current.target, current.type, current.event_info);
+		    size = 0;
+		    count++;
+		 }
+	    }
+       }
+     while (check > 0);
+
+   if (check < 0)
+     switch (errno)
+       {
+	case EBADF:
+	case EINVAL:
+	case EIO:
+	case EISDIR:
+	   _fd_read = -1;
+       }
+
+   return count;
+#else
+   return 0;
+#endif
+}
+
+EAPI Evas_Bool
+evas_async_events_put(void *target, Evas_Callback_Type type, void *event_info, void (*func)(void *target, Evas_Callback_Type type, void *event_info))
+{
+#ifdef BUILD_ASYNC_EVENTS
+   Evas_Event_Async new;
+   Evas_Bool result = 0;
+
+   if (!func) return 0;
+
+   new.func = func;
+   new.target = target;
+   new.type = type;
+   new.event_info = event_info;
+
+   pthread_mutex_lock(&_mutex);
+   if (_fd_write != -1)
+     {
+	ssize_t	check;
+	int	offset = 0;
+
+	do {
+	   check = write(_fd_write, ((char*)&new) + offset, sizeof(new) - offset);
+	   offset += check;
+	} while (offset != sizeof(new) && (errno == EINTR || errno == EAGAIN));
+
+	if (offset == sizeof(new))
+	  result = 1;
+     }
+   pthread_mutex_unlock(&_mutex);
+
+   return result;
+#else
+   return -1;
+#endif
+}
+
diff --git a/src/lib/include/evas_private.h b/src/lib/include/evas_private.h
index 317e985..e832180 100644
--- a/src/lib/include/evas_private.h
+++ b/src/lib/include/evas_private.h
@@ -828,6 +828,9 @@ void evas_module_use(Evas_Module *em);
 void evas_module_clean(void);
 void evas_module_shutdown(void);
 
+int evas_async_events_init(void);
+int evas_async_events_shutdown(void);
+
 void _evas_walk(Evas *e);
 void _evas_unwalk(Evas *e);
        
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference 
Don't miss this year's exciting event. There's still time to save $100. 
Use priority code J8TL2D2. 
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to