[PATCH 2/2] io: use g_clear_handle_id() for GSource cleanup

Philippe Mathieu-Daudé posted 2 patches 3 days, 8 hours ago
Maintainers: Peter Maydell <peter.maydell@linaro.org>, "Marc-André Lureau" <marcandre.lureau@redhat.com>, Paolo Bonzini <pbonzini@redhat.com>, Joel Stanley <joel@jms.id.au>, "Michael S. Tsirkin" <mst@redhat.com>, Samuel Tardieu <sam@rfc1149.net>, Cornelia Huck <cohuck@redhat.com>, Eric Farman <farman@linux.ibm.com>, Matthew Rosato <mjrosato@linux.ibm.com>, Halil Pasic <pasic@linux.ibm.com>, Christian Borntraeger <borntraeger@linux.ibm.com>, "Collin L. Walling" <walling@linux.ibm.com>, Laurent Vivier <lvivier@redhat.com>, Amit Shah <amit@kernel.org>, "Daniel P. Berrangé" <berrange@redhat.com>, Jason Wang <jasowang@redhat.com>, Stefano Garzarella <sgarzare@redhat.com>, Marcelo Tosatti <mtosatti@redhat.com>
[PATCH 2/2] io: use g_clear_handle_id() for GSource cleanup
Posted by Philippe Mathieu-Daudé 3 days, 8 hours ago
Use g_clear_handle_id() instead of g_source_remove() with
manual ID checking and zeroing.

This simplifies the code and ensures consistent handling of
GSource IDs, since g_clear_handle_id() checks for a non-zero
ID before calling the cleanup function and zeros it afterwards.

No functional change intended.

