All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] win32: Windows-specific fixes from the mailing list
@ 2026-04-13 16:43 Mohamed Mediouni
  2026-04-13 16:43 ` [PATCH 1/3] serial COM: windows serial COM PollingFunc don't sleep Mohamed Mediouni
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Mohamed Mediouni @ 2026-04-13 16:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Stefan Weil, Paolo Bonzini, Marc-André Lureau, Jason Wang,
	Mohamed Mediouni

It looks like these ought to be merged but were not, so
posting them again.

Gal Horowitz (2):
  tap-win32: cleanup leaked handles on tap close
  tap-win32: allocate separate tap state for each instance

Werner de Carne (1):
  serial COM: windows serial COM PollingFunc don't sleep

 chardev/char-win.c | 16 +++++++++------
 net/tap-win32.c    | 51 ++++++++++++++++++++++++++++++++++++----------
 2 files changed, 50 insertions(+), 17 deletions(-)

-- 
2.50.1 (Apple Git-155)



^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/3] serial COM: windows serial COM PollingFunc don't sleep
  2026-04-13 16:43 [PATCH 0/3] win32: Windows-specific fixes from the mailing list Mohamed Mediouni
@ 2026-04-13 16:43 ` Mohamed Mediouni
  2026-04-15  9:48   ` Marc-André Lureau
  2026-04-13 16:43 ` [PATCH 2/3] tap-win32: cleanup leaked handles on tap close Mohamed Mediouni
  2026-04-13 16:43 ` [PATCH 3/3] tap-win32: allocate separate tap state for each instance Mohamed Mediouni
  2 siblings, 1 reply; 5+ messages in thread
From: Mohamed Mediouni @ 2026-04-13 16:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Stefan Weil, Paolo Bonzini, Marc-André Lureau, Jason Wang,
	Werner de Carne

From: Werner de Carne <werner@carne.de>

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1802
Signed-off-by: Werner de Carne <werner@carne.de>
---
 chardev/char-win.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/chardev/char-win.c b/chardev/char-win.c
index fef45e83aa..f13d526e2f 100644
--- a/chardev/char-win.c
+++ b/chardev/char-win.c
@@ -28,7 +28,7 @@
 #include "qapi/error.h"
 #include "chardev/char-win.h"
 
-static void win_chr_read(Chardev *chr, DWORD len)
+static int win_chr_read(Chardev *chr, DWORD len)
 {
     WinChardev *s = WIN_CHARDEV(chr);
     int max_size = qemu_chr_be_can_write(chr);
@@ -40,7 +40,7 @@ static void win_chr_read(Chardev *chr, DWORD len)
         len = max_size;
     }
     if (len == 0) {
-        return;
+        return 0;
     }
 
     ZeroMemory(&s->orecv, sizeof(s->orecv));
@@ -56,6 +56,8 @@ static void win_chr_read(Chardev *chr, DWORD len)
     if (size > 0) {
         qemu_chr_be_write(chr, buf, size);
     }
+    
+    return size > 0 ? 1 : 0;
 }
 
 static int win_chr_serial_poll(void *opaque)
@@ -67,8 +69,9 @@ static int win_chr_serial_poll(void *opaque)
 
     ClearCommError(s->file, &comerr, &status);
     if (status.cbInQue > 0) {
-        win_chr_read(chr, status.cbInQue);
-        return 1;
+        if (win_chr_read(chr, status.cbInQue)) {
+			return 1;
+		}
     }
     return 0;
 }
@@ -147,8 +150,9 @@ int win_chr_pipe_poll(void *opaque)
 
     PeekNamedPipe(s->file, NULL, 0, NULL, &size, NULL);
     if (size > 0) {
-        win_chr_read(chr, size);
-        return 1;
+    	if (win_chr_read(chr, size)) {
+			return 1;
+		}
     }
     return 0;
 }
-- 
2.50.1 (Apple Git-155)



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/3] tap-win32: cleanup leaked handles on tap close
  2026-04-13 16:43 [PATCH 0/3] win32: Windows-specific fixes from the mailing list Mohamed Mediouni
  2026-04-13 16:43 ` [PATCH 1/3] serial COM: windows serial COM PollingFunc don't sleep Mohamed Mediouni
