multiple wait object support for win32 (kazu)
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Sun, 25 Jun 2006 17:18:27 +0000 (17:18 +0000)
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Sun, 25 Jun 2006 17:18:27 +0000 (17:18 +0000)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2013 c046a42c-6fe2-441c-8c8c-71466251a162

tap-win32.c
vl.c
vl.h

index b605695..af5e25e 100644 (file)
@@ -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 (file)
--- 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 (file)
--- 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 */