aboutsummaryrefslogtreecommitdiff
path: root/qemu-char.c
diff options
context:
space:
mode:
authorAnthony Liguori <aliguori@us.ibm.com>2013-03-05 23:21:18 +0530
committerAnthony Liguori <aliguori@us.ibm.com>2013-03-08 13:57:12 -0600
commit96c6384776d631839a9c8fe02bf135f9ba22586c (patch)
treec3e7c8f498bd4b1026d379956589b26e0be4cec4 /qemu-char.c
parented7a154063266a30a31752d3b18d484ddc7f5aa9 (diff)
char: add IOWatchPoll support
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 <aliguori@us.ibm.com> Signed-off-by: Amit Shah <amit.shah@redhat.com> Message-id: 9b59ac17b9d0bb3972a73fed04d415f07b391936.1362505276.git.amit.shah@redhat.com Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Diffstat (limited to 'qemu-char.c')
-rw-r--r--qemu-char.c140
1 files changed, 140 insertions, 0 deletions
diff --git a/qemu-char.c b/qemu-char.c
index 0a74c10df7..8aa0b41954 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;