qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH 3/7] qemu-char: Wait until socket connect to report


From: minyard
Subject: [Qemu-devel] [PATCH 3/7] qemu-char: Wait until socket connect to report connected
Date: Tue, 4 Mar 2014 18:38:53 -0600

From: Corey Minyard <address@hidden>

The socket code was reporting that a socket connection was connected
as soon as the connect call was issued.  If the connection failed, it
would then report it was not connected.  With the reconnect code, it's
better to wait until the connection is actually operational before
reporting that the socket is connected.

Signed-off-by: Corey Minyard <address@hidden>
---
 qemu-char.c | 49 ++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 40 insertions(+), 9 deletions(-)

diff --git a/qemu-char.c b/qemu-char.c
index d9838aa..6d6dd36 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2310,9 +2310,10 @@ static CharDriverState 
*qemu_chr_open_udp(CharDriverState *chr, QemuOpts *opts)
 typedef struct {
 
     GIOChannel *chan, *listen_chan;
+    int waitsrc;
     guint listen_tag;
     int fd, listen_fd;
-    int connected;
+    enum { TCP_NOT_CONNECTED, TCP_WAITING_CONNECT, TCP_CONNECTED } state;
     int max_size;
     int do_telnetopt;
     int do_nodelay;
@@ -2325,7 +2326,7 @@ static gboolean tcp_chr_accept(GIOChannel *chan, 
GIOCondition cond, void *opaque
 static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
 {
     TCPCharDriver *s = chr->opaque;
-    if (s->connected) {
+    if (s->state == TCP_CONNECTED) {
         return io_channel_send(s->chan, buf, len);
     } else {
         /* XXX: indicate an error ? */
@@ -2337,7 +2338,7 @@ static int tcp_chr_read_poll(void *opaque)
 {
     CharDriverState *chr = opaque;
     TCPCharDriver *s = chr->opaque;
-    if (!s->connected)
+    if (s->state != TCP_CONNECTED)
         return 0;
     s->max_size = qemu_chr_be_can_write(chr);
     return s->max_size;
@@ -2482,7 +2483,7 @@ static gboolean tcp_chr_read(GIOChannel *chan, 
GIOCondition cond, void *opaque)
     uint8_t buf[READ_BUF_LEN];
     int len, size;
 
-    if (!s->connected || s->max_size <= 0) {
+    if (s->state != TCP_CONNECTED || s->max_size <= 0) {
         return TRUE;
     }
     len = sizeof(buf);
@@ -2491,7 +2492,7 @@ static gboolean tcp_chr_read(GIOChannel *chan, 
GIOCondition cond, void *opaque)
     size = tcp_chr_recv(chr, (void *)buf, len);
     if (size == 0) {
         /* connection closed */
-        s->connected = 0;
+        s->state = TCP_NOT_CONNECTED;
         if (s->listen_chan) {
             s->listen_tag = g_io_add_watch(s->listen_chan, G_IO_IN, 
tcp_chr_accept, chr);
         }
@@ -2518,17 +2519,48 @@ CharDriverState *qemu_chr_open_eventfd(CharDriverState 
*chr, int eventfd)
 }
 #endif
 
-static void tcp_chr_connect(void *opaque)
+static gboolean tcp_wait_connect(GIOChannel *source,
+                                 GIOCondition condition,
+                                 gpointer opaque)
 {
     CharDriverState *chr = opaque;
     TCPCharDriver *s = chr->opaque;
 
-    s->connected = 1;
+    if (s->state != TCP_WAITING_CONNECT) {
+        return FALSE;
+    }
+    if (condition & G_IO_ERR || condition & G_IO_HUP) {
+        /* The connected failed */
+        s->state = TCP_NOT_CONNECTED;
+        g_io_channel_unref(s->chan);
+        s->chan = NULL;
+        closesocket(s->fd);
+        s->fd = -1;
+        return FALSE;
+    }
+
+    s->state = TCP_CONNECTED;
     if (s->chan) {
         chr->fd_in_tag = io_add_watch_poll(s->chan, tcp_chr_read_poll,
                                            tcp_chr_read, chr);
     }
     qemu_chr_be_generic_open(chr);
+    return FALSE;
+}
+
+static void tcp_chr_connect(void *opaque)
+{
+    CharDriverState *chr = opaque;
+    TCPCharDriver *s = chr->opaque;
+
+    s->state = TCP_WAITING_CONNECT;
+    if (s->chan) {
+        /* Wait until write becomes ready before reporting connected. */
+        s->waitsrc = g_io_add_watch(s->chan,
+                                    G_IO_OUT | G_IO_HUP | G_IO_ERR,
+                                    tcp_wait_connect,
+                                    chr);
+    }
 }
 
 #define IACSET(x,a,b,c) x[0] = a; x[1] = b; x[2] = c;
@@ -2650,7 +2682,7 @@ static CharDriverState 
*qemu_chr_open_socket_fd(CharDriverState *chr,
 
     s = g_malloc0(sizeof(TCPCharDriver));
 
-    s->connected = 0;
+    s->state = TCP_NOT_CONNECTED;
     s->fd = -1;
     s->listen_fd = -1;
     s->msgfd = -1;
@@ -2695,7 +2727,6 @@ static CharDriverState 
*qemu_chr_open_socket_fd(CharDriverState *chr,
             s->do_telnetopt = 1;
         }
     } else {
-        s->connected = 1;
         s->fd = fd;
         socket_set_nodelay(fd);
         s->chan = io_channel_from_socket(s->fd);
-- 
1.8.3.1




reply via email to

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