@ 2026-04-13 16:43 ` Mohamed Mediouni
  2026-04-13 16:43 ` [PATCH 3/3] tap-win32: allocate separate tap state for each instance Mohamed Mediouni
  2 siblings, 0 replies; 5+ messages in thread
From: Mohamed Mediouni @ 2026-04-13 16:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Stefan Weil, Paolo Bonzini, Marc-André Lureau, Jason Wang,
	Gal Horowitz

From: Gal Horowitz <galush.horowitz@gmail.com>

Currently, all handles owned by a win32 tap are leaked on cleanup.
This commit ensures that the handles are properly closed upon tap
cleanup. A check for the return value of CreateThread is also added.

Signed-off-by: Gal Horowitz <galush.horowitz@gmail.com>
---
 net/tap-win32.c | 40 +++++++++++++++++++++++++++++++++-------
 1 file changed, 33 insertions(+), 7 deletions(-)

diff --git a/net/tap-win32.c b/net/tap-win32.c
index 38baf90e0b..ae25e5a883 100644
--- a/net/tap-win32.c
+++ b/net/tap-win32.c
@@ -104,6 +104,7 @@ typedef struct tap_win32_overlapped {
     HANDLE output_queue_semaphore;
     HANDLE free_list_semaphore;
     HANDLE tap_semaphore;
+    HANDLE thread_handle;
     CRITICAL_SECTION output_queue_cs;
     CRITICAL_SECTION free_list_cs;
     OVERLAPPED read_overlapped;
@@ -589,6 +590,26 @@ static void tap_win32_free_buffer(tap_win32_overlapped_t *overlapped,
     put_buffer_on_free_list(overlapped, buffer);
 }
 
+static void tap_win32_close(tap_win32_overlapped_t *overlapped)
+{
+    TerminateThread(overlapped->thread_handle, 0);
+    CloseHandle(overlapped->thread_handle);
+
+    CloseHandle(overlapped->tap_semaphore);
+    CloseHandle(overlapped->free_list_semaphore);
+    CloseHandle(overlapped->output_queue_semaphore);
+
+    DeleteCriticalSection(&overlapped->free_list_cs);
+    DeleteCriticalSection(&overlapped->output_queue_cs);
+
+    CloseHandle(overlapped->write_event);
+    CloseHandle(overlapped->read_event);
+
+    CloseHandle(overlapped->handle);
+
+    g_free(overlapped);
+}
+
 static int tap_win32_open(tap_win32_overlapped_t **phandle,
                           const char *preferred_name)
 {
@@ -604,7 +625,6 @@ static int tap_win32_open(tap_win32_overlapped_t **phandle,
         unsigned long debug;
     } version;
     DWORD version_len;
-    DWORD idThread;
 
     if (preferred_name != NULL) {
         snprintf(name_buffer, sizeof(name_buffer), "%s", preferred_name);
@@ -642,15 +662,22 @@ static int tap_win32_open(tap_win32_overlapped_t **phandle,
     }
 
     if (!tap_win32_set_status(handle, TRUE)) {
+        CloseHandle(handle);
         return -1;
     }
 
     tap_win32_overlapped_init(&tap_overlapped, handle);
 
-    *phandle = &tap_overlapped;
+    tap_overlapped.thread_handle = CreateThread(NULL, 0,
+        tap_win32_thread_entry, (LPVOID)&tap_overlapped, 0, NULL);
+
+    if (tap_overlapped->thread_handle == NULL) {
+        tap_win32_close(tap_overlapped);
+        return -1;
+    }
+
+    *phandle = tap_overlapped;
 
-    CreateThread(NULL, 0, tap_win32_thread_entry,
-                 (LPVOID)&tap_overlapped, 0, &idThread);
     return 0;
 }
 
@@ -667,9 +694,8 @@ static void tap_cleanup(NetClientState *nc)
 
     qemu_del_wait_object(s->handle->tap_semaphore, NULL, NULL);
 
-    /* FIXME: need to kill thread and close file handle:
-       tap_win32_close(s);
-    */
+    tap_win32_close(s->handle);
+    s->handle = NULL;
 }
 
 static ssize_t tap_receive(NetClientState *nc, const uint8_t *buf, size_t size)
-- 
2.50.1 (Apple Git-155)



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 3/3] tap-win32: allocate separate tap state for each instance
  2026-04-13 16:43 [PATCH 0/3] win32: Windows-specific fixes from the mailing list Mohamed Mediouni
  2026-04-13 16:43 ` [PATCH 1/3] serial COM: windows serial COM PollingFunc don't sleep Mohamed Mediouni
  2026-04-13 16:43 ` [PATCH 2/3] tap-win32: cleanup leaked handles on tap close Mohamed Mediouni
