Commit a18e524af0c23b083dc69f9a2eed563893d01f22

Authored by bellard
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 }
@@ -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 */
@@ -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 */