summary refs log tree commit diff stats
path: root/chardev/char.c
diff options
context:
space:
mode:
Diffstat (limited to 'chardev/char.c')
-rw-r--r--chardev/char.c174
1 files changed, 1 insertions, 173 deletions
diff --git a/chardev/char.c b/chardev/char.c
index 722c98dc33..3cbe42a1a8 100644
--- a/chardev/char.c
+++ b/chardev/char.c
@@ -86,6 +86,7 @@
 #include "ui/qemu-spice.h"
 
 #include "char-mux.h"
+#include "char-io.h"
 
 #define TCP_MAX_FDS 16
 
@@ -479,8 +480,6 @@ void qemu_chr_fe_printf(CharBackend *be, const char *fmt, ...)
     va_end(ap);
 }
 
-static void remove_fd_in_watch(Chardev *chr);
-
 static void qemu_char_open(Chardev *chr, ChardevBackend *backend,
                            bool *be_opened, Error **errp)
 {
@@ -716,178 +715,7 @@ void qemu_chr_fe_take_focus(CharBackend *b)
     }
 }
 
-typedef struct IOWatchPoll
-{
-    GSource parent;
-
-    QIOChannel *ioc;
-    GSource *src;
-
-    IOCanReadHandler *fd_can_read;
-    GSourceFunc fd_read;
-    void *opaque;
-    GMainContext *context;
-} IOWatchPoll;
-
-static IOWatchPoll *io_watch_poll_from_source(GSource *source)
-{
-    return container_of(source, IOWatchPoll, parent);
-}
-
-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;
-    bool was_active = iwp->src != NULL;
-    if (was_active == now_active) {
-        return FALSE;
-    }
-
-    if (now_active) {
-        iwp->src = qio_channel_create_watch(
-            iwp->ioc, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL);
-        g_source_set_callback(iwp->src, iwp->fd_read, iwp->opaque, NULL);
-        g_source_attach(iwp->src, iwp->context);
-    } else {
-        g_source_destroy(iwp->src);
-        g_source_unref(iwp->src);
-        iwp->src = NULL;
-    }
-    return FALSE;
-}
-
-static gboolean io_watch_poll_check(GSource *source)
-{
-    return FALSE;
-}
-
-static gboolean io_watch_poll_dispatch(GSource *source, GSourceFunc callback,
-                                       gpointer user_data)
-{
-    abort();
-}
-
-static void io_watch_poll_finalize(GSource *source)
-{
-    /* Due to a glib bug, removing the last reference to a source
-     * inside a finalize callback causes recursive locking (and a
-     * deadlock).  This is not a problem inside other callbacks,
-     * including dispatch callbacks, so we call io_remove_watch_poll
-     * to remove this source.  At this point, iwp->src must
-     * be NULL, or we would leak it.
-     *
-     * This would be solved much more elegantly by child sources,
-     * but we support older glib versions that do not have them.
-     */
-    IOWatchPoll *iwp = io_watch_poll_from_source(source);
-    assert(iwp->src == NULL);
-}
-
-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(Chardev *chr,
-                               QIOChannel *ioc,
-                               IOCanReadHandler *fd_can_read,
-                               QIOChannelFunc fd_read,
-                               gpointer user_data,
-                               GMainContext *context)
-{
-    IOWatchPoll *iwp;
-    int tag;
-    char *name;
-
-    iwp = (IOWatchPoll *) g_source_new(&io_watch_poll_funcs,
-                                       sizeof(IOWatchPoll));
-    iwp->fd_can_read = fd_can_read;
-    iwp->opaque = user_data;
-    iwp->ioc = ioc;
-    iwp->fd_read = (GSourceFunc) fd_read;
-    iwp->src = NULL;
-    iwp->context = context;
-
-    name = g_strdup_printf("chardev-iowatch-%s", chr->label);
-    g_source_set_name((GSource *)iwp, name);
-    g_free(name);
-
-    tag = g_source_attach(&iwp->parent, context);
-    g_source_unref(&iwp->parent);
-    return tag;
-}
-
-static void io_remove_watch_poll(guint tag)
-{
-    GSource *source;
-    IOWatchPoll *iwp;
-
-    g_return_if_fail (tag > 0);
-
-    source = g_main_context_find_source_by_id(NULL, tag);
-    g_return_if_fail (source != NULL);
-
-    iwp = io_watch_poll_from_source(source);
-    if (iwp->src) {
-        g_source_destroy(iwp->src);
-        g_source_unref(iwp->src);
-        iwp->src = NULL;
-    }
-    g_source_destroy(&iwp->parent);
-}
-
-static void remove_fd_in_watch(Chardev *chr)
-{
-    if (chr->fd_in_tag) {
-        io_remove_watch_poll(chr->fd_in_tag);
-        chr->fd_in_tag = 0;
-    }
-}
-
-
-static int io_channel_send_full(QIOChannel *ioc,
-                                const void *buf, size_t len,
-                                int *fds, size_t nfds)
-{
-    size_t offset = 0;
-
-    while (offset < len) {
-        ssize_t ret = 0;
-        struct iovec iov = { .iov_base = (char *)buf + offset,
-                             .iov_len = len - offset };
-
-        ret = qio_channel_writev_full(
-            ioc, &iov, 1,
-            fds, nfds, NULL);
-        if (ret == QIO_CHANNEL_ERR_BLOCK) {
-            if (offset) {
-                return offset;
-            }
-
-            errno = EAGAIN;
-            return -1;
-        } else if (ret < 0) {
-            errno = EINVAL;
-            return -1;
-        }
-
-        offset += ret;
-    }
-
-    return offset;
-}
-
-
 #ifndef _WIN32
-static int io_channel_send(QIOChannel *ioc, const void *buf, size_t len)
-{
-    return io_channel_send_full(ioc, buf, len, NULL, 0);
-}
-
 typedef struct FDChardev {
     Chardev parent;
     Chardev *chr;