@ 2026-04-13 16:43 ` Mohamed Mediouni
  2 siblings, 0 replies; 5+ messages in thread
From: Mohamed Mediouni @ 2026-04-13 16:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Stefan Weil, Paolo Bonzini, Marc-André Lureau, Jason Wang,
	Gal Horowitz

From: Gal Horowitz <galush.horowitz@gmail.com>

A static global is incorrectly used as the tap state for all win32 taps
created. Instead, we now allocate per win32 tap.

Signed-off-by: Gal Horowitz <galush.horowitz@gmail.com>
---
 net/tap-win32.c | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/net/tap-win32.c b/net/tap-win32.c
index ae25e5a883..3d7227fcf4 100644
--- a/net/tap-win32.c
+++ b/net/tap-win32.c
@@ -115,8 +115,6 @@ typedef struct tap_win32_overlapped {
     tun_buffer_t* output_queue_back;
 } tap_win32_overlapped_t;
 
-static tap_win32_overlapped_t tap_overlapped;
-
 static tun_buffer_t* get_buffer_from_free_list(tap_win32_overlapped_t* const overlapped)
 {
     tun_buffer_t* buffer = NULL;
@@ -403,8 +401,10 @@ static int tap_win32_set_status(HANDLE handle, int status)
                 &status, sizeof (status), &len, NULL);
 }
 
-static void tap_win32_overlapped_init(tap_win32_overlapped_t* const overlapped, const HANDLE handle)
+static tap_win32_overlapped_t *tap_win32_overlapped_new(const HANDLE handle)
 {
+    tap_win32_overlapped_t *overlapped = g_new0(tap_win32_overlapped_t, 1);
+
     overlapped->handle = handle;
 
     overlapped->read_event = CreateEvent(NULL, FALSE, FALSE, NULL);
@@ -455,6 +455,8 @@ static void tap_win32_overlapped_init(tap_win32_overlapped_t* const overlapped,
     overlapped->tap_semaphore = CreateSemaphore(NULL, 0, TUN_MAX_BUFFER_COUNT, NULL);
     if(!overlapped->tap_semaphore)
         fprintf(stderr, "error creating tap_semaphore.\n");
+
+    return overlapped;
 }
 
 static int tap_win32_write(tap_win32_overlapped_t *overlapped,
@@ -625,6 +627,7 @@ static int tap_win32_open(tap_win32_overlapped_t **phandle,
         unsigned long debug;
     } version;
     DWORD version_len;
+    tap_win32_overlapped_t *tap_overlapped = NULL;
 
     if (preferred_name != NULL) {
         snprintf(name_buffer, sizeof(name_buffer), "%s", preferred_name);
@@ -666,10 +669,10 @@ static int tap_win32_open(tap_win32_overlapped_t **phandle,
         return -1;
     }
 
-    tap_win32_overlapped_init(&tap_overlapped, handle);
+    tap_overlapped = tap_win32_overlapped_new(handle);
 
-    tap_overlapped.thread_handle = CreateThread(NULL, 0,
-        tap_win32_thread_entry, (LPVOID)&tap_overlapped, 0, NULL);
+    tap_overlapped->thread_handle = CreateThread(NULL, 0,
+        tap_win32_thread_entry, (LPVOID)tap_overlapped, 0, NULL);
 
     if (tap_overlapped->thread_handle == NULL) {
         tap_win32_close(tap_overlapped);
-- 
2.50.1 (Apple Git-155)



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/3] serial COM: windows serial COM PollingFunc don't sleep
  2026-04-13 16:43 ` [PATCH 1/3] serial COM: windows serial COM PollingFunc don't sleep Mohamed Mediouni
