wait on HANDLES in the select loop on Windows.
authorcaro <caro@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Sun, 25 Oct 2009 07:07:48 +0000 (07:07 +0000)
committercaro <caro@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Sun, 25 Oct 2009 07:07:48 +0000 (07:07 +0000)
git-svn-id: http://svn.enlightenment.org/svn/e/trunk/ecore@43253 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/lib/ecore/Ecore.h
src/lib/ecore/ecore_main.c
src/lib/ecore/ecore_private.h

index b1e2145..bce3bf3 100644 (file)
 #elif defined (__FreeBSD__) && (__FreeBSD_version >= 420001)
 # include <sys/select.h>
 #else
-# include <sys/types.h>
 # include <sys/time.h>
 # include <signal.h>
 #endif
+#include <sys/types.h>
 
 #ifndef TRUE
 # define TRUE 1
@@ -125,7 +125,8 @@ extern "C" {
    typedef void Ecore_Idler; /**< A handle for idlers */
    typedef void Ecore_Idle_Enterer; /**< A handle for idle enterers */
    typedef void Ecore_Idle_Exiter; /**< A handle for idle exiters */
-   typedef void Ecore_Fd_Handler; /**< A handle for Fd hanlders */
+   typedef void Ecore_Fd_Handler; /**< A handle for Fd handlers */
+   typedef void Ecore_Win32_Handler; /**< A handle for HANDLE handlers on Windows */
    typedef void Ecore_Event_Handler; /**< A handle for an event handler */
    typedef void Ecore_Event_Filter; /**< A handle for an event filter */
    typedef void Ecore_Event; /**< A handle for an event */
@@ -293,6 +294,7 @@ extern "C" {
    EAPI int               ecore_main_fd_handler_fd_get(Ecore_Fd_Handler *fd_handler);
    EAPI int               ecore_main_fd_handler_active_get(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Handler_Flags flags);
    EAPI void              ecore_main_fd_handler_active_set(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Handler_Flags flags);
+   EAPI Ecore_Win32_Handler *ecore_main_win32_handler_add(void *h, int (*func) (void *data, Ecore_Win32_Handler *wh), const void *data);
 
    EAPI Ecore_Pipe  *ecore_pipe_add(void (*handler) (void *data, void *buffer, unsigned int nbyte), const void *data);
    EAPI void        *ecore_pipe_del(Ecore_Pipe *p);
index 6526ec7..54770e0 100644 (file)
@@ -52,6 +52,9 @@ static int               in_main_loop = 0;
 static int               do_quit = 0;
 static Ecore_Fd_Handler *fd_handlers = NULL;
 static int               fd_handlers_delete_me = 0;
+#ifdef _WIN32
+static Ecore_Win32_Handler *win32_handlers = NULL;
+#endif
 
 #ifdef _WIN32
 static int (*main_loop_select)(int , fd_set *, fd_set *, fd_set *, struct timeval *) = _ecore_main_win32_select;
@@ -216,6 +219,37 @@ ecore_main_fd_handler_add(int fd, Ecore_Fd_Handler_Flags flags, int (*func) (voi
    return fdh;
 }
 
+#ifdef _WIN32
+EAPI Ecore_Win32_Handler *
+ecore_main_win32_handler_add(void *h,
+                             int (*func) (void *data, Ecore_Win32_Handler *wh),
+                             const void *data)
+{
+   Ecore_Win32_Handler *wh;
+
+   if (!h || !func)
+     return NULL;
+
+   wh = calloc(1, sizeof(Ecore_Win32_Handler));
+   if (!wh) return NULL;
+   ECORE_MAGIC_SET(wh, ECORE_MAGIC_WIN32_HANDLER);
+   wh->h = (HANDLE)h;
+   wh->func = func;
+   wh->data = (void *)data;
+   win32_handlers = (Ecore_Win32_Handler *)eina_inlist_append(EINA_INLIST_GET(win32_handlers),
+                                                              EINA_INLIST_GET(wh));
+   return wh;
+}
+#else
+EAPI Ecore_Win32_Handler *
+ecore_main_win32_handler_add(void *h __UNUSED__,
+                             int (*func) (void *data, Ecore_Win32_Handler *wh) __UNUSED__,
+                             const void *data __UNUSED__)
+{
+   return NULL;
+}
+#endif
+
 /**
  * Deletes the given FD handler.
  * @param   fd_handler The given FD handler.
@@ -706,8 +740,11 @@ static int
 _ecore_main_win32_select(int nfds, fd_set *readfds, fd_set *writefds,
                         fd_set *exceptfds, struct timeval *tv)
 {
-   HANDLE events[MAXIMUM_WAIT_OBJECTS];
+   HANDLE objects[MAXIMUM_WAIT_OBJECTS];
    int    sockets[MAXIMUM_WAIT_OBJECTS];
+   Ecore_Win32_Handler *wh;
+   int    objects_nbr = 0;
+   int    handles_nbr = 0;
    int    events_nbr = 0;
    DWORD  result;
    DWORD  timeout;
@@ -733,12 +770,21 @@ _ecore_main_win32_select(int nfds, fd_set *readfds, fd_set *writefds,
          {
              event = WSACreateEvent();
             WSAEventSelect(i, event, network_event);
-            events[events_nbr] = event;
+            objects[objects_nbr] = event;
             sockets[events_nbr] = i;
             events_nbr++;
+             objects_nbr++;
           }
      }
 
+   /* store the HANDLEs in the objects to wait for */
+   EINA_INLIST_FOREACH(win32_handlers, wh)
+     {
+        objects[objects_nbr] = wh->h;
+        handles_nbr++;
+        objects_nbr++;
+     }
+
    /* Empty the queue before waiting */
    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
      {
@@ -753,7 +799,7 @@ _ecore_main_win32_select(int nfds, fd_set *readfds, fd_set *writefds,
    else
      timeout = (DWORD)(tv->tv_sec * 1000.0 + tv->tv_usec / 1000.0);
 
-   result = MsgWaitForMultipleObjects(events_nbr, (const HANDLE *)events, FALSE,
+   result = MsgWaitForMultipleObjects(objects_nbr, (const HANDLE *)objects, FALSE,
                                      timeout, QS_ALLINPUT);
 
    FD_ZERO(readfds);
@@ -765,7 +811,7 @@ _ecore_main_win32_select(int nfds, fd_set *readfds, fd_set *writefds,
      {
         res = 0;
      }
-   else if (result == (WAIT_OBJECT_0 + events_nbr))
+   else if (result == (WAIT_OBJECT_0 + objects_nbr))
      {
         while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
          {
@@ -779,7 +825,7 @@ _ecore_main_win32_select(int nfds, fd_set *readfds, fd_set *writefds,
      {
         WSANETWORKEVENTS network_event;
 
-        WSAEnumNetworkEvents(sockets[result], events[result], &network_event);
+        WSAEnumNetworkEvents(sockets[result], objects[result], &network_event);
 
         if(network_event.lNetworkEvents & FD_READ)
          FD_SET(sockets[result], readfds);
@@ -790,6 +836,15 @@ _ecore_main_win32_select(int nfds, fd_set *readfds, fd_set *writefds,
 
         res = 1;
      }
+   else if ((result >= WAIT_OBJECT_0 + events_nbr) && (result < WAIT_OBJECT_0 + objects_nbr))
+     {
+        EINA_INLIST_FOREACH(win32_handlers, wh)
+          {
+             if (objects[result - WAIT_OBJECT_0] == wh->h)
+               wh->func(wh->data, wh);
+          }
+        res = 1;
+     }
    else
      {
         fprintf(stderr, "unknown result...\n");
@@ -797,7 +852,16 @@ _ecore_main_win32_select(int nfds, fd_set *readfds, fd_set *writefds,
 
    /* Remove event objects again */
    for(i = 0; i < events_nbr; i++)
-     WSACloseEvent(events[i]);
+     WSACloseEvent(objects[i]);
+
+   /* remove HANDLEs */
+   while (win32_handlers)
+     {
+        wh = win32_handlers;
+        win32_handlers = (Ecore_Win32_Handler *)eina_inlist_remove(EINA_INLIST_GET(win32_handlers),
+                                                                   EINA_INLIST_GET(wh));
+        free(wh);
+     }
 
    return res;
 }
index e3ec537..d891088 100644 (file)
 # include <signal.h>
 #endif
 
+#ifdef _WIN32
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+# undef WIN32_LEAN_AND_MEAN
+#endif
+
 #include <Eina.h>
 
 #ifdef EAPI
@@ -81,6 +87,7 @@
 #define ECORE_MAGIC_ANIMATOR        0xf7643ea5
 #define ECORE_MAGIC_POLLER          0xf7568127
 #define ECORE_MAGIC_PIPE            0xf7458226
+#define ECORE_MAGIC_WIN32_HANDLER   0xf7e8f1a3
 
 
 #define ECORE_MAGIC                 Ecore_Magic  __magic
@@ -219,6 +226,9 @@ typedef struct _Ecore_Event         Ecore_Event;
 typedef struct _Ecore_Animator      Ecore_Animator;
 typedef struct _Ecore_Pipe          Ecore_Pipe;
 typedef struct _Ecore_Poller        Ecore_Poller;
+#ifdef _WIN32
+typedef struct _Ecore_Win32_Handler Ecore_Win32_Handler;
+#endif
 
 #ifndef _WIN32
 struct _Ecore_Exe
@@ -316,6 +326,17 @@ struct _Ecore_Fd_Handler
    void                    *prep_data;
 };
 
+#ifdef _WIN32
+struct _Ecore_Win32_Handler
+{
+   EINA_INLIST;
+   ECORE_MAGIC;
+   HANDLE         h;
+   int          (*func) (void *data, Ecore_Win32_Handler *win32_handler);
+   void          *data;
+};
+#endif
+
 struct _Ecore_Event_Handler
 {
    EINA_INLIST;