Commit a18e524af0c23b083dc69f9a2eed563893d01f22
1 parent
e15d7371
multiple wait object support for win32 (kazu)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2013 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
75 additions
and
16 deletions
tap-win32.c
| ... | ... | @@ -630,6 +630,7 @@ static int tap_win32_open(tap_win32_overlapped_t **phandle, |
| 630 | 630 | typedef struct TAPState { |
| 631 | 631 | VLANClientState *vc; |
| 632 | 632 | tap_win32_overlapped_t *handle; |
| 633 | + HANDLE tap_event; | |
| 633 | 634 | } TAPState; |
| 634 | 635 | |
| 635 | 636 | static TAPState *tap_win32_state = NULL; |
| ... | ... | @@ -656,6 +657,7 @@ void tap_win32_poll(void) |
| 656 | 657 | if (size > 0) { |
| 657 | 658 | qemu_send_packet(s->vc, buf, size); |
| 658 | 659 | tap_win32_free_buffer(s->handle, buf); |
| 660 | + SetEvent(s->tap_event); | |
| 659 | 661 | } |
| 660 | 662 | } |
| 661 | 663 | |
| ... | ... | @@ -676,5 +678,11 @@ int tap_win32_init(VLANState *vlan, const char *ifname) |
| 676 | 678 | snprintf(s->vc->info_str, sizeof(s->vc->info_str), |
| 677 | 679 | "tap: ifname=%s", ifname); |
| 678 | 680 | tap_win32_state = s; |
| 681 | + | |
| 682 | + s->tap_event = CreateEvent(NULL, FALSE, FALSE, NULL); | |
| 683 | + if (!s->tap_event) { | |
| 684 | + fprintf(stderr, "tap-win32: Failed CreateEvent\n"); | |
| 685 | + } | |
| 686 | + qemu_add_wait_object(s->tap_event, NULL, NULL); | |
| 679 | 687 | return 0; |
| 680 | 688 | } | ... | ... |
vl.c
| ... | ... | @@ -1014,7 +1014,7 @@ static void init_timers(void) |
| 1014 | 1014 | perror("failed CreateEvent"); |
| 1015 | 1015 | exit(1); |
| 1016 | 1016 | } |
| 1017 | - ResetEvent(host_alarm); | |
| 1017 | + qemu_add_wait_object(host_alarm, NULL, NULL); | |
| 1018 | 1018 | } |
| 1019 | 1019 | pit_min_timer_count = ((uint64_t)10000 * PIT_FREQ) / 1000000; |
| 1020 | 1020 | #else |
| ... | ... | @@ -3962,6 +3962,51 @@ void qemu_del_polling_cb(PollingFunc *func, void *opaque) |
| 3962 | 3962 | } |
| 3963 | 3963 | } |
| 3964 | 3964 | |
| 3965 | +#ifdef _WIN32 | |
| 3966 | +/***********************************************************/ | |
| 3967 | +/* Wait objects support */ | |
| 3968 | +typedef struct WaitObjects { | |
| 3969 | + int num; | |
| 3970 | + HANDLE events[MAXIMUM_WAIT_OBJECTS + 1]; | |
| 3971 | + WaitObjectFunc *func[MAXIMUM_WAIT_OBJECTS + 1]; | |
| 3972 | + void *opaque[MAXIMUM_WAIT_OBJECTS + 1]; | |
| 3973 | +} WaitObjects; | |
| 3974 | + | |
| 3975 | +static WaitObjects wait_objects = {0}; | |
| 3976 | + | |
| 3977 | +int qemu_add_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque) | |
| 3978 | +{ | |
| 3979 | + WaitObjects *w = &wait_objects; | |
| 3980 | + | |
| 3981 | + if (w->num >= MAXIMUM_WAIT_OBJECTS) | |
| 3982 | + return -1; | |
| 3983 | + w->events[w->num] = handle; | |
| 3984 | + w->func[w->num] = func; | |
| 3985 | + w->opaque[w->num] = opaque; | |
| 3986 | + w->num++; | |
| 3987 | + return 0; | |
| 3988 | +} | |
| 3989 | + | |
| 3990 | +void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque) | |
| 3991 | +{ | |
| 3992 | + int i, found; | |
| 3993 | + WaitObjects *w = &wait_objects; | |
| 3994 | + | |
| 3995 | + found = 0; | |
| 3996 | + for (i = 0; i < w->num; i++) { | |
| 3997 | + if (w->events[i] == handle) | |
| 3998 | + found = 1; | |
| 3999 | + if (found) { | |
| 4000 | + w->events[i] = w->events[i + 1]; | |
| 4001 | + w->func[i] = w->func[i + 1]; | |
| 4002 | + w->opaque[i] = w->opaque[i + 1]; | |
| 4003 | + } | |
| 4004 | + } | |
| 4005 | + if (found) | |
| 4006 | + w->num--; | |
| 4007 | +} | |
| 4008 | +#endif | |
| 4009 | + | |
| 3965 | 4010 | /***********************************************************/ |
| 3966 | 4011 | /* savevm/loadvm support */ |
| 3967 | 4012 | |
| ... | ... | @@ -4838,21 +4883,18 @@ void main_loop_wait(int timeout) |
| 4838 | 4883 | } |
| 4839 | 4884 | #ifdef _WIN32 |
| 4840 | 4885 | if (ret == 0 && timeout > 0) { |
| 4841 | - int err; | |
| 4842 | - HANDLE hEvents[1]; | |
| 4843 | - | |
| 4844 | - hEvents[0] = host_alarm; | |
| 4845 | - ret = WaitForMultipleObjects(1, hEvents, FALSE, timeout); | |
| 4846 | - switch(ret) { | |
| 4847 | - case WAIT_OBJECT_0 + 0: | |
| 4848 | - break; | |
| 4849 | - case WAIT_TIMEOUT: | |
| 4850 | - break; | |
| 4851 | - default: | |
| 4852 | - err = GetLastError(); | |
| 4853 | - fprintf(stderr, "Wait error %d %d\n", ret, err); | |
| 4854 | - break; | |
| 4855 | - } | |
| 4886 | + int err; | |
| 4887 | + WaitObjects *w = &wait_objects; | |
| 4888 | + | |
| 4889 | + ret = WaitForMultipleObjects(w->num, w->events, FALSE, timeout); | |
| 4890 | + if (WAIT_OBJECT_0 + 0 <= ret && ret <= WAIT_OBJECT_0 + w->num - 1) { | |
| 4891 | + if (w->func[ret - WAIT_OBJECT_0]) | |
| 4892 | + w->func[ret - WAIT_OBJECT_0](w->opaque[ret - WAIT_OBJECT_0]); | |
| 4893 | + } else if (ret == WAIT_TIMEOUT) { | |
| 4894 | + } else { | |
| 4895 | + err = GetLastError(); | |
| 4896 | + fprintf(stderr, "Wait error %d %d\n", ret, err); | |
| 4897 | + } | |
| 4856 | 4898 | } |
| 4857 | 4899 | #endif |
| 4858 | 4900 | /* poll any events */ | ... | ... |
vl.h
| ... | ... | @@ -47,6 +47,7 @@ |
| 47 | 47 | #endif |
| 48 | 48 | |
| 49 | 49 | #ifdef _WIN32 |
| 50 | +#include <windows.h> | |
| 50 | 51 | #define fsync _commit |
| 51 | 52 | #define lseek _lseeki64 |
| 52 | 53 | #define ENOTSUP 4096 |
| ... | ... | @@ -221,6 +222,14 @@ typedef int PollingFunc(void *opaque); |
| 221 | 222 | int qemu_add_polling_cb(PollingFunc *func, void *opaque); |
| 222 | 223 | void qemu_del_polling_cb(PollingFunc *func, void *opaque); |
| 223 | 224 | |
| 225 | +#ifdef _WIN32 | |
| 226 | +/* Wait objects handling */ | |
| 227 | +typedef void WaitObjectFunc(void *opaque); | |
| 228 | + | |
| 229 | +int qemu_add_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque); | |
| 230 | +void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque); | |
| 231 | +#endif | |
| 232 | + | |
| 224 | 233 | /* character device */ |
| 225 | 234 | |
| 226 | 235 | #define CHR_EVENT_BREAK 0 /* serial break char */ | ... | ... |