diff options
-rw-r--r-- | tap-win32.c | 8 | ||||
-rw-r--r-- | vl.c | 74 | ||||
-rw-r--r-- | vl.h | 9 |
3 files changed, 75 insertions, 16 deletions
diff --git a/tap-win32.c b/tap-win32.c index b6056955c0..af5e25e683 100644 --- a/tap-win32.c +++ b/tap-win32.c @@ -630,6 +630,7 @@ static int tap_win32_open(tap_win32_overlapped_t **phandle, typedef struct TAPState { VLANClientState *vc; tap_win32_overlapped_t *handle; + HANDLE tap_event; } TAPState; static TAPState *tap_win32_state = NULL; @@ -656,6 +657,7 @@ void tap_win32_poll(void) if (size > 0) { qemu_send_packet(s->vc, buf, size); tap_win32_free_buffer(s->handle, buf); + SetEvent(s->tap_event); } } @@ -676,5 +678,11 @@ int tap_win32_init(VLANState *vlan, const char *ifname) snprintf(s->vc->info_str, sizeof(s->vc->info_str), "tap: ifname=%s", ifname); tap_win32_state = s; + + s->tap_event = CreateEvent(NULL, FALSE, FALSE, NULL); + if (!s->tap_event) { + fprintf(stderr, "tap-win32: Failed CreateEvent\n"); + } + qemu_add_wait_object(s->tap_event, NULL, NULL); return 0; } @@ -1014,7 +1014,7 @@ static void init_timers(void) perror("failed CreateEvent"); exit(1); } - ResetEvent(host_alarm); + qemu_add_wait_object(host_alarm, NULL, NULL); } pit_min_timer_count = ((uint64_t)10000 * PIT_FREQ) / 1000000; #else @@ -3962,6 +3962,51 @@ void qemu_del_polling_cb(PollingFunc *func, void *opaque) } } +#ifdef _WIN32 +/***********************************************************/ +/* Wait objects support */ +typedef struct WaitObjects { + int num; + HANDLE events[MAXIMUM_WAIT_OBJECTS + 1]; + WaitObjectFunc *func[MAXIMUM_WAIT_OBJECTS + 1]; + void *opaque[MAXIMUM_WAIT_OBJECTS + 1]; +} WaitObjects; + +static WaitObjects wait_objects = {0}; + +int qemu_add_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque) +{ + WaitObjects *w = &wait_objects; + + if (w->num >= MAXIMUM_WAIT_OBJECTS) + return -1; + w->events[w->num] = handle; + w->func[w->num] = func; + w->opaque[w->num] = opaque; + w->num++; + return 0; +} + +void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque) +{ + int i, found; + WaitObjects *w = &wait_objects; + + found = 0; + for (i = 0; i < w->num; i++) { + if (w->events[i] == handle) + found = 1; + if (found) { + w->events[i] = w->events[i + 1]; + w->func[i] = w->func[i + 1]; + w->opaque[i] = w->opaque[i + 1]; + } + } + if (found) + w->num--; +} +#endif + /***********************************************************/ /* savevm/loadvm support */ @@ -4838,21 +4883,18 @@ void main_loop_wait(int timeout) } #ifdef _WIN32 if (ret == 0 && timeout > 0) { - int err; - HANDLE hEvents[1]; - - hEvents[0] = host_alarm; - ret = WaitForMultipleObjects(1, hEvents, FALSE, timeout); - switch(ret) { - case WAIT_OBJECT_0 + 0: - break; - case WAIT_TIMEOUT: - break; - default: - err = GetLastError(); - fprintf(stderr, "Wait error %d %d\n", ret, err); - break; - } + int err; + WaitObjects *w = &wait_objects; + + ret = WaitForMultipleObjects(w->num, w->events, FALSE, timeout); + if (WAIT_OBJECT_0 + 0 <= ret && ret <= WAIT_OBJECT_0 + w->num - 1) { + if (w->func[ret - WAIT_OBJECT_0]) + w->func[ret - WAIT_OBJECT_0](w->opaque[ret - WAIT_OBJECT_0]); + } else if (ret == WAIT_TIMEOUT) { + } else { + err = GetLastError(); + fprintf(stderr, "Wait error %d %d\n", ret, err); + } } #endif /* poll any events */ @@ -47,6 +47,7 @@ #endif #ifdef _WIN32 +#include <windows.h> #define fsync _commit #define lseek _lseeki64 #define ENOTSUP 4096 @@ -221,6 +222,14 @@ typedef int PollingFunc(void *opaque); int qemu_add_polling_cb(PollingFunc *func, void *opaque); void qemu_del_polling_cb(PollingFunc *func, void *opaque); +#ifdef _WIN32 +/* Wait objects handling */ +typedef void WaitObjectFunc(void *opaque); + +int qemu_add_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque); +void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque); +#endif + /* character device */ #define CHR_EVENT_BREAK 0 /* serial break char */ |