From a18e524af0c23b083dc69f9a2eed563893d01f22 Mon Sep 17 00:00:00 2001 From: bellard Date: Sun, 25 Jun 2006 17:18:27 +0000 Subject: [PATCH] multiple wait object support for win32 (kazu) git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2013 c046a42c-6fe2-441c-8c8c-71466251a162 --- tap-win32.c | 8 +++++++ vl.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++------------- vl.h | 9 ++++++++ 3 files changed, 75 insertions(+), 16 deletions(-) diff --git a/tap-win32.c b/tap-win32.c index b605695..af5e25e 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; } diff --git a/vl.c b/vl.c index 9f7143c..118a1e2 100644 --- a/vl.c +++ b/vl.c @@ -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 */ diff --git a/vl.h b/vl.h index 3312451..3cc4621 100644 --- a/vl.h +++ b/vl.h @@ -47,6 +47,7 @@ #endif #ifdef _WIN32 +#include #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 */ -- 1.7.9.5