File io-move-websock-resource-release-to-clos.patch of Package qemu.42505
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Tue, 30 Sep 2025 11:58:35 +0100
Subject: io: move websock resource release to close method
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The QIOChannelWebsock object releases all its resources in the
finalize callback. This is later than desired, as callers expect
to be able to call qio_channel_close() to fully close a channel
and release resources related to I/O.
The logic in the finalize method is at most a failsafe to handle
cases where a consumer forgets to call qio_channel_close.
This adds equivalent logic to the close method to release the
resources, using g_clear_handle_id/g_clear_pointer to be robust
against repeated invocations. The finalize method is tweaked
so that the GSource is removed before releasing the underlying
channel.
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 322c3c4f3abee616a18b3bfe563ec29dd67eae63)
References: bsc#1250984
Signed-off-by: Dario Faggioli <dfaggioli@suse.com>
---
io/channel-websock.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/io/channel-websock.c b/io/channel-websock.c
index 03c1f7cb62f77af2b0bef66207db..496d8e08bd4c9f2326f56c0daf5c 100644
--- a/io/channel-websock.c
+++ b/io/channel-websock.c
@@ -927,13 +927,13 @@ static void qio_channel_websock_finalize(Object *obj)
buffer_free(&ioc->encinput);
buffer_free(&ioc->encoutput);
buffer_free(&ioc->rawinput);
- object_unref(OBJECT(ioc->master));
if (ioc->io_tag) {
g_source_remove(ioc->io_tag);
}
if (ioc->io_err) {
error_free(ioc->io_err);
}
+ object_unref(OBJECT(ioc->master));
}
@@ -1222,6 +1222,16 @@ static int qio_channel_websock_close(QIOChannel *ioc,
QIOChannelWebsock *wioc = QIO_CHANNEL_WEBSOCK(ioc);
trace_qio_channel_websock_close(ioc);
+ buffer_free(&wioc->encinput);
+ buffer_free(&wioc->encoutput);
+ buffer_free(&wioc->rawinput);
+ if (wioc->io_tag) {
+ g_source_remove(wioc->io_tag);
+ wioc->io_tag = 0;
+ }
+ if (wioc->io_err) {
+ g_clear_pointer(&wioc->io_err, error_free);
+ }
return qio_channel_close(wioc->master, errp);
}