From: caro Date: Sun, 25 Oct 2009 07:07:48 +0000 (+0000) Subject: wait on HANDLES in the select loop on Windows. X-Git-Tag: build/2012-07-04.173327~2414 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=5ba31f4a2bfbbac7f825761a5c9b8a21480b2618;p=profile%2Fivi%2Fecore.git wait on HANDLES in the select loop on Windows. git-svn-id: http://svn.enlightenment.org/svn/e/trunk/ecore@43253 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- diff --git a/src/lib/ecore/Ecore.h b/src/lib/ecore/Ecore.h index b1e2145..bce3bf3 100644 --- a/src/lib/ecore/Ecore.h +++ b/src/lib/ecore/Ecore.h @@ -56,10 +56,10 @@ #elif defined (__FreeBSD__) && (__FreeBSD_version >= 420001) # include #else -# include # include # include #endif +#include #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); diff --git a/src/lib/ecore/ecore_main.c b/src/lib/ecore/ecore_main.c index 6526ec7..54770e0 100644 --- a/src/lib/ecore/ecore_main.c +++ b/src/lib/ecore/ecore_main.c @@ -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; } diff --git a/src/lib/ecore/ecore_private.h b/src/lib/ecore/ecore_private.h index e3ec537..d891088 100644 --- a/src/lib/ecore/ecore_private.h +++ b/src/lib/ecore/ecore_private.h @@ -11,6 +11,12 @@ # include #endif +#ifdef _WIN32 +# define WIN32_LEAN_AND_MEAN +# include +# undef WIN32_LEAN_AND_MEAN +#endif + #include #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;