1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
|
static int
_ecore_main_win32_select(int nfds __UNUSED__, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *tv)
{
HANDLE objects[MAXIMUM_WAIT_OBJECTS];
int sockets[MAXIMUM_WAIT_OBJECTS];
Ecore_Fd_Handler *fdh;
Ecore_Win32_Handler *wh;
unsigned int objects_nbr = 0;
unsigned int handles_nbr = 0;
unsigned int events_nbr = 0;
DWORD result;
DWORD timeout;
MSG msg;
unsigned int i;
int res;
/* Create an event object per socket */
EINA_INLIST_FOREACH(fd_handlers, fdh)
{
WSAEVENT event;
long network_event;
network_event = 0;
if (FD_ISSET(fdh->fd, readfds))
network_event |= FD_READ;
if (FD_ISSET(fdh->fd, writefds))
network_event |= FD_WRITE;
if (FD_ISSET(fdh->fd, exceptfds))
network_event |= FD_OOB;
if (network_event)
{
event = WSACreateEvent();
WSAEventSelect(fdh->fd, event, network_event);
objects[objects_nbr] = event;
sockets[events_nbr] = fdh->fd;
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))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
/* Wait for any message sent or posted to this queue */
/* or for one of the passed handles be set to signaled. */
if (!tv)
timeout = INFINITE;
else
timeout = (DWORD)((tv->tv_sec * 1000.0) + (tv->tv_usec / 1000.0));
if (timeout == 0) return 0;
result = MsgWaitForMultipleObjects(objects_nbr, (const HANDLE *)objects, EINA_FALSE,
timeout, QS_ALLINPUT);
FD_ZERO(readfds);
FD_ZERO(writefds);
FD_ZERO(exceptfds);
/* The result tells us the type of event we have. */
if (result == WAIT_FAILED)
{
char *msg;
msg = evil_last_error_get();
ERR(" * %s\n", msg);
free(msg);
res = -1;
}
else if (result == WAIT_TIMEOUT)
{
/* ERR("time out\n"); */
res = 0;
}
else if (result == (WAIT_OBJECT_0 + objects_nbr))
{
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
res = 0;
}
else if ((result >= 0) && (result < WAIT_OBJECT_0 + events_nbr))
{
WSANETWORKEVENTS network_event;
WSAEnumNetworkEvents(sockets[result], objects[result], &network_event);
if (network_event.lNetworkEvents & FD_READ)
FD_SET(sockets[result], readfds);
if (network_event.lNetworkEvents & FD_WRITE)
FD_SET(sockets[result], writefds);
if (network_event.lNetworkEvents & FD_OOB)
FD_SET(sockets[result], exceptfds);
res = 1;
}
else if ((result >= (WAIT_OBJECT_0 + events_nbr)) &&
(result < (WAIT_OBJECT_0 + objects_nbr)))
{
if (!win32_handler_current)
{
/* regular main loop, start from head */
win32_handler_current = win32_handlers;
}
else
{
/* recursive main loop, continue from where we were */
win32_handler_current = (Ecore_Win32_Handler *)EINA_INLIST_GET(win32_handler_current)->next;
}
while (win32_handler_current)
{
wh = win32_handler_current;
if (objects[result - WAIT_OBJECT_0] == wh->h)
{
if (!wh->delete_me)
{
wh->references++;
if (!wh->func(wh->data, wh))
{
wh->delete_me = 1;
win32_handlers_delete_me = 1;
}
wh->references--;
}
}
if (win32_handler_current) /* may have changed in recursive main loops */
win32_handler_current = (Ecore_Win32_Handler *)EINA_INLIST_GET(win32_handler_current)->next;
}
res = 1;
}
else
{
ERR("unknown result...\n");
res = -1;
}
/* Remove event objects again */
for (i = 0; i < events_nbr; i++) WSACloseEvent(objects[i]);
return res;
} |
Partager