discover: Don't free clients on write failure
authorJeremy Kerr <jk@ozlabs.org>
Tue, 15 Oct 2013 02:25:23 +0000 (10:25 +0800)
committerJeremy Kerr <jk@ozlabs.org>
Tue, 15 Oct 2013 03:19:55 +0000 (11:19 +0800)
Currently, if we see an error when writing to a client, we free the
client immediately. This means that any pending reads will be discarded.
Additionally, if a client disconnects before we have finished the writes in
discover_server_process_connection, we won't register the waiter to read
from the socket.

Instead of freeing the client on write failure, this change sets a flag
(se we don't continue to write), and we rely on the read EOF to free the
client. This means we don't drop incoming messages.

Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
discover/discover-server.c

index 25dbd1476cdd9d6cf2ba817d74716d7944e40542..2467e33dc97ac5b9cfc45c44576f18d6f969c79a 100644 (file)
@@ -34,6 +34,7 @@ struct client {
        struct list_item list;
        struct waiter *waiter;
        int fd;
+       bool remote_closed;
 };
 
 
@@ -89,9 +90,12 @@ static int client_write_message(
 {
        int rc;
 
+       if (client->remote_closed)
+               return -1;
+
        rc = pb_protocol_write_message(client->fd, message);
        if (rc)
-               talloc_free(client);
+               client->remote_closed = true;
 
        return rc;
 }
@@ -250,6 +254,9 @@ static int discover_server_process_connection(void *arg)
 
        client->fd = fd;
        client->server = server;
+       client->waiter = waiter_register_io(server->waitset, client->fd,
+                               WAIT_IN, discover_server_process_message,
+                               client);
 
        /* send sysinfo to client */
        rc = write_system_info_message(server, client, system_info_get());
@@ -275,10 +282,6 @@ static int discover_server_process_connection(void *arg)
                }
        }
 
-       client->waiter = waiter_register_io(server->waitset, client->fd,
-                               WAIT_IN, discover_server_process_message,
-                               client);
-
        return 0;
 }