aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tap-win32.c8
-rw-r--r--vl.c74
-rw-r--r--vl.h9
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;
}
diff --git a/vl.c b/vl.c
index 9f7143cd83..118a1e2119 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 3312451579..3cc4621bc5 100644
--- a/vl.h
+++ b/vl.h
@@ -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 */