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,6 +630,7 @@ static int tap_win32_open(tap_win32_overlapped_t **phandle, | ||
| 630 | typedef struct TAPState { | 630 | typedef struct TAPState { |
| 631 | VLANClientState *vc; | 631 | VLANClientState *vc; |
| 632 | tap_win32_overlapped_t *handle; | 632 | tap_win32_overlapped_t *handle; |
| 633 | + HANDLE tap_event; | ||
| 633 | } TAPState; | 634 | } TAPState; |
| 634 | 635 | ||
| 635 | static TAPState *tap_win32_state = NULL; | 636 | static TAPState *tap_win32_state = NULL; |
| @@ -656,6 +657,7 @@ void tap_win32_poll(void) | @@ -656,6 +657,7 @@ void tap_win32_poll(void) | ||
| 656 | if (size > 0) { | 657 | if (size > 0) { |
| 657 | qemu_send_packet(s->vc, buf, size); | 658 | qemu_send_packet(s->vc, buf, size); |
| 658 | tap_win32_free_buffer(s->handle, buf); | 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,5 +678,11 @@ int tap_win32_init(VLANState *vlan, const char *ifname) | ||
| 676 | snprintf(s->vc->info_str, sizeof(s->vc->info_str), | 678 | snprintf(s->vc->info_str, sizeof(s->vc->info_str), |
| 677 | "tap: ifname=%s", ifname); | 679 | "tap: ifname=%s", ifname); |
| 678 | tap_win32_state = s; | 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 | return 0; | 687 | return 0; |
| 680 | } | 688 | } |
vl.c
| @@ -1014,7 +1014,7 @@ static void init_timers(void) | @@ -1014,7 +1014,7 @@ static void init_timers(void) | ||
| 1014 | perror("failed CreateEvent"); | 1014 | perror("failed CreateEvent"); |
| 1015 | exit(1); | 1015 | exit(1); |
| 1016 | } | 1016 | } |
| 1017 | - ResetEvent(host_alarm); | 1017 | + qemu_add_wait_object(host_alarm, NULL, NULL); |
| 1018 | } | 1018 | } |
| 1019 | pit_min_timer_count = ((uint64_t)10000 * PIT_FREQ) / 1000000; | 1019 | pit_min_timer_count = ((uint64_t)10000 * PIT_FREQ) / 1000000; |
| 1020 | #else | 1020 | #else |
| @@ -3962,6 +3962,51 @@ void qemu_del_polling_cb(PollingFunc *func, void *opaque) | @@ -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 | /* savevm/loadvm support */ | 4011 | /* savevm/loadvm support */ |
| 3967 | 4012 | ||
| @@ -4838,21 +4883,18 @@ void main_loop_wait(int timeout) | @@ -4838,21 +4883,18 @@ void main_loop_wait(int timeout) | ||
| 4838 | } | 4883 | } |
| 4839 | #ifdef _WIN32 | 4884 | #ifdef _WIN32 |
| 4840 | if (ret == 0 && timeout > 0) { | 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 | #endif | 4899 | #endif |
| 4858 | /* poll any events */ | 4900 | /* poll any events */ |
vl.h
| @@ -47,6 +47,7 @@ | @@ -47,6 +47,7 @@ | ||
| 47 | #endif | 47 | #endif |
| 48 | 48 | ||
| 49 | #ifdef _WIN32 | 49 | #ifdef _WIN32 |
| 50 | +#include <windows.h> | ||
| 50 | #define fsync _commit | 51 | #define fsync _commit |
| 51 | #define lseek _lseeki64 | 52 | #define lseek _lseeki64 |
| 52 | #define ENOTSUP 4096 | 53 | #define ENOTSUP 4096 |
| @@ -221,6 +222,14 @@ typedef int PollingFunc(void *opaque); | @@ -221,6 +222,14 @@ typedef int PollingFunc(void *opaque); | ||
| 221 | int qemu_add_polling_cb(PollingFunc *func, void *opaque); | 222 | int qemu_add_polling_cb(PollingFunc *func, void *opaque); |
| 222 | void qemu_del_polling_cb(PollingFunc *func, void *opaque); | 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 | /* character device */ | 233 | /* character device */ |
| 225 | 234 | ||
| 226 | #define CHR_EVENT_BREAK 0 /* serial break char */ | 235 | #define CHR_EVENT_BREAK 0 /* serial break char */ |