Mechanical change using the following Coccinelle spatch script:

  @@
  expression TAG;
  @@
  -    if (TAG > 0) {
  +    if (TAG) {
           g_source_remove(TAG);
           <... when != TAG
           TAG = 0;
           ...>
       }

  @@
  expression TAG;
  @@
  -    g_source_remove(TAG);
  -    TAG = 0;
  +    g_clear_handle_id(&TAG, g_source_remove);

  @@
  expression TAG;
  @@
  -    if (TAG) {
           g_clear_handle_id(&TAG, g_source_remove);
  -    }

Inspired-by: Matthew Penney <matt@matthewpenney.net>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
 hw/char/cmsdk-apb-uart.c  |  5 +----
 hw/char/nrf51_uart.c      |  5 +----
 hw/char/serial.c          |  6 +-----
 hw/char/stm32l4x5_usart.c |  5 +----
 hw/char/terminal3270.c    |  5 +----
 hw/char/virtio-console.c  | 10 ++--------
 hw/usb/redirect.c         |  5 +----
 io/channel-websock.c      | 13 +++----------
 net/passt.c               |  8 ++------
 net/stream.c              | 15 +++------------
 net/stream_data.c         |  5 +----
 net/vhost-user.c          |  8 ++------
 ui/dbus-clipboard.c       |  6 ++----
 ui/input-barrier.c        |  6 +-----
 ui/vnc-auth-vencrypt.c    |  6 +-----
 ui/vnc-ws.c               | 12 ++----------
 16 files changed, 25 insertions(+), 95 deletions(-)

diff --git a/hw/char/cmsdk-apb-uart.c b/hw/char/cmsdk-apb-uart.c
index edb80f61819..0631821a571 100644
--- a/hw/char/cmsdk-apb-uart.c
+++ b/hw/char/cmsdk-apb-uart.c
@@ -236,10 +236,7 @@ buffer_drained:
 
 static void uart_cancel_transmit(CMSDKAPBUART *s)
 {
-    if (s->watch_tag) {
-        g_source_remove(s->watch_tag);
-        s->watch_tag = 0;
-    }
+    g_clear_handle_id(&s->watch_tag, g_source_remove);
 }
 
 static void uart_write(void *opaque, hwaddr offset, uint64_t value,
diff --git a/hw/char/nrf51_uart.c b/hw/char/nrf51_uart.c
index 73069232441..96f0d085fdd 100644
--- a/hw/char/nrf51_uart.c
+++ b/hw/char/nrf51_uart.c
@@ -104,10 +104,7 @@ buffer_drained:
 
 static void uart_cancel_transmit(NRF51UARTState *s)
 {
-    if (s->watch_tag) {
-        g_source_remove(s->watch_tag);
-        s->watch_tag = 0;
-    }
+    g_clear_handle_id(&s->watch_tag, g_source_remove);
 }
 
 static void uart_write(void *opaque, hwaddr addr,
diff --git a/hw/char/serial.c b/hw/char/serial.c
index 0f3469a1e8f..0729cd2ce9d 100644
--- a/hw/char/serial.c
+++ b/hw/char/serial.c
@@ -856,11 +856,7 @@ const VMStateDescription vmstate_serial = {
 static void serial_reset(void *opaque)
 {
     SerialState *s = opaque;
-
-    if (s->watch_tag > 0) {
-        g_source_remove(s->watch_tag);
-        s->watch_tag = 0;
-    }
+    g_clear_handle_id(&s->watch_tag, g_source_remove);
 
     s->rbr = 0;
     s->ier = 0;
diff --git a/hw/char/stm32l4x5_usart.c b/hw/char/stm32l4x5_usart.c
index 736f1e764e6..dd1b0991956 100644
--- a/hw/char/stm32l4x5_usart.c
+++ b/hw/char/stm32l4x5_usart.c
@@ -280,10 +280,7 @@ buffer_drained:
 
 static void usart_cancel_transmit(Stm32l4x5UsartBaseState *s)
 {
-    if (s->watch_tag) {
-        g_source_remove(s->watch_tag);
-        s->watch_tag = 0;
-    }
+    g_clear_handle_id(&s->watch_tag, g_source_remove);
 }
 
 static void stm32l4x5_update_params(Stm32l4x5UsartBaseState *s)
diff --git a/hw/char/terminal3270.c b/hw/char/terminal3270.c
index 1d857bad9bc..989b6f6ee1e 100644
--- a/hw/char/terminal3270.c
+++ b/hw/char/terminal3270.c
@@ -52,10 +52,7 @@ static int terminal_can_read(void *opaque)
 
 static void terminal_timer_cancel(Terminal3270 *t)
 {
-    if (t->timer_tag) {
-        g_source_remove(t->timer_tag);
-        t->timer_tag = 0;
-    }
+    g_clear_handle_id(&t->timer_tag, g_source_remove);
 }
 
 /*
diff --git a/hw/char/virtio-console.c b/hw/char/virtio-console.c
index efe7cd6772e..4737b9a56eb 100644
--- a/hw/char/virtio-console.c
+++ b/hw/char/virtio-console.c
@@ -159,10 +159,7 @@ static void chr_event(void *opaque, QEMUChrEvent event)
         virtio_serial_open(port);
         break;
     case CHR_EVENT_CLOSED:
-        if (vcon->watch) {
-            g_source_remove(vcon->watch);
-            vcon->watch = 0;
-        }
+        g_clear_handle_id(&vcon->watch, g_source_remove);
         virtio_serial_close(port);
         break;
     case CHR_EVENT_BREAK:
@@ -255,10 +252,7 @@ static void virtconsole_realize(DeviceState *dev, Error **errp)
 static void virtconsole_unrealize(DeviceState *dev)
 {
     VirtConsole *vcon = VIRTIO_CONSOLE(dev);
-
-    if (vcon->watch) {
-        g_clear_handle_id(&vcon->watch, g_source_remove);
-    }
+    g_clear_handle_id(&vcon->watch, g_source_remove);
 }
 
 static void virtconsole_class_init(ObjectClass *klass, const void *data)
diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
index 100afbdb06a..bde821e214b 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -1226,10 +1226,7 @@ static void usbredir_chardev_close_bh(void *opaque)
         usbredirparser_destroy(dev->parser);
         dev->parser = NULL;
     }
-    if (dev->watch) {
-        g_source_remove(dev->watch);
-        dev->watch = 0;
-    }
+    g_clear_handle_id(&dev->watch, g_source_remove);
 }
 
 static void usbredir_create_parser(USBRedirDevice *dev)
diff --git a/io/channel-websock.c b/io/channel-websock.c
index da7e7c9e345..3479a5c32d2 100644
--- a/io/channel-websock.c
+++ b/io/channel-websock.c
@@ -1066,10 +1066,7 @@ static gboolean qio_channel_websock_flush(QIOChannel *ioc,
 
 static void qio_channel_websock_unset_watch(QIOChannelWebsock *ioc)
 {
-    if (ioc->io_tag) {
-        g_source_remove(ioc->io_tag);
-        ioc->io_tag = 0;
-    }
+    g_clear_handle_id(&ioc->io_tag, g_source_remove);
 }
 
 static void qio_channel_websock_set_watch(QIOChannelWebsock *ioc)
@@ -1246,12 +1243,8 @@ static int qio_channel_websock_close(QIOChannel *ioc,
     buffer_free(&wioc->encinput);
     buffer_free(&wioc->encoutput);
     buffer_free(&wioc->rawinput);
-    if (wioc->hs_io_tag) {
-        g_clear_handle_id(&wioc->hs_io_tag, g_source_remove);
-    }
-    if (wioc->io_tag) {
-        g_clear_handle_id(&wioc->io_tag, g_source_remove);
-    }
+    g_clear_handle_id(&wioc->hs_io_tag, g_source_remove);
+    g_clear_handle_id(&wioc->io_tag, g_source_remove);
     if (wioc->io_err) {
         g_clear_pointer(&wioc->io_err, error_free);
     }
diff --git a/net/passt.c b/net/passt.c
index 4ff94ee509d..d3b5ab426c9 100644
--- a/net/passt.c
+++ b/net/passt.c
@@ -90,10 +90,7 @@ static void net_passt_cleanup(NetClientState *nc)
         g_free(s->vhost_net);
         s->vhost_net = NULL;
     }
-    if (s->vhost_watch) {
-        g_source_remove(s->vhost_watch);
-        s->vhost_watch = 0;
-    }
+    g_clear_handle_id(&s->vhost_watch, g_source_remove);
     qemu_chr_fe_deinit(&s->vhost_chr, true);
     if (s->vhost_user) {
         vhost_user_cleanup(s->vhost_user);
@@ -421,8 +418,7 @@ static void passt_vhost_user_event(void *opaque, QEMUChrEvent event)
         if (s->vhost_watch) {
             AioContext *ctx = qemu_get_current_aio_context();
 
-            g_source_remove(s->vhost_watch);
-            s->vhost_watch = 0;
+            g_clear_handle_id(&s->vhost_watch, g_source_remove);
             qemu_chr_fe_set_handlers(&s->vhost_chr, NULL, NULL,  NULL, NULL,
                                      NULL, NULL, false);
 
diff --git a/net/stream.c b/net/stream.c
index ea83f4a763a..6df4e251feb 100644
--- a/net/stream.c
+++ b/net/stream.c
@@ -71,24 +71,15 @@ static gboolean net_stream_send(QIOChannel *ioc,
 static void net_stream_cleanup(NetClientState *nc)
 {
     NetStreamState *s = DO_UPCAST(NetStreamState, data.nc, nc);
-    if (s->timer_tag) {
-        g_source_remove(s->timer_tag);
-        s->timer_tag = 0;
-    }
+    g_clear_handle_id(&s->timer_tag, g_source_remove);
     if (s->addr) {
         qapi_free_SocketAddress(s->addr);
         s->addr = NULL;
     }
     if (s->data.ioc) {
         if (QIO_CHANNEL_SOCKET(s->data.ioc)->fd != -1) {
-            if (s->data.ioc_read_tag) {
-                g_source_remove(s->data.ioc_read_tag);
-                s->data.ioc_read_tag = 0;
-            }
-            if (s->data.ioc_write_tag) {
-                g_source_remove(s->data.ioc_write_tag);
-                s->data.ioc_write_tag = 0;
-            }
+            g_clear_handle_id(&s->data.ioc_read_tag, g_source_remove);
+            g_clear_handle_id(&s->data.ioc_write_tag, g_source_remove);
         }
         object_unref(OBJECT(s->data.ioc));
         s->data.ioc = NULL;
diff --git a/net/stream_data.c b/net/stream_data.c
index 03740e9f73e..73b45da9fe3 100644
--- a/net/stream_data.c
+++ b/net/stream_data.c
@@ -84,10 +84,7 @@ void net_stream_data_rs_finalize(SocketReadState *rs)
     if (qemu_send_packet_async(&d->nc, rs->buf,
                                rs->packet_len,
                                net_stream_data_send_completed) == 0) {
-        if (d->ioc_read_tag) {
-            g_source_remove(d->ioc_read_tag);
-            d->ioc_read_tag = 0;
-        }
+        g_clear_handle_id(&d->ioc_read_tag, g_source_remove);
     }
 }
 
diff --git a/net/vhost-user.c b/net/vhost-user.c
index a4bb49bbcff..2d0fc49b4d8 100644
--- a/net/vhost-user.c
+++ b/net/vhost-user.c
@@ -215,10 +215,7 @@ static void net_vhost_user_cleanup(NetClientState *nc)
         s->vhost_net = NULL;
     }
     if (nc->queue_index == 0) {
-        if (s->watch) {
-            g_source_remove(s->watch);
-            s->watch = 0;
-        }
+        g_clear_handle_id(&s->watch, g_source_remove);
         qemu_chr_fe_deinit(&s->chr, true);
         if (s->vhost_user) {
             vhost_user_cleanup(s->vhost_user);
@@ -356,8 +353,7 @@ static void net_vhost_user_event(void *opaque, QEMUChrEvent event)
         if (s->watch) {
             AioContext *ctx = qemu_get_current_aio_context();
 
-            g_source_remove(s->watch);
-            s->watch = 0;
+            g_clear_handle_id(&s->watch, g_source_remove);
             qemu_chr_fe_set_handlers(&s->chr, NULL, NULL, NULL, NULL,
                                      NULL, NULL, false);
 
diff --git a/ui/dbus-clipboard.c b/ui/dbus-clipboard.c
index 935b6b1a2ac..90318384ee4 100644
--- a/ui/dbus-clipboard.c
+++ b/ui/dbus-clipboard.c
@@ -80,8 +80,7 @@ dbus_clipboard_update_info(DBusDisplay *dpy, QemuClipboardInfo *info)
     if (req->invocation && info->types[req->type].data) {
         dbus_clipboard_complete_request(dpy, req->invocation, info, req->type);
         g_clear_object(&req->invocation);
-        g_source_remove(req->timeout_id);
-        req->timeout_id = 0;
+        g_clear_handle_id(&req->timeout_id, g_source_remove);
         return;
     }
 
@@ -183,8 +182,7 @@ dbus_clipboard_request_cancelled(DBusClipboardRequest *req)
         "Cancelled clipboard request");
 
     g_clear_object(&req->invocation);
-    g_source_remove(req->timeout_id);
-    req->timeout_id = 0;
+    g_clear_handle_id(&req->timeout_id, g_source_remove);
 }
 
 static void
diff --git a/ui/input-barrier.c b/ui/input-barrier.c
index 0a2198ca500..84212c50442 100644
--- a/ui/input-barrier.c
+++ b/ui/input-barrier.c
@@ -518,11 +518,7 @@ static void input_barrier_complete(UserCreatable *uc, Error **errp)
 static void input_barrier_instance_finalize(Object *obj)
 {
     InputBarrier *ib = INPUT_BARRIER(obj);
-
-    if (ib->ioc_tag) {
-        g_source_remove(ib->ioc_tag);
-        ib->ioc_tag = 0;
-    }
+    g_clear_handle_id(&ib->ioc_tag, g_source_remove);
 
     if (ib->sioc) {
         qio_channel_close(QIO_CHANNEL(ib->sioc), NULL);
diff --git a/ui/vnc-auth-vencrypt.c b/ui/vnc-auth-vencrypt.c
index d9c212ff328..a1b8cde2292 100644
--- a/ui/vnc-auth-vencrypt.c
+++ b/ui/vnc-auth-vencrypt.c
@@ -101,11 +101,7 @@ static int protocol_client_vencrypt_auth(VncState *vs, uint8_t *data, size_t len
         QIOChannelTLS *tls;
         vnc_write_u8(vs, 1); /* Accept auth */
         vnc_flush(vs);
-
-        if (vs->ioc_tag) {
-            g_source_remove(vs->ioc_tag);
-            vs->ioc_tag = 0;
-        }
+        g_clear_handle_id(&vs->ioc_tag, g_source_remove);
 
         tls = qio_channel_tls_new_server(
             vs->ioc,
diff --git a/ui/vnc-ws.c b/ui/vnc-ws.c
index 9e3503d93d8..65e8b344b65 100644
--- a/ui/vnc-ws.c
+++ b/ui/vnc-ws.c
@@ -54,11 +54,7 @@ gboolean vncws_tls_handshake_io(QIOChannel *ioc G_GNUC_UNUSED,
     VncState *vs = opaque;
     QIOChannelTLS *tls;
     Error *err = NULL;
-
-    if (vs->ioc_tag) {
-        g_source_remove(vs->ioc_tag);
-        vs->ioc_tag = 0;
-    }
+    g_clear_handle_id(&vs->ioc_tag, g_source_remove);
 
     if (condition & (G_IO_HUP | G_IO_ERR)) {
         vnc_client_error(vs);
@@ -123,11 +119,7 @@ gboolean vncws_handshake_io(QIOChannel *ioc G_GNUC_UNUSED,
 {
     VncState *vs = opaque;
     QIOChannelWebsock *wioc;
-
-    if (vs->ioc_tag) {
-        g_source_remove(vs->ioc_tag);
-        vs->ioc_tag = 0;
-    }
+    g_clear_handle_id(&vs->ioc_tag, g_source_remove);
 
     if (condition & (G_IO_HUP | G_IO_ERR)) {
         vnc_client_error(vs);
-- 
2.53.0


Re: [PATCH 2/2] io: use g_clear_handle_id() for GSource cleanup
Posted by Matthew Penney 2 days, 4 hours ago
Hi Philippe,

Thanks for picking this up and cleaning it up.

This matches what I was aiming for with my series.

Best regards,
Matt



Sent with Proton Mail secure email.

On Wednesday, 8 April 2026 at 11:06, Philippe Mathieu-Daudé <philmd@linaro.org> wrote:

> Use g_clear_handle_id() instead of g_source_remove() with
> manual ID checking and zeroing.
> 
> This simplifies the code and ensures consistent handling of
> GSource IDs, since g_clear_handle_id() checks for a non-zero
> ID before calling the cleanup function and zeros it afterwards.
> 
> No functional change intended.
> 
> Mechanical change using the following Coccinelle spatch script:
> 
>   @@
>   expression TAG;
>   @@
>   -    if (TAG > 0) {
>   +    if (TAG) {
>            g_source_remove(TAG);
>            <... when != TAG
>            TAG = 0;
>            ...>
>        }
> 
>   @@
>   expression TAG;
>   @@
>   -    g_source_remove(TAG);
>   -    TAG = 0;
>   +    g_clear_handle_id(&TAG, g_source_remove);
> 
>   @@
>   expression TAG;
>   @@
>   -    if (TAG) {
>            g_clear_handle_id(&TAG, g_source_remove);
>   -    }
> 
> Inspired-by: Matthew Penney <matt@matthewpenney.net>
> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> ---
>  hw/char/cmsdk-apb-uart.c  |  5 +----
>  hw/char/nrf51_uart.c      |  5 +----
>  hw/char/serial.c          |  6 +-----
>  hw/char/stm32l4x5_usart.c |  5 +----
>  hw/char/terminal3270.c    |  5 +----
>  hw/char/virtio-console.c  | 10 ++--------
>  hw/usb/redirect.c         |  5 +----
>  io/channel-websock.c      | 13 +++----------
>  net/passt.c               |  8 ++------
>  net/stream.c              | 15 +++------------
>  net/stream_data.c         |  5 +----
>  net/vhost-user.c          |  8 ++------
>  ui/dbus-clipboard.c       |  6 ++----
>  ui/input-barrier.c        |  6 +-----
>  ui/vnc-auth-vencrypt.c    |  6 +-----
>  ui/vnc-ws.c               | 12 ++----------
>  16 files changed, 25 insertions(+), 95 deletions(-)
> 
> diff --git a/hw/char/cmsdk-apb-uart.c b/hw/char/cmsdk-apb-uart.c
> index edb80f61819..0631821a571 100644
> --- a/hw/char/cmsdk-apb-uart.c
> +++ b/hw/char/cmsdk-apb-uart.c
> @@ -236,10 +236,7 @@ buffer_drained:
> 
>  static void uart_cancel_transmit(CMSDKAPBUART *s)
>  {
> -    if (s->watch_tag) {
> -        g_source_remove(s->watch_tag);
> -        s->watch_tag = 0;
> -    }
> +    g_clear_handle_id(&s->watch_tag, g_source_remove);
>  }
> 
>  static void uart_write(void *opaque, hwaddr offset, uint64_t value,
> diff --git a/hw/char/nrf51_uart.c b/hw/char/nrf51_uart.c
> index 73069232441..96f0d085fdd 100644
> --- a/hw/char/nrf51_uart.c
> +++ b/hw/char/nrf51_uart.c
> @@ -104,10 +104,7 @@ buffer_drained:
> 
>  static void uart_cancel_transmit(NRF51UARTState *s)
>  {
> -    if (s->watch_tag) {
> -        g_source_remove(s->watch_tag);
> -        s->watch_tag = 0;
> -    }
> +    g_clear_handle_id(&s->watch_tag, g_source_remove);
>  }
> 
>  static void uart_write(void *opaque, hwaddr addr,
> diff --git a/hw/char/serial.c b/hw/char/serial.c
> index 0f3469a1e8f..0729cd2ce9d 100644
> --- a/hw/char/serial.c
> +++ b/hw/char/serial.c
> @@ -856,11 +856,7 @@ const VMStateDescription vmstate_serial = {
>  static void serial_reset(void *opaque)
>  {
>      SerialState *s = opaque;
> -
> -    if (s->watch_tag > 0) {
> -        g_source_remove(s->watch_tag);
> -        s->watch_tag = 0;
> -    }
> +    g_clear_handle_id(&s->watch_tag, g_source_remove);
> 
>      s->rbr = 0;
>      s->ier = 0;
> diff --git a/hw/char/stm32l4x5_usart.c b/hw/char/stm32l4x5_usart.c
> index 736f1e764e6..dd1b0991956 100644
> --- a/hw/char/stm32l4x5_usart.c
> +++ b/hw/char/stm32l4x5_usart.c
> @@ -280,10 +280,7 @@ buffer_drained:
> 
>  static void usart_cancel_transmit(Stm32l4x5UsartBaseState *s)
>  {
> -    if (s->watch_tag) {
> -        g_source_remove(s->watch_tag);
> -        s->watch_tag = 0;
> -    }
> +    g_clear_handle_id(&s->watch_tag, g_source_remove);
>  }
> 
>  static void stm32l4x5_update_params(Stm32l4x5UsartBaseState *s)
> diff --git a/hw/char/terminal3270.c b/hw/char/terminal3270.c
> index 1d857bad9bc..989b6f6ee1e 100644
> --- a/hw/char/terminal3270.c
> +++ b/hw/char/terminal3270.c
> @@ -52,10 +52,7 @@ static int terminal_can_read(void *opaque)
> 
>  static void terminal_timer_cancel(Terminal3270 *t)
>  {
> -    if (t->timer_tag) {
> -        g_source_remove(t->timer_tag);
> -        t->timer_tag = 0;
> -    }
> +    g_clear_handle_id(&t->timer_tag, g_source_remove);
>  }
> 
>  /*
> diff --git a/hw/char/virtio-console.c b/hw/char/virtio-console.c
> index efe7cd6772e..4737b9a56eb 100644
> --- a/hw/char/virtio-console.c
> +++ b/hw/char/virtio-console.c
> @@ -159,10 +159,7 @@ static void chr_event(void *opaque, QEMUChrEvent event)
>          virtio_serial_open(port);
>          break;
>      case CHR_EVENT_CLOSED:
> -        if (vcon->watch) {
> -            g_source_remove(vcon->watch);
> -            vcon->watch = 0;
> -        }
> +        g_clear_handle_id(&vcon->watch, g_source_remove);
>          virtio_serial_close(port);
>          break;
>      case CHR_EVENT_BREAK:
> @@ -255,10 +252,7 @@ static void virtconsole_realize(DeviceState *dev, Error **errp)
>  static void virtconsole_unrealize(DeviceState *dev)
>  {
>      VirtConsole *vcon = VIRTIO_CONSOLE(dev);
> -
> -    if (vcon->watch) {
> -        g_clear_handle_id(&vcon->watch, g_source_remove);
> -    }
> +    g_clear_handle_id(&vcon->watch, g_source_remove);
>  }
> 
>  static void virtconsole_class_init(ObjectClass *klass, const void *data)
> diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
> index 100afbdb06a..bde821e214b 100644
> --- a/hw/usb/redirect.c
> +++ b/hw/usb/redirect.c
> @@ -1226,10 +1226,7 @@ static void usbredir_chardev_close_bh(void *opaque)
>          usbredirparser_destroy(dev->parser);
>          dev->parser = NULL;
>      }
> -    if (dev->watch) {
> -        g_source_remove(dev->watch);
> -        dev->watch = 0;
> -    }
> +    g_clear_handle_id(&dev->watch, g_source_remove);
>  }
> 
>  static void usbredir_create_parser(USBRedirDevice *dev)
> diff --git a/io/channel-websock.c b/io/channel-websock.c
> index da7e7c9e345..3479a5c32d2 100644
> --- a/io/channel-websock.c
> +++ b/io/channel-websock.c
> @@ -1066,10 +1066,7 @@ static gboolean qio_channel_websock_flush(QIOChannel *ioc,
> 
>  static void qio_channel_websock_unset_watch(QIOChannelWebsock *ioc)
>  {
> -    if (ioc->io_tag) {
> -        g_source_remove(ioc->io_tag);
> -        ioc->io_tag = 0;
> -    }
> +    g_clear_handle_id(&ioc->io_tag, g_source_remove);
>  }
> 
>  static void qio_channel_websock_set_watch(QIOChannelWebsock *ioc)
> @@ -1246,12 +1243,8 @@ static int qio_channel_websock_close(QIOChannel *ioc,
>      buffer_free(&wioc->encinput);
>      buffer_free(&wioc->encoutput);
>      buffer_free(&wioc->rawinput);
> -    if (wioc->hs_io_tag) {
> -        g_clear_handle_id(&wioc->hs_io_tag, g_source_remove);
> -    }
> -    if (wioc->io_tag) {
> -        g_clear_handle_id(&wioc->io_tag, g_source_remove);
> -    }
> +    g_clear_handle_id(&wioc->hs_io_tag, g_source_remove);
> +    g_clear_handle_id(&wioc->io_tag, g_source_remove);
>      if (wioc->io_err) {
>          g_clear_pointer(&wioc->io_err, error_free);
>      }
> diff --git a/net/passt.c b/net/passt.c
> index 4ff94ee509d..d3b5ab426c9 100644
> --- a/net/passt.c
> +++ b/net/passt.c
> @@ -90,10 +90,7 @@ static void net_passt_cleanup(NetClientState *nc)
>          g_free(s->vhost_net);
>          s->vhost_net = NULL;
>      }
> -    if (s->vhost_watch) {
> -        g_source_remove(s->vhost_watch);
> -        s->vhost_watch = 0;
> -    }
> +    g_clear_handle_id(&s->vhost_watch, g_source_remove);
>      qemu_chr_fe_deinit(&s->vhost_chr, true);
>      if (s->vhost_user) {
>          vhost_user_cleanup(s->vhost_user);
> @@ -421,8 +418,7 @@ static void passt_vhost_user_event(void *opaque, QEMUChrEvent event)
>          if (s->vhost_watch) {
>              AioContext *ctx = qemu_get_current_aio_context();
> 
> -            g_source_remove(s->vhost_watch);
> -            s->vhost_watch = 0;
> +            g_clear_handle_id(&s->vhost_watch, g_source_remove);
>              qemu_chr_fe_set_handlers(&s->vhost_chr, NULL, NULL,  NULL, NULL,
>                                       NULL, NULL, false);
> 
> diff --git a/net/stream.c b/net/stream.c
> index ea83f4a763a..6df4e251feb 100644
> --- a/net/stream.c
> +++ b/net/stream.c
> @@ -71,24 +71,15 @@ static gboolean net_stream_send(QIOChannel *ioc,
>  static void net_stream_cleanup(NetClientState *nc)
>  {
>      NetStreamState *s = DO_UPCAST(NetStreamState, data.nc, nc);
> -    if (s->timer_tag) {
> -        g_source_remove(s->timer_tag);
> -        s->timer_tag = 0;
> -    }
> +    g_clear_handle_id(&s->timer_tag, g_source_remove);
>      if (s->addr) {
>          qapi_free_SocketAddress(s->addr);
>          s->addr = NULL;
>      }
>      if (s->data.ioc) {
>          if (QIO_CHANNEL_SOCKET(s->data.ioc)->fd != -1) {
> -            if (s->data.ioc_read_tag) {
> -                g_source_remove(s->data.ioc_read_tag);
> -                s->data.ioc_read_tag = 0;
> -            }
> -            if (s->data.ioc_write_tag) {
> -                g_source_remove(s->data.ioc_write_tag);
> -                s->data.ioc_write_tag = 0;
> -            }
> +            g_clear_handle_id(&s->data.ioc_read_tag, g_source_remove);
> +            g_clear_handle_id(&s->data.ioc_write_tag, g_source_remove);
>          }
>          object_unref(OBJECT(s->data.ioc));
>          s->data.ioc = NULL;
> diff --git a/net/stream_data.c b/net/stream_data.c
> index 03740e9f73e..73b45da9fe3 100644
> --- a/net/stream_data.c
> +++ b/net/stream_data.c
> @@ -84,10 +84,7 @@ void net_stream_data_rs_finalize(SocketReadState *rs)
>      if (qemu_send_packet_async(&d->nc, rs->buf,
>                                 rs->packet_len,
>                                 net_stream_data_send_completed) == 0) {
> -        if (d->ioc_read_tag) {
> -            g_source_remove(d->ioc_read_tag);
> -            d->ioc_read_tag = 0;
> -        }
> +        g_clear_handle_id(&d->ioc_read_tag, g_source_remove);
>      }
>  }
> 
> diff --git a/net/vhost-user.c b/net/vhost-user.c
> index a4bb49bbcff..2d0fc49b4d8 100644
> --- a/net/vhost-user.c
> +++ b/net/vhost-user.c
> @@ -215,10 +215,7 @@ static void net_vhost_user_cleanup(NetClientState *nc)
>          s->vhost_net = NULL;
>      }
>      if (nc->queue_index == 0) {
> -        if (s->watch) {
> -            g_source_remove(s->watch);
> -            s->watch = 0;
> -        }
> +        g_clear_handle_id(&s->watch, g_source_remove);
>          qemu_chr_fe_deinit(&s->chr, true);
>          if (s->vhost_user) {
>              vhost_user_cleanup(s->vhost_user);
> @@ -356,8 +353,7 @@ static void net_vhost_user_event(void *opaque, QEMUChrEvent event)
>          if (s->watch) {
>              AioContext *ctx = qemu_get_current_aio_context();
> 
> -            g_source_remove(s->watch);
> -            s->watch = 0;
> +            g_clear_handle_id(&s->watch, g_source_remove);
>              qemu_chr_fe_set_handlers(&s->chr, NULL, NULL, NULL, NULL,
>                                       NULL, NULL, false);
> 
> diff --git a/ui/dbus-clipboard.c b/ui/dbus-clipboard.c
> index 935b6b1a2ac..90318384ee4 100644
> --- a/ui/dbus-clipboard.c
> +++ b/ui/dbus-clipboard.c
> @@ -80,8 +80,7 @@ dbus_clipboard_update_info(DBusDisplay *dpy, QemuClipboardInfo *info)
>      if (req->invocation && info->types[req->type].data) {
>          dbus_clipboard_complete_request(dpy, req->invocation, info, req->type);
>          g_clear_object(&req->invocation);
> -        g_source_remove(req->timeout_id);
> -        req->timeout_id = 0;
> +        g_clear_handle_id(&req->timeout_id, g_source_remove);
>          return;
>      }
> 
> @@ -183,8 +182,7 @@ dbus_clipboard_request_cancelled(DBusClipboardRequest *req)
>          "Cancelled clipboard request");
> 
>      g_clear_object(&req->invocation);
> -    g_source_remove(req->timeout_id);
> -    req->timeout_id = 0;
> +    g_clear_handle_id(&req->timeout_id, g_source_remove);
>  }
> 
>  static void
> diff --git a/ui/input-barrier.c b/ui/input-barrier.c
> index 0a2198ca500..84212c50442 100644
> --- a/ui/input-barrier.c
> +++ b/ui/input-barrier.c
> @@ -518,11 +518,7 @@ static void input_barrier_complete(UserCreatable *uc, Error **errp)
>  static void input_barrier_instance_finalize(Object *obj)
>  {
>      InputBarrier *ib = INPUT_BARRIER(obj);
> -
> -    if (ib->ioc_tag) {
> -        g_source_remove(ib->ioc_tag);
> -        ib->ioc_tag = 0;
> -    }
> +    g_clear_handle_id(&ib->ioc_tag, g_source_remove);
> 
>      if (ib->sioc) {
>          qio_channel_close(QIO_CHANNEL(ib->sioc), NULL);
> diff --git a/ui/vnc-auth-vencrypt.c b/ui/vnc-auth-vencrypt.c
> index d9c212ff328..a1b8cde2292 100644
> --- a/ui/vnc-auth-vencrypt.c
> +++ b/ui/vnc-auth-vencrypt.c
> @@ -101,11 +101,7 @@ static int protocol_client_vencrypt_auth(VncState *vs, uint8_t *data, size_t len
>          QIOChannelTLS *tls;
>          vnc_write_u8(vs, 1); /* Accept auth */
>          vnc_flush(vs);
> -
> -        if (vs->ioc_tag) {
> -            g_source_remove(vs->ioc_tag);
> -            vs->ioc_tag = 0;
> -        }
> +        g_clear_handle_id(&vs->ioc_tag, g_source_remove);
> 
>          tls = qio_channel_tls_new_server(
>              vs->ioc,
> diff --git a/ui/vnc-ws.c b/ui/vnc-ws.c
> index 9e3503d93d8..65e8b344b65 100644
> --- a/ui/vnc-ws.c
> +++ b/ui/vnc-ws.c
> @@ -54,11 +54,7 @@ gboolean vncws_tls_handshake_io(QIOChannel *ioc G_GNUC_UNUSED,
>      VncState *vs = opaque;
>      QIOChannelTLS *tls;
>      Error *err = NULL;
> -
> -    if (vs->ioc_tag) {
> -        g_source_remove(vs->ioc_tag);
> -        vs->ioc_tag = 0;
> -    }
> +    g_clear_handle_id(&vs->ioc_tag, g_source_remove);
> 
>      if (condition & (G_IO_HUP | G_IO_ERR)) {
>          vnc_client_error(vs);
> @@ -123,11 +119,7 @@ gboolean vncws_handshake_io(QIOChannel *ioc G_GNUC_UNUSED,
>  {
>      VncState *vs = opaque;
>      QIOChannelWebsock *wioc;
> -
> -    if (vs->ioc_tag) {
> -        g_source_remove(vs->ioc_tag);
> -        vs->ioc_tag = 0;
> -    }
> +    g_clear_handle_id(&vs->ioc_tag, g_source_remove);
> 
>      if (condition & (G_IO_HUP | G_IO_ERR)) {
>          vnc_client_error(vs);
> --
> 2.53.0
> 
>