@ 2026-04-15  9:48   ` Marc-André Lureau
  0 siblings, 0 replies; 5+ messages in thread
From: Marc-André Lureau @ 2026-04-15  9:48 UTC (permalink / raw)
  To: Mohamed Mediouni
  Cc: qemu-devel, Stefan Weil, Paolo Bonzini, Jason Wang,
	Werner de Carne

Hi

On Mon, Apr 13, 2026 at 8:56 PM Mohamed Mediouni
<mohamed@unpredictable.fr> wrote:
>
> From: Werner de Carne <werner@carne.de>
>
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1802
> Signed-off-by: Werner de Carne <werner@carne.de>
> ---
>  chardev/char-win.c | 16 ++++++++++------
>  1 file changed, 10 insertions(+), 6 deletions(-)
>
> diff --git a/chardev/char-win.c b/chardev/char-win.c
> index fef45e83aa..f13d526e2f 100644
> --- a/chardev/char-win.c
> +++ b/chardev/char-win.c
> @@ -28,7 +28,7 @@
>  #include "qapi/error.h"
>  #include "chardev/char-win.h"
>
> -static void win_chr_read(Chardev *chr, DWORD len)
> +static int win_chr_read(Chardev *chr, DWORD len)
>  {
>      WinChardev *s = WIN_CHARDEV(chr);
>      int max_size = qemu_chr_be_can_write(chr);
> @@ -40,7 +40,7 @@ static void win_chr_read(Chardev *chr, DWORD len)
>          len = max_size;
>      }
>      if (len == 0) {
> -        return;
> +        return 0;
>      }
>
>      ZeroMemory(&s->orecv, sizeof(s->orecv));
> @@ -56,6 +56,8 @@ static void win_chr_read(Chardev *chr, DWORD len)
>      if (size > 0) {
>          qemu_chr_be_write(chr, buf, size);
>      }
> +
> +    return size > 0 ? 1 : 0;
>  }
>
>  static int win_chr_serial_poll(void *opaque)
> @@ -67,8 +69,9 @@ static int win_chr_serial_poll(void *opaque)
>
>      ClearCommError(s->file, &comerr, &status);
>      if (status.cbInQue > 0) {
> -        win_chr_read(chr, status.cbInQue);
> -        return 1;
> +        if (win_chr_read(chr, status.cbInQue)) {
> +                       return 1;

indent is off

> +               }
>      }
>      return 0;
>  }
> @@ -147,8 +150,9 @@ int win_chr_pipe_poll(void *opaque)
>
>      PeekNamedPipe(s->file, NULL, 0, NULL, &size, NULL);
>      if (size > 0) {
> -        win_chr_read(chr, size);
> -        return 1;
> +       if (win_chr_read(chr, size)) {
> +                       return 1;

same

Otherwise
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>

> +               }
>      }
>      return 0;
>  }
> --
> 2.50.1 (Apple Git-155)
>
>


-- 
Marc-André Lureau


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-04-15  9:49 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-13 16:43 [PATCH 0/3] win32: Windows-specific fixes from the mailing list Mohamed Mediouni
2026-04-13 16:43 ` [PATCH 1/3] serial COM: windows serial COM PollingFunc don't sleep Mohamed Mediouni
2026-04-15  9:48   ` Marc-André Lureau
2026-04-13 16:43 ` [PATCH 2/3] tap-win32: cleanup leaked handles on tap close Mohamed Mediouni
2026-04-13 16:43 ` [PATCH 3/3] tap-win32: allocate separate tap state for each instance Mohamed Mediouni

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.