From: Heinz Graalfs <graalfs@linux.vnet.ibm.com>
To: qemu-devel@nongnu.org
Cc: cornelia.huck@de.ibm.com, pbonzini@redhat.com,
Heinz Graalfs <graalfs@linux.vnet.ibm.com>,
borntraeger@de.ibm.com
Subject: [Qemu-devel] [RFC 1/3] char: Trigger timeouts on poll() when frontend is unready
Date: Fri, 24 Oct 2014 10:13:45 +0200 [thread overview]
Message-ID: <1414138427-60643-2-git-send-email-graalfs@linux.vnet.ibm.com> (raw)
In-Reply-To: <1414138427-60643-1-git-send-email-graalfs@linux.vnet.ibm.com>
When a character frontend returns zero on 'can_read' poll() goes on
without the backend's descriptor.
The remaining active descriptors may not be a part of the main
thread's poll; for example, if dataplane is active, activity may only
be ongoing on the dataplane thread.
This patch changes the character backend's io_watch_poll() loop logic.
If a frontend returns -EAGAIN on 'can_read' a poll() timeout
is triggered, thus the backend's descriptor has a chance to reappear within
the poll desriptor array. The timeout callback reinvokes 'can_read' to ask
the frontend if it is ready. Scheduling a timeout callback on poll() ends
when the frontend returns a non negative value on 'can_read'.
Frontends still returning zero on 'can_read' or without such callback are
not affected.
Signed-off-by: Heinz Graalfs <graalfs@linux.vnet.ibm.com>
---
qemu-char.c | 27 ++++++++++++++++++++++++++-
1 file changed, 26 insertions(+), 1 deletion(-)
diff --git a/qemu-char.c b/qemu-char.c
index 8623c70..4adf7e4 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -697,6 +697,7 @@ typedef struct IOWatchPoll
IOCanReadHandler *fd_can_read;
GSourceFunc fd_read;
void *opaque;
+ guint timer_tag;
} IOWatchPoll;
static IOWatchPoll *io_watch_poll_from_source(GSource *source)
@@ -704,19 +705,38 @@ static IOWatchPoll *io_watch_poll_from_source(GSource *source)
return container_of(source, IOWatchPoll, parent);
}
+static gboolean io_watch_timer(gpointer opaque)
+{
+ IOWatchPoll *iwp = io_watch_poll_from_source(opaque);
+
+ if (iwp->fd_can_read(iwp->opaque) == -EAGAIN) {
+ return TRUE;
+ }
+ iwp->timer_tag = 0;
+ return FALSE;
+}
+
static gboolean io_watch_poll_prepare(GSource *source, gint *timeout_)
{
IOWatchPoll *iwp = io_watch_poll_from_source(source);
- bool now_active = iwp->fd_can_read(iwp->opaque) > 0;
+ int avail = iwp->fd_can_read(iwp->opaque);
+ bool now_active = avail > 0;
+ bool use_timeout = avail == -EAGAIN;
bool was_active = iwp->src != NULL;
if (was_active == now_active) {
return FALSE;
}
+ if (iwp->timer_tag) {
+ g_source_remove(iwp->timer_tag);
+ iwp->timer_tag = 0;
+ }
if (now_active) {
iwp->src = g_io_create_watch(iwp->channel, G_IO_IN | G_IO_ERR | G_IO_HUP);
g_source_set_callback(iwp->src, iwp->fd_read, iwp->opaque, NULL);
g_source_attach(iwp->src, NULL);
+ } else if (use_timeout) {
+ iwp->timer_tag = g_timeout_add(100, io_watch_timer, source);
} else {
g_source_destroy(iwp->src);
g_source_unref(iwp->src);
@@ -774,6 +794,7 @@ static guint io_add_watch_poll(GIOChannel *channel,
iwp->channel = channel;
iwp->fd_read = (GSourceFunc) fd_read;
iwp->src = NULL;
+ iwp->timer_tag = 0;
tag = g_source_attach(&iwp->parent, NULL);
g_source_unref(&iwp->parent);
@@ -796,6 +817,10 @@ static void io_remove_watch_poll(guint tag)
g_source_unref(iwp->src);
iwp->src = NULL;
}
+ if (iwp->timer_tag) {
+ g_source_remove(iwp->timer_tag);
+ iwp->timer_tag = 0;
+ }
g_source_destroy(&iwp->parent);
}
--
1.8.3.1
next prev parent reply other threads:[~2014-10-24 8:14 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-10-24 8:13 [Qemu-devel] [RFC 0/3] qemu-char: Add poll timeouts for character backends Heinz Graalfs
2014-10-24 8:13 ` Heinz Graalfs [this message]
2014-10-24 8:13 ` [Qemu-devel] [RFC 2/3] s390x: Fix hanging SCLP line mode console Heinz Graalfs
2014-10-24 8:13 ` [Qemu-devel] [RFC 3/3] s390x: Avoid hanging SCLP ASCII console Heinz Graalfs
2014-10-24 9:15 ` [Qemu-devel] [RFC 0/3] qemu-char: Add poll timeouts for character backends Paolo Bonzini
2014-10-24 11:29 ` Heinz Graalfs
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1414138427-60643-2-git-send-email-graalfs@linux.vnet.ibm.com \
--to=graalfs@linux.vnet.ibm.com \
--cc=borntraeger@de.ibm.com \
--cc=cornelia.huck@de.ibm.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).