changeset 20612:e8a85457b96d

doveadm: Fixed hanging when printing output from different server connections.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Mon, 08 Aug 2016 19:24:08 +0300
parents be966bc4b758
children f29b99e582a8
files src/doveadm/server-connection.c
diffstat 1 files changed, 29 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/src/doveadm/server-connection.c	Mon Aug 08 19:22:15 2016 +0300
+++ b/src/doveadm/server-connection.c	Mon Aug 08 19:24:08 2016 +0300
@@ -58,18 +58,29 @@
 };
 
 static struct server_connection *printing_conn = NULL;
+static ARRAY(struct doveadm_server *) print_pending_servers = ARRAY_INIT;
 
 static void server_connection_input(struct server_connection *conn);
 static bool server_connection_input_one(struct server_connection *conn);
 
-static void print_connection_released(void)
+static void server_set_print_pending(struct doveadm_server *server)
 {
-	struct doveadm_server *server = printing_conn->server;
+	struct doveadm_server *const *serverp;
+
+	if (!array_is_created(&print_pending_servers))
+		i_array_init(&print_pending_servers, 16);
+	array_foreach(&print_pending_servers, serverp) {
+		if (*serverp == server)
+			return;
+	}
+	array_append(&print_pending_servers, &server, 1);
+}
+
+static void server_print_connection_released(struct doveadm_server *server)
+{
 	struct server_connection *const *conns;
 	unsigned int i, count;
 
-	printing_conn = NULL;
-
 	conns = array_get(&server->connections, &count);
 	for (i = 0; i < count; i++) {
 		if (conns[i]->io != NULL)
@@ -82,6 +93,19 @@
 	}
 }
 
+static void print_connection_released(void)
+{
+	struct doveadm_server *const *serverp;
+
+	printing_conn = NULL;
+	if (!array_is_created(&print_pending_servers))
+		return;
+
+	array_foreach(&print_pending_servers, serverp)
+		server_print_connection_released(*serverp);
+	array_free(&print_pending_servers);
+}
+
 static int server_connection_send_cmd_input_more(struct server_connection *conn)
 {
 	off_t ret;
@@ -180,6 +204,7 @@
 	} else {
 		/* someone else is printing. don't continue until it
 		   goes away */
+		server_set_print_pending(conn->server);
 		io_remove(&conn->io);
 		return;
 	}