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 */ | ... | ... |