io: Add qio_channel_wait_cond() helper

Add the helper to wait for QIO channel's IO availability in any
context (coroutine, or non-coroutine).  Use it tree-wide for three
occurences.

Cc: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Link: https://lore.kernel.org/r/20251022192612.2737648-2-peterx@redhat.com
Signed-off-by: Peter Xu <peterx@redhat.com>
This commit is contained in:
Peter Xu 2025-10-22 15:26:00 -04:00
parent 5777e20718
commit 1edf0df284
3 changed files with 27 additions and 15 deletions

View file

@ -871,6 +871,21 @@ void qio_channel_wake_read(QIOChannel *ioc);
void qio_channel_wait(QIOChannel *ioc,
GIOCondition condition);
/**
* qio_channel_wait_cond:
* @ioc: the channel object
* @condition: the I/O condition to wait for
*
* Block execution from the current thread until
* the condition indicated by @condition becomes
* available.
*
* This will work with/without a coroutine context, by automatically select
* the proper API to wait.
*/
void qio_channel_wait_cond(QIOChannel *ioc,
GIOCondition condition);
/**
* qio_channel_set_aio_fd_handler:
* @ioc: the channel object

View file

@ -159,11 +159,7 @@ int coroutine_mixed_fn qio_channel_readv_full_all_eof(QIOChannel *ioc,
len = qio_channel_readv_full(ioc, local_iov, nlocal_iov, local_fds,
local_nfds, flags, errp);
if (len == QIO_CHANNEL_ERR_BLOCK) {
if (qemu_in_coroutine()) {
qio_channel_yield(ioc, G_IO_IN);
} else {
qio_channel_wait(ioc, G_IO_IN);
}
qio_channel_wait_cond(ioc, G_IO_IN);
continue;
}
@ -268,11 +264,7 @@ int coroutine_mixed_fn qio_channel_writev_full_all(QIOChannel *ioc,
nfds, flags, errp);
if (len == QIO_CHANNEL_ERR_BLOCK) {
if (qemu_in_coroutine()) {
qio_channel_yield(ioc, G_IO_OUT);
} else {
qio_channel_wait(ioc, G_IO_OUT);
}
qio_channel_wait_cond(ioc, G_IO_OUT);
continue;
}
if (len < 0) {
@ -774,6 +766,15 @@ void qio_channel_wait(QIOChannel *ioc,
g_main_context_unref(ctxt);
}
void qio_channel_wait_cond(QIOChannel *ioc,
GIOCondition condition)
{
if (qemu_in_coroutine()) {
qio_channel_yield(ioc, condition);
} else {
qio_channel_wait(ioc, condition);
}
}
static void qio_channel_finalize(Object *obj)
{

View file

@ -343,11 +343,7 @@ static ssize_t coroutine_mixed_fn qemu_fill_buffer(QEMUFile *f)
QIO_CHANNEL_READ_FLAG_FD_PRESERVE_BLOCKING,
&local_error);
if (len == QIO_CHANNEL_ERR_BLOCK) {
if (qemu_in_coroutine()) {
qio_channel_yield(f->ioc, G_IO_IN);
} else {
qio_channel_wait(f->ioc, G_IO_IN);
}
qio_channel_wait_cond(f->ioc, G_IO_IN);
}
} while (len == QIO_CHANNEL_ERR_BLOCK);