On 18/02/19 17:18, Kevin Wolf wrote: > Similar to how qemu_co_sleep_ns() allows to be preempted by an external > coroutine entry, allow reentering qio_channel_yield() early. > > Signed-off-by: Kevin Wolf <kw...@redhat.com> > --- > include/io/channel.h | 9 ++++++--- > io/channel.c | 10 ++++++++++ > 2 files changed, 16 insertions(+), 3 deletions(-) > > diff --git a/include/io/channel.h b/include/io/channel.h > index da2f138200..59460cb1ec 100644 > --- a/include/io/channel.h > +++ b/include/io/channel.h > @@ -739,10 +739,13 @@ void qio_channel_detach_aio_context(QIOChannel *ioc); > * addition, no two coroutine can be waiting on the same condition > * and channel at the same time. > * > - * This must only be called from coroutine context > + * This must only be called from coroutine context. It is safe to > + * reenter the coroutine externally while it is waiting; in this > + * case the function will return even if @condition is not yet > + * available. > */ > -void qio_channel_yield(QIOChannel *ioc, > - GIOCondition condition); > +void coroutine_fn qio_channel_yield(QIOChannel *ioc, > + GIOCondition condition); > > /** > * qio_channel_wait: > diff --git a/io/channel.c b/io/channel.c > index 8dd0684f5d..303376e08d 100644 > --- a/io/channel.c > +++ b/io/channel.c > @@ -469,6 +469,16 @@ void coroutine_fn qio_channel_yield(QIOChannel *ioc, > } > qio_channel_set_aio_fd_handlers(ioc); > qemu_coroutine_yield(); > + > + /* Allow interrupting the operation by reentering the coroutine other > than > + * through the aio_fd_handlers. */ > + if (condition == G_IO_IN && ioc->read_coroutine) { > + ioc->read_coroutine = NULL; > + qio_channel_set_aio_fd_handlers(ioc); > + } else if (condition == G_IO_OUT && ioc->write_coroutine) { > + ioc->write_coroutine = NULL; > + qio_channel_set_aio_fd_handlers(ioc); > + } > } > > >
Perhaps it's a bit cleaner to remove the ioc->..._coroutine assignments, and the call to qio_channel_set_aio_fd_handlers, from qio_channel_restart_read and qio_channel_restart_write. Paolo