diff --git a/tap-win32.c b/tap-win32.c index af5e25e6832c68f7882ceb9abf3ef7ce37f26a5a..d84a622d355f94bdff1519d063190254bea23d5e 100644 --- a/tap-win32.c +++ b/tap-win32.c @@ -97,6 +97,7 @@ typedef struct tap_win32_overlapped { HANDLE write_event; HANDLE output_queue_semaphore; HANDLE free_list_semaphore; + HANDLE tap_semaphore; CRITICAL_SECTION output_queue_cs; CRITICAL_SECTION free_list_cs; OVERLAPPED read_overlapped; @@ -445,6 +446,10 @@ static void tap_win32_overlapped_init(tap_win32_overlapped_t* const overlapped, overlapped->free_list = element; } } + /* To count buffers, initially no-signal. */ + overlapped->tap_semaphore = CreateSemaphore(NULL, 0, TUN_MAX_BUFFER_COUNT, NULL); + if(!overlapped->tap_semaphore) + fprintf(stderr, "error creating tap_semaphore.\n"); } static int tap_win32_write(tap_win32_overlapped_t *overlapped, @@ -526,6 +531,7 @@ static DWORD WINAPI tap_win32_thread_entry(LPVOID param) if(read_size > 0) { buffer->read_size = read_size; put_buffer_on_output_queue(overlapped, buffer); + ReleaseSemaphore(overlapped->tap_semaphore, 1, NULL); buffer = get_buffer_from_free_list(overlapped); } } @@ -620,8 +626,6 @@ static int tap_win32_open(tap_win32_overlapped_t **phandle, hThread = CreateThread(NULL, 0, tap_win32_thread_entry, (LPVOID)&tap_overlapped, 0, &idThread); - SetThreadPriority(hThread,THREAD_PRIORITY_TIME_CRITICAL); - return 0; } @@ -630,11 +634,8 @@ 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; - static void tap_receive(void *opaque, const uint8_t *buf, int size) { TAPState *s = opaque; @@ -642,22 +643,17 @@ static void tap_receive(void *opaque, const uint8_t *buf, int size) tap_win32_write(s->handle, buf, size); } -/* XXX: horrible, suppress this by using proper thread signaling */ -void tap_win32_poll(void) +static void tap_win32_send(void *opaque) { - TAPState *s = tap_win32_state; + TAPState *s = opaque; uint8_t *buf; int max_size = 4096; int size; - if (!s) - return; - size = tap_win32_read(s->handle, &buf, max_size); if (size > 0) { qemu_send_packet(s->vc, buf, size); tap_win32_free_buffer(s->handle, buf); - SetEvent(s->tap_event); } } @@ -677,12 +673,7 @@ 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); + qemu_add_wait_object(s->handle->tap_semaphore, tap_win32_send, s); return 0; } diff --git a/vl.c b/vl.c index 29142e1f6f581ee72924f2969bbf2deb1cf07e3a..771903099315a7fa52a25ac77d6e5c0a279089ec 100644 --- a/vl.c +++ b/vl.c @@ -5714,9 +5714,6 @@ void main_loop_wait(int timeout) } slirp_select_poll(&rfds, &wfds, &xfds); } -#endif -#ifdef _WIN32 - tap_win32_poll(); #endif qemu_aio_poll(); qemu_bh_poll(); diff --git a/vl.h b/vl.h index 4bef80192c7ff859f44681759576a514998c691b..461caea022c44415135055f2cda2af58efff1924 100644 --- a/vl.h +++ b/vl.h @@ -348,7 +348,6 @@ void do_info_network(void); /* TAP win32 */ int tap_win32_init(VLANState *vlan, const char *ifname); -void tap_win32_poll(void); /* NIC info */