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