wait on HANDLES in the select loop on Windows.

SVN revision: 43253
This commit is contained in:
Vincent Torri 2009-10-25 07:07:48 +00:00
parent 2e25a97c11
commit f5fec31eb9
3 changed files with 95 additions and 8 deletions

View File

@ -56,10 +56,10 @@
#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);

View 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;
}

View File

@ -11,6 +11,12 @@
# 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;