[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 03/19] char: add IOWatchPoll support
From: |
Anthony Liguori |
Subject: |
[Qemu-devel] [PATCH 03/19] char: add IOWatchPoll support |
Date: |
Mon, 18 Feb 2013 15:48:00 -0600 |
This is a special GSource that supports CharDriverState style
poll callbacks.
For reviewability and bisectability, this code is #if 0'd out in this
patch to avoid unused warnings since all of the functions are static.
Signed-off-by: Anthony Liguori <address@hidden>
Signed-off-by: Amit Shah <address@hidden>
---
qemu-char.c | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 140 insertions(+)
diff --git a/qemu-char.c b/qemu-char.c
index 7a3278d..2dc8510 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -541,6 +541,146 @@ int send_all(int fd, const void *_buf, int len1)
#ifndef _WIN32
+#if 0
+typedef struct IOWatchPoll
+{
+ GSource *src;
+ int max_size;
+
+ IOCanReadHandler *fd_can_read;
+ void *opaque;
+
+ QTAILQ_ENTRY(IOWatchPoll) node;
+} IOWatchPoll;
+
+static QTAILQ_HEAD(, IOWatchPoll) io_watch_poll_list =
+ QTAILQ_HEAD_INITIALIZER(io_watch_poll_list);
+
+static IOWatchPoll *io_watch_poll_from_source(GSource *source)
+{
+ IOWatchPoll *i;
+
+ QTAILQ_FOREACH(i, &io_watch_poll_list, node) {
+ if (i->src == source) {
+ return i;
+ }
+ }
+
+ return NULL;
+}
+
+static gboolean io_watch_poll_prepare(GSource *source, gint *timeout_)
+{
+ IOWatchPoll *iwp = io_watch_poll_from_source(source);
+
+ iwp->max_size = iwp->fd_can_read(iwp->opaque);
+ if (iwp->max_size == 0) {
+ return FALSE;
+ }
+
+ return g_io_watch_funcs.prepare(source, timeout_);
+}
+
+static gboolean io_watch_poll_check(GSource *source)
+{
+ IOWatchPoll *iwp = io_watch_poll_from_source(source);
+
+ if (iwp->max_size == 0) {
+ return FALSE;
+ }
+
+ return g_io_watch_funcs.check(source);
+}
+
+static gboolean io_watch_poll_dispatch(GSource *source, GSourceFunc callback,
+ gpointer user_data)
+{
+ return g_io_watch_funcs.dispatch(source, callback, user_data);
+}
+
+static void io_watch_poll_finalize(GSource *source)
+{
+ IOWatchPoll *iwp = io_watch_poll_from_source(source);
+ QTAILQ_REMOVE(&io_watch_poll_list, iwp, node);
+ g_io_watch_funcs.finalize(source);
+}
+
+static GSourceFuncs io_watch_poll_funcs = {
+ .prepare = io_watch_poll_prepare,
+ .check = io_watch_poll_check,
+ .dispatch = io_watch_poll_dispatch,
+ .finalize = io_watch_poll_finalize,
+};
+
+/* Can only be used for read */
+static guint io_add_watch_poll(GIOChannel *channel,
+ IOCanReadHandler *fd_can_read,
+ GIOFunc fd_read,
+ gpointer user_data)
+{
+ IOWatchPoll *iwp;
+ GSource *src;
+ guint tag;
+
+ src = g_io_create_watch(channel, G_IO_IN | G_IO_ERR | G_IO_HUP);
+ g_source_set_funcs(src, &io_watch_poll_funcs);
+ g_source_set_callback(src, (GSourceFunc)fd_read, user_data, NULL);
+ tag = g_source_attach(src, NULL);
+ g_source_unref(src);
+
+ iwp = g_malloc0(sizeof(*iwp));
+ iwp->src = src;
+ iwp->max_size = 0;
+ iwp->fd_can_read = fd_can_read;
+ iwp->opaque = user_data;
+
+ QTAILQ_INSERT_HEAD(&io_watch_poll_list, iwp, node);
+
+ return tag;
+}
+
+static GIOChannel *io_channel_from_fd(int fd)
+{
+ GIOChannel *chan;
+
+ if (fd == -1) {
+ return NULL;
+ }
+
+ chan = g_io_channel_unix_new(fd);
+
+ g_io_channel_set_encoding(chan, NULL, NULL);
+ g_io_channel_set_buffered(chan, FALSE);
+
+ return chan;
+}
+
+static int io_channel_send_all(GIOChannel *fd, const void *_buf, int len1)
+{
+ GIOStatus status;
+ gsize bytes_written;
+ int len;
+ const uint8_t *buf = _buf;
+
+ len = len1;
+ while (len > 0) {
+ status = g_io_channel_write_chars(fd, (const gchar *)buf, len,
+ &bytes_written, NULL);
+ if (status != G_IO_STATUS_NORMAL) {
+ if (status != G_IO_STATUS_AGAIN) {
+ return -1;
+ }
+ } else if (status == G_IO_STATUS_EOF) {
+ break;
+ } else {
+ buf += bytes_written;
+ len -= bytes_written;
+ }
+ }
+ return len1 - len;
+}
+#endif
+
typedef struct {
int fd_in, fd_out;
int max_size;
--
1.8.0
- [Qemu-devel] [PATCH 18/19] serial: add flow control to transmit, (continued)
- [Qemu-devel] [PATCH 18/19] serial: add flow control to transmit, Anthony Liguori, 2013/02/18
- [Qemu-devel] [PATCH 15/19] qemu-char: move baum registration to baum.c, Anthony Liguori, 2013/02/18
- [Qemu-devel] [PATCH 16/19] qemu-char: move msmouse registeration to msmouse.c, Anthony Liguori, 2013/02/18
- [Qemu-devel] [PATCH 17/19] qemu-char: move text console init to console.c, Anthony Liguori, 2013/02/18
- [Qemu-devel] [PATCH 02/19] qemu-char: remove dead/confusing logic with nb_stdio_clients, Anthony Liguori, 2013/02/18
- [Qemu-devel] [PATCH 04/19] qemu-char: convert fd_chr to use a GIOChannel, Anthony Liguori, 2013/02/18
- [Qemu-devel] [PATCH 05/19] qemu-char: convert pty to GIOChannel, Anthony Liguori, 2013/02/19
- Re: [Qemu-devel] [PATCH 00/19] chardev flow control, Amit Shah, 2013/02/19
- Re: [Qemu-devel] [PATCH 00/19] chardev flow control, Hans de Goede, 2013/02/19
- [Qemu-devel] [PATCH 03/19] char: add IOWatchPoll support,
Anthony Liguori <=
- [Qemu-devel] [PATCH 01/19] char-socket: fix error reporting, Anthony Liguori, 2013/02/19