Blame 0111-char-Equip-the-unix-tcp-backend-to-handle-nonblockin.patch

Justin M. Forbes d4cdad
From b235c039fbab104ab582922f0083625564e177b1 Mon Sep 17 00:00:00 2001
Justin M. Forbes d4cdad
From: Amit Shah <amit.shah@redhat.com>
Justin M. Forbes d4cdad
Date: Mon, 21 Mar 2011 22:02:47 +0100
Justin M. Forbes d4cdad
Subject: [PATCH 111/118] char: Equip the unix/tcp backend to handle
Justin M. Forbes d4cdad
 nonblocking writes#
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
Now that the infrastructure is in place to return -EAGAIN to callers,
Justin M. Forbes d4cdad
individual char drivers can set their update_fd_handlers() function to
Justin M. Forbes d4cdad
set or remove an fd's write handler.  This handler checks if the driver
Justin M. Forbes d4cdad
became writable.
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
A generic callback routine is used for unblocking writes and letting
Justin M. Forbes d4cdad
users of chardevs know that a driver became writable again.
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
Signed-off-by: Amit Shah <amit.shah@redhat.com>
Justin M. Forbes d4cdad
---
Justin M. Forbes d4cdad
 qemu-char.c |   34 ++++++++++++++++++++++++++++++++++
Justin M. Forbes d4cdad
 1 files changed, 34 insertions(+), 0 deletions(-)
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
diff --git a/qemu-char.c b/qemu-char.c
Justin M. Forbes d4cdad
index 5e7f68e..f98b240 100644
Justin M. Forbes d4cdad
--- a/qemu-char.c
Justin M. Forbes d4cdad
+++ b/qemu-char.c
Justin M. Forbes d4cdad
@@ -106,6 +106,19 @@
Justin M. Forbes d4cdad
 static QTAILQ_HEAD(CharDriverStateHead, CharDriverState) chardevs =
Justin M. Forbes d4cdad
     QTAILQ_HEAD_INITIALIZER(chardevs);
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
+/*
Justin M. Forbes d4cdad
+ * Generic routine that gets called when chardev becomes writable.
Justin M. Forbes d4cdad
+ * Lets chardev user know it's OK to send more data.
Justin M. Forbes d4cdad
+ */
Justin M. Forbes d4cdad
+static void char_write_unblocked(void *opaque)
Justin M. Forbes d4cdad
+{
Justin M. Forbes d4cdad
+    CharDriverState *chr = opaque;
Justin M. Forbes d4cdad
+
Justin M. Forbes d4cdad
+    chr->write_blocked = false;
Justin M. Forbes d4cdad
+    chr->chr_disable_write_fd_handler(chr);
Justin M. Forbes d4cdad
+    chr->chr_write_unblocked(chr->handler_opaque);
Justin M. Forbes d4cdad
+}
Justin M. Forbes d4cdad
+
Justin M. Forbes d4cdad
 void qemu_chr_be_event(CharDriverState *s, int event)
Justin M. Forbes d4cdad
 {
Justin M. Forbes d4cdad
     /* Keep track if the char device is open */
Justin M. Forbes d4cdad
@@ -2515,6 +2528,25 @@ static void tcp_chr_close(CharDriverState *chr)
Justin M. Forbes d4cdad
     qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
Justin M. Forbes d4cdad
 }
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
+static void tcp_enable_write_fd_handler(CharDriverState *chr)
Justin M. Forbes d4cdad
+{
Justin M. Forbes d4cdad
+    TCPCharDriver *s = chr->opaque;
Justin M. Forbes d4cdad
+
Justin M. Forbes d4cdad
+    /*
Justin M. Forbes d4cdad
+     * This function is called only after tcp_chr_connect() is called
Justin M. Forbes d4cdad
+     * (either in 'server' mode or client mode.  So we're sure of
Justin M. Forbes d4cdad
+     * s->fd being initialised.
Justin M. Forbes d4cdad
+     */
Justin M. Forbes d4cdad
+    enable_write_fd_handler(s->fd, char_write_unblocked);
Justin M. Forbes d4cdad
+}
Justin M. Forbes d4cdad
+
Justin M. Forbes d4cdad
+static void tcp_disable_write_fd_handler(CharDriverState *chr)
Justin M. Forbes d4cdad
+{
Justin M. Forbes d4cdad
+    TCPCharDriver *s = chr->opaque;
Justin M. Forbes d4cdad
+
Justin M. Forbes d4cdad
+    disable_write_fd_handler(s->fd);
Justin M. Forbes d4cdad
+}
Justin M. Forbes d4cdad
+
Justin M. Forbes d4cdad
 static int qemu_chr_open_socket(QemuOpts *opts, CharDriverState **_chr)
Justin M. Forbes d4cdad
 {
Justin M. Forbes d4cdad
     CharDriverState *chr = NULL;
Justin M. Forbes d4cdad
@@ -2571,6 +2603,8 @@ static int qemu_chr_open_socket(QemuOpts *opts, CharDriverState **_chr)
Justin M. Forbes d4cdad
     chr->chr_close = tcp_chr_close;
Justin M. Forbes d4cdad
     chr->get_msgfd = tcp_get_msgfd;
Justin M. Forbes d4cdad
     chr->chr_add_client = tcp_chr_add_client;
Justin M. Forbes d4cdad
+    chr->chr_enable_write_fd_handler = tcp_enable_write_fd_handler;
Justin M. Forbes d4cdad
+    chr->chr_disable_write_fd_handler = tcp_disable_write_fd_handler;
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
     if (is_listen) {
Justin M. Forbes d4cdad
         s->listen_fd = fd;
Justin M. Forbes d4cdad
-- 
Justin M. Forbes d4cdad
1.7.7.5
Justin M. Forbes d4cdad