qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 08/19] qemu-char: add watch support


From: Anthony Liguori
Subject: [Qemu-devel] [PATCH 08/19] qemu-char: add watch support
Date: Mon, 18 Feb 2013 15:48:05 -0600

This allows a front-end to request for a callback when the backend
is writable again.

Signed-off-by: Anthony Liguori <address@hidden>
---
 include/char/char.h |  4 ++++
 qemu-char.c         | 32 +++++++++++++++++++++++++++++++-
 2 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/include/char/char.h b/include/char/char.h
index c91ce3c..09ac401 100644
--- a/include/char/char.h
+++ b/include/char/char.h
@@ -56,6 +56,7 @@ typedef void IOEventHandler(void *opaque, int event);
 struct CharDriverState {
     void (*init)(struct CharDriverState *s);
     int (*chr_write)(struct CharDriverState *s, const uint8_t *buf, int len);
+    GSource *(*chr_add_watch)(struct CharDriverState *s, GIOCondition cond);
     void (*chr_update_read_handler)(struct CharDriverState *s);
     int (*chr_ioctl)(struct CharDriverState *s, int cmd, void *arg);
     int (*get_msgfd)(struct CharDriverState *s);
@@ -152,6 +153,9 @@ void qemu_chr_fe_close(struct CharDriverState *chr);
 void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...)
     GCC_FMT_ATTR(2, 3);
 
+guint qemu_chr_fe_add_watch(CharDriverState *s, GIOCondition cond,
+                            GIOFunc func, void *user_data);
+
 /**
  * @qemu_chr_fe_write:
  *
diff --git a/qemu-char.c b/qemu-char.c
index 9cc6f6b..572c5ea 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -686,7 +686,11 @@ static int io_channel_send_all(GIOChannel *fd, const void 
*_buf, int len1)
         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) {
+            if (status == G_IO_STATUS_AGAIN) {
+                errno = EAGAIN;
+                return -1;
+            } else {
+                errno = EINVAL;
                 return -1;
             }
         } else if (status == G_IO_STATUS_EOF) {
@@ -753,6 +757,12 @@ static int fd_chr_read_poll(void *opaque)
     return s->max_size;
 }
 
+static GSource *fd_chr_add_watch(CharDriverState *chr, GIOCondition cond)
+{
+    FDCharDriver *s = chr->opaque;
+    return g_io_create_watch(s->fd_out, cond);
+}
+
 static void fd_chr_update_read_handler(CharDriverState *chr)
 {
     FDCharDriver *s = chr->opaque;
@@ -796,8 +806,10 @@ static CharDriverState *qemu_chr_open_fd(int fd_in, int 
fd_out)
     s = g_malloc0(sizeof(FDCharDriver));
     s->fd_in = io_channel_from_fd(fd_in);
     s->fd_out = io_channel_from_fd(fd_out);
+    fcntl(fd_out, F_SETFL, O_NONBLOCK);
     s->chr = chr;
     chr->opaque = s;
+    chr->chr_add_watch = fd_chr_add_watch;
     chr->chr_write = fd_chr_write;
     chr->chr_update_read_handler = fd_chr_update_read_handler;
     chr->chr_close = fd_chr_close;
@@ -3285,6 +3297,24 @@ void qemu_chr_fe_close(struct CharDriverState *chr)
     }
 }
 
+guint qemu_chr_fe_add_watch(CharDriverState *s, GIOCondition cond,
+                            GIOFunc func, void *user_data)
+{
+    GSource *src;
+    guint tag;
+
+    if (s->chr_add_watch == NULL) {
+        return -ENOSYS;
+    }
+
+    src = s->chr_add_watch(s, cond);
+    g_source_set_callback(src, (GSourceFunc)func, user_data, NULL);
+    tag = g_source_attach(src, NULL);
+    g_source_unref(src);
+
+    return tag;
+}
+
 void qemu_chr_delete(CharDriverState *chr)
 {
     QTAILQ_REMOVE(&chardevs, chr, next);
-- 
1.8.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]