00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "includes.h"
00016 #include <winsock2.h>
00017
00018 #include "common.h"
00019 #include "eloop.h"
00020
00021
00022 struct eloop_sock {
00023 int sock;
00024 void *eloop_data;
00025 void *user_data;
00026 eloop_sock_handler handler;
00027 WSAEVENT event;
00028 };
00029
00030 struct eloop_event {
00031 void *eloop_data;
00032 void *user_data;
00033 eloop_event_handler handler;
00034 HANDLE event;
00035 };
00036
00037 struct eloop_timeout {
00038 struct os_time time;
00039 void *eloop_data;
00040 void *user_data;
00041 eloop_timeout_handler handler;
00042 struct eloop_timeout *next;
00043 };
00044
00045 struct eloop_signal {
00046 int sig;
00047 void *user_data;
00048 eloop_signal_handler handler;
00049 int signaled;
00050 };
00051
00052 struct eloop_data {
00053 int max_sock;
00054 size_t reader_count;
00055 struct eloop_sock *readers;
00056
00057 size_t event_count;
00058 struct eloop_event *events;
00059
00060 struct eloop_timeout *timeout;
00061
00062 int signal_count;
00063 struct eloop_signal *signals;
00064 int signaled;
00065 int pending_terminate;
00066
00067 int terminate;
00068 int reader_table_changed;
00069
00070 struct eloop_signal term_signal;
00071 HANDLE term_event;
00072
00073 HANDLE *handles;
00074 size_t num_handles;
00075 };
00076
00077 static struct eloop_data eloop;
00078
00079
00080 int eloop_init(void)
00081 {
00082 os_memset(&eloop, 0, sizeof(eloop));
00083 eloop.num_handles = 1;
00084 eloop.handles = os_malloc(eloop.num_handles *
00085 sizeof(eloop.handles[0]));
00086 if (eloop.handles == NULL)
00087 return -1;
00088
00089 eloop.term_event = CreateEvent(NULL, FALSE, FALSE, NULL);
00090 if (eloop.term_event == NULL) {
00091 printf("CreateEvent() failed: %d\n",
00092 (int) GetLastError());
00093 os_free(eloop.handles);
00094 return -1;
00095 }
00096
00097 return 0;
00098 }
00099
00100
00101 static int eloop_prepare_handles(void)
00102 {
00103 HANDLE *n;
00104
00105 if (eloop.num_handles > eloop.reader_count + eloop.event_count + 8)
00106 return 0;
00107 n = os_realloc(eloop.handles,
00108 eloop.num_handles * 2 * sizeof(eloop.handles[0]));
00109 if (n == NULL)
00110 return -1;
00111 eloop.handles = n;
00112 eloop.num_handles *= 2;
00113 return 0;
00114 }
00115
00116
00117 int eloop_register_read_sock(int sock, eloop_sock_handler handler,
00118 void *eloop_data, void *user_data)
00119 {
00120 WSAEVENT event;
00121 struct eloop_sock *tmp;
00122
00123 if (eloop_prepare_handles())
00124 return -1;
00125
00126 event = WSACreateEvent();
00127 if (event == WSA_INVALID_EVENT) {
00128 printf("WSACreateEvent() failed: %d\n", WSAGetLastError());
00129 return -1;
00130 }
00131
00132 if (WSAEventSelect(sock, event, FD_READ)) {
00133 printf("WSAEventSelect() failed: %d\n", WSAGetLastError());
00134 WSACloseEvent(event);
00135 return -1;
00136 }
00137 tmp = os_realloc(eloop.readers,
00138 (eloop.reader_count + 1) * sizeof(struct eloop_sock));
00139 if (tmp == NULL) {
00140 WSAEventSelect(sock, event, 0);
00141 WSACloseEvent(event);
00142 return -1;
00143 }
00144
00145 tmp[eloop.reader_count].sock = sock;
00146 tmp[eloop.reader_count].eloop_data = eloop_data;
00147 tmp[eloop.reader_count].user_data = user_data;
00148 tmp[eloop.reader_count].handler = handler;
00149 tmp[eloop.reader_count].event = event;
00150 eloop.reader_count++;
00151 eloop.readers = tmp;
00152 if (sock > eloop.max_sock)
00153 eloop.max_sock = sock;
00154 eloop.reader_table_changed = 1;
00155
00156 return 0;
00157 }
00158
00159
00160 void eloop_unregister_read_sock(int sock)
00161 {
00162 size_t i;
00163
00164 if (eloop.readers == NULL || eloop.reader_count == 0)
00165 return;
00166
00167 for (i = 0; i < eloop.reader_count; i++) {
00168 if (eloop.readers[i].sock == sock)
00169 break;
00170 }
00171 if (i == eloop.reader_count)
00172 return;
00173
00174 WSAEventSelect(eloop.readers[i].sock, eloop.readers[i].event, 0);
00175 WSACloseEvent(eloop.readers[i].event);
00176
00177 if (i != eloop.reader_count - 1) {
00178 os_memmove(&eloop.readers[i], &eloop.readers[i + 1],
00179 (eloop.reader_count - i - 1) *
00180 sizeof(struct eloop_sock));
00181 }
00182 eloop.reader_count--;
00183 eloop.reader_table_changed = 1;
00184 }
00185
00186
00187 int eloop_register_event(void *event, size_t event_size,
00188 eloop_event_handler handler,
00189 void *eloop_data, void *user_data)
00190 {
00191 struct eloop_event *tmp;
00192 HANDLE h = event;
00193
00194 if (event_size != sizeof(HANDLE) || h == INVALID_HANDLE_VALUE)
00195 return -1;
00196
00197 if (eloop_prepare_handles())
00198 return -1;
00199
00200 tmp = os_realloc(eloop.events,
00201 (eloop.event_count + 1) * sizeof(struct eloop_event));
00202 if (tmp == NULL)
00203 return -1;
00204
00205 tmp[eloop.event_count].eloop_data = eloop_data;
00206 tmp[eloop.event_count].user_data = user_data;
00207 tmp[eloop.event_count].handler = handler;
00208 tmp[eloop.event_count].event = h;
00209 eloop.event_count++;
00210 eloop.events = tmp;
00211
00212 return 0;
00213 }
00214
00215
00216 void eloop_unregister_event(void *event, size_t event_size)
00217 {
00218 size_t i;
00219 HANDLE h = event;
00220
00221 if (eloop.events == NULL || eloop.event_count == 0 ||
00222 event_size != sizeof(HANDLE))
00223 return;
00224
00225 for (i = 0; i < eloop.event_count; i++) {
00226 if (eloop.events[i].event == h)
00227 break;
00228 }
00229 if (i == eloop.event_count)
00230 return;
00231
00232 if (i != eloop.event_count - 1) {
00233 os_memmove(&eloop.events[i], &eloop.events[i + 1],
00234 (eloop.event_count - i - 1) *
00235 sizeof(struct eloop_event));
00236 }
00237 eloop.event_count--;
00238 }
00239
00240
00241 int eloop_register_timeout(unsigned int secs, unsigned int usecs,
00242 eloop_timeout_handler handler,
00243 void *eloop_data, void *user_data)
00244 {
00245 struct eloop_timeout *timeout, *tmp, *prev;
00246
00247 timeout = os_malloc(sizeof(*timeout));
00248 if (timeout == NULL)
00249 return -1;
00250 os_get_time(&timeout->time);
00251 timeout->time.sec += secs;
00252 timeout->time.usec += usecs;
00253 while (timeout->time.usec >= 1000000) {
00254 timeout->time.sec++;
00255 timeout->time.usec -= 1000000;
00256 }
00257 timeout->eloop_data = eloop_data;
00258 timeout->user_data = user_data;
00259 timeout->handler = handler;
00260 timeout->next = NULL;
00261
00262 if (eloop.timeout == NULL) {
00263 eloop.timeout = timeout;
00264 return 0;
00265 }
00266
00267 prev = NULL;
00268 tmp = eloop.timeout;
00269 while (tmp != NULL) {
00270 if (os_time_before(&timeout->time, &tmp->time))
00271 break;
00272 prev = tmp;
00273 tmp = tmp->next;
00274 }
00275
00276 if (prev == NULL) {
00277 timeout->next = eloop.timeout;
00278 eloop.timeout = timeout;
00279 } else {
00280 timeout->next = prev->next;
00281 prev->next = timeout;
00282 }
00283
00284 return 0;
00285 }
00286
00287
00288 int eloop_cancel_timeout(eloop_timeout_handler handler,
00289 void *eloop_data, void *user_data)
00290 {
00291 struct eloop_timeout *timeout, *prev, *next;
00292 int removed = 0;
00293
00294 prev = NULL;
00295 timeout = eloop.timeout;
00296 while (timeout != NULL) {
00297 next = timeout->next;
00298
00299 if (timeout->handler == handler &&
00300 (timeout->eloop_data == eloop_data ||
00301 eloop_data == ELOOP_ALL_CTX) &&
00302 (timeout->user_data == user_data ||
00303 user_data == ELOOP_ALL_CTX)) {
00304 if (prev == NULL)
00305 eloop.timeout = next;
00306 else
00307 prev->next = next;
00308 os_free(timeout);
00309 removed++;
00310 } else
00311 prev = timeout;
00312
00313 timeout = next;
00314 }
00315
00316 return removed;
00317 }
00318
00319
00320 int eloop_is_timeout_registered(eloop_timeout_handler handler,
00321 void *eloop_data, void *user_data)
00322 {
00323 struct eloop_timeout *tmp;
00324
00325 tmp = eloop.timeout;
00326 while (tmp != NULL) {
00327 if (tmp->handler == handler &&
00328 tmp->eloop_data == eloop_data &&
00329 tmp->user_data == user_data)
00330 return 1;
00331
00332 tmp = tmp->next;
00333 }
00334
00335 return 0;
00336 }
00337
00338
00339
00340 #if 0
00341 static void eloop_handle_signal(int sig)
00342 {
00343 int i;
00344
00345 eloop.signaled++;
00346 for (i = 0; i < eloop.signal_count; i++) {
00347 if (eloop.signals[i].sig == sig) {
00348 eloop.signals[i].signaled++;
00349 break;
00350 }
00351 }
00352 }
00353 #endif
00354
00355
00356 static void eloop_process_pending_signals(void)
00357 {
00358 int i;
00359
00360 if (eloop.signaled == 0)
00361 return;
00362 eloop.signaled = 0;
00363
00364 if (eloop.pending_terminate) {
00365 eloop.pending_terminate = 0;
00366 }
00367
00368 for (i = 0; i < eloop.signal_count; i++) {
00369 if (eloop.signals[i].signaled) {
00370 eloop.signals[i].signaled = 0;
00371 eloop.signals[i].handler(eloop.signals[i].sig,
00372 eloop.signals[i].user_data);
00373 }
00374 }
00375
00376 if (eloop.term_signal.signaled) {
00377 eloop.term_signal.signaled = 0;
00378 eloop.term_signal.handler(eloop.term_signal.sig,
00379 eloop.term_signal.user_data);
00380 }
00381 }
00382
00383
00384 int eloop_register_signal(int sig, eloop_signal_handler handler,
00385 void *user_data)
00386 {
00387 struct eloop_signal *tmp;
00388
00389 tmp = os_realloc(eloop.signals,
00390 (eloop.signal_count + 1) *
00391 sizeof(struct eloop_signal));
00392 if (tmp == NULL)
00393 return -1;
00394
00395 tmp[eloop.signal_count].sig = sig;
00396 tmp[eloop.signal_count].user_data = user_data;
00397 tmp[eloop.signal_count].handler = handler;
00398 tmp[eloop.signal_count].signaled = 0;
00399 eloop.signal_count++;
00400 eloop.signals = tmp;
00401
00402
00403
00404 return 0;
00405 }
00406
00407
00408 #ifndef _WIN32_WCE
00409 static BOOL eloop_handle_console_ctrl(DWORD type)
00410 {
00411 switch (type) {
00412 case CTRL_C_EVENT:
00413 case CTRL_BREAK_EVENT:
00414 eloop.signaled++;
00415 eloop.term_signal.signaled++;
00416 SetEvent(eloop.term_event);
00417 return TRUE;
00418 default:
00419 return FALSE;
00420 }
00421 }
00422 #endif
00423
00424
00425 int eloop_register_signal_terminate(eloop_signal_handler handler,
00426 void *user_data)
00427 {
00428 #ifndef _WIN32_WCE
00429 if (SetConsoleCtrlHandler((PHANDLER_ROUTINE) eloop_handle_console_ctrl,
00430 TRUE) == 0) {
00431 printf("SetConsoleCtrlHandler() failed: %d\n",
00432 (int) GetLastError());
00433 return -1;
00434 }
00435 #endif
00436
00437 eloop.term_signal.handler = handler;
00438 eloop.term_signal.user_data = user_data;
00439
00440 return 0;
00441 }
00442
00443
00444 int eloop_register_signal_reconfig(eloop_signal_handler handler,
00445 void *user_data)
00446 {
00447
00448 return 0;
00449 }
00450
00451
00452 void eloop_run(void)
00453 {
00454 struct os_time tv, now;
00455 DWORD count, ret, timeout, err;
00456 size_t i;
00457
00458 while (!eloop.terminate &&
00459 (eloop.timeout || eloop.reader_count > 0 ||
00460 eloop.event_count > 0)) {
00461 tv.sec = tv.usec = 0;
00462 if (eloop.timeout) {
00463 os_get_time(&now);
00464 if (os_time_before(&now, &eloop.timeout->time))
00465 os_time_sub(&eloop.timeout->time, &now, &tv);
00466 }
00467
00468 count = 0;
00469 for (i = 0; i < eloop.event_count; i++)
00470 eloop.handles[count++] = eloop.events[i].event;
00471
00472 for (i = 0; i < eloop.reader_count; i++)
00473 eloop.handles[count++] = eloop.readers[i].event;
00474
00475 if (eloop.term_event)
00476 eloop.handles[count++] = eloop.term_event;
00477
00478 if (eloop.timeout)
00479 timeout = tv.sec * 1000 + tv.usec / 1000;
00480 else
00481 timeout = INFINITE;
00482
00483 if (count > MAXIMUM_WAIT_OBJECTS) {
00484 printf("WaitForMultipleObjects: Too many events: "
00485 "%d > %d (ignoring extra events)\n",
00486 (int) count, MAXIMUM_WAIT_OBJECTS);
00487 count = MAXIMUM_WAIT_OBJECTS;
00488 }
00489 #ifdef _WIN32_WCE
00490 ret = WaitForMultipleObjects(count, eloop.handles, FALSE,
00491 timeout);
00492 #else
00493 ret = WaitForMultipleObjectsEx(count, eloop.handles, FALSE,
00494 timeout, TRUE);
00495 #endif
00496 err = GetLastError();
00497
00498 eloop_process_pending_signals();
00499
00500
00501 if (eloop.timeout) {
00502 struct eloop_timeout *tmp;
00503
00504 os_get_time(&now);
00505 if (!os_time_before(&now, &eloop.timeout->time)) {
00506 tmp = eloop.timeout;
00507 eloop.timeout = eloop.timeout->next;
00508 tmp->handler(tmp->eloop_data,
00509 tmp->user_data);
00510 os_free(tmp);
00511 }
00512
00513 }
00514
00515 if (ret == WAIT_FAILED) {
00516 printf("WaitForMultipleObjects(count=%d) failed: %d\n",
00517 (int) count, (int) err);
00518 os_sleep(1, 0);
00519 continue;
00520 }
00521
00522 #ifndef _WIN32_WCE
00523 if (ret == WAIT_IO_COMPLETION)
00524 continue;
00525 #endif
00526
00527 if (ret == WAIT_TIMEOUT)
00528 continue;
00529
00530 while (ret >= WAIT_OBJECT_0 &&
00531 ret < WAIT_OBJECT_0 + eloop.event_count) {
00532 eloop.events[ret].handler(
00533 eloop.events[ret].eloop_data,
00534 eloop.events[ret].user_data);
00535 ret = WaitForMultipleObjects(eloop.event_count,
00536 eloop.handles, FALSE, 0);
00537 }
00538
00539 eloop.reader_table_changed = 0;
00540 for (i = 0; i < eloop.reader_count; i++) {
00541 WSANETWORKEVENTS events;
00542 if (WSAEnumNetworkEvents(eloop.readers[i].sock,
00543 eloop.readers[i].event,
00544 &events) == 0 &&
00545 (events.lNetworkEvents & FD_READ)) {
00546 eloop.readers[i].handler(
00547 eloop.readers[i].sock,
00548 eloop.readers[i].eloop_data,
00549 eloop.readers[i].user_data);
00550 if (eloop.reader_table_changed)
00551 break;
00552 }
00553 }
00554 }
00555 }
00556
00557
00558 void eloop_terminate(void)
00559 {
00560 eloop.terminate = 1;
00561 SetEvent(eloop.term_event);
00562 }
00563
00564
00565 void eloop_destroy(void)
00566 {
00567 struct eloop_timeout *timeout, *prev;
00568
00569 timeout = eloop.timeout;
00570 while (timeout != NULL) {
00571 prev = timeout;
00572 timeout = timeout->next;
00573 os_free(prev);
00574 }
00575 os_free(eloop.readers);
00576 os_free(eloop.signals);
00577 if (eloop.term_event)
00578 CloseHandle(eloop.term_event);
00579 os_free(eloop.handles);
00580 eloop.handles = NULL;
00581 os_free(eloop.events);
00582 eloop.events = NULL;
00583 }
00584
00585
00586 int eloop_terminated(void)
00587 {
00588 return eloop.terminate;
00589 }
00590
00591
00592 void eloop_wait_for_read_sock(int sock)
00593 {
00594 WSAEVENT event;
00595
00596 event = WSACreateEvent();
00597 if (event == WSA_INVALID_EVENT) {
00598 printf("WSACreateEvent() failed: %d\n", WSAGetLastError());
00599 return;
00600 }
00601
00602 if (WSAEventSelect(sock, event, FD_READ)) {
00603 printf("WSAEventSelect() failed: %d\n", WSAGetLastError());
00604 WSACloseEvent(event);
00605 return ;
00606 }
00607
00608 WaitForSingleObject(event, INFINITE);
00609 WSAEventSelect(sock, event, 0);
00610 WSACloseEvent(event);
00611 }