diff src/director/doveadm-connection.c @ 14681:ca37d1577291

Added o_stream_nsend*() and related functions to make delayed error handling safer. Once o_stream_nsend*() is called, o_stream_nfinish() must be called before stream is destroyed to finish checking if there were any errors. If something failed and the stream is just wanted to be closed, o_stream_ignore_last_errors() can be called. For streams where errors don't really make any difference (network sockets) you can call o_stream_set_no_error_handling() immediately after creating the stream.
author Timo Sirainen <tss@iki.fi>
date Mon, 25 Jun 2012 00:01:59 +0300
parents 42cca8a1d179
children d0d7b810646b
line wrap: on
line diff
--- a/src/director/doveadm-connection.c	Sun Jun 24 21:43:48 2012 +0300
+++ b/src/director/doveadm-connection.c	Mon Jun 25 00:01:59 2012 +0300
@@ -51,7 +51,7 @@
 			    (*hostp)->user_count);
 	}
 	str_append_c(str, '\n');
-	o_stream_send(conn->output, str_data(str), str_len(str));
+	o_stream_nsend(conn->output, str_data(str), str_len(str));
 }
 
 static void doveadm_cmd_host_list_removed(struct doveadm_connection *conn)
@@ -87,7 +87,7 @@
 	for (; i < orig_hosts_count; i++)
 		str_printfa(str, "%s\n", net_ip2addr(&orig_hosts[i]->ip));
 	str_append_c(str, '\n');
-	o_stream_send(conn->output, str_data(str), str_len(str));
+	o_stream_nsend(conn->output, str_data(str), str_len(str));
 
 	mail_hosts_deinit(&orig_hosts_list);
 }
@@ -127,7 +127,7 @@
 			    (unsigned long)last_failed);
 	}
 	str_append_c(str, '\n');
-	o_stream_send(conn->output, str_data(str), str_len(str));
+	o_stream_nsend(conn->output, str_data(str), str_len(str));
 }
 
 static bool
@@ -150,7 +150,7 @@
 		host = director_host_add(conn->dir, &ip, port);
 		director_notify_ring_added(host, conn->dir->self_host);
 	}
-	o_stream_send(conn->output, "OK\n", 3);
+	o_stream_nsend(conn->output, "OK\n", 3);
 	return TRUE;
 }
 
@@ -174,10 +174,10 @@
 		director_host_lookup(conn->dir, &ip, port) :
 		director_host_lookup_ip(conn->dir, &ip);
 	if (host == NULL)
-		o_stream_send_str(conn->output, "NOTFOUND\n");
+		o_stream_nsend_str(conn->output, "NOTFOUND\n");
 	else {
 		director_ring_remove(host, conn->dir->self_host);
-		o_stream_send(conn->output, "OK\n", 3);
+		o_stream_nsend(conn->output, "OK\n", 3);
 	}
 	return TRUE;
 }
@@ -199,7 +199,7 @@
 		return FALSE;
 	}
 	if (vhost_count > MAX_VALID_VHOST_COUNT && vhost_count != -1U) {
-		o_stream_send_str(conn->output, "vhost count too large\n");
+		o_stream_nsend_str(conn->output, "vhost count too large\n");
 		return TRUE;
 	}
 	host = mail_host_lookup(dir->mail_hosts, &ip);
@@ -209,7 +209,7 @@
 		mail_host_set_vhost_count(dir->mail_hosts, host, vhost_count);
 	director_update_host(dir, dir->self_host, NULL, host);
 
-	o_stream_send(conn->output, "OK\n", 3);
+	o_stream_nsend(conn->output, "OK\n", 3);
 	return TRUE;
 }
 
@@ -225,11 +225,11 @@
 	}
 	host = mail_host_lookup(conn->dir->mail_hosts, &ip);
 	if (host == NULL)
-		o_stream_send_str(conn->output, "NOTFOUND\n");
+		o_stream_nsend_str(conn->output, "NOTFOUND\n");
 	else {
 		director_remove_host(conn->dir, conn->dir->self_host,
 				     NULL, host);
-		o_stream_send(conn->output, "OK\n", 3);
+		o_stream_nsend(conn->output, "OK\n", 3);
 	}
 	return TRUE;
 }
@@ -243,7 +243,7 @@
 		director_flush_host(conn->dir, conn->dir->self_host,
 				    NULL, *hostp);
 	}
-	o_stream_send(conn->output, "OK\n", 3);
+	o_stream_nsend(conn->output, "OK\n", 3);
 }
 
 static bool
@@ -263,11 +263,11 @@
 	}
 	host = mail_host_lookup(conn->dir->mail_hosts, &ip);
 	if (host == NULL)
-		o_stream_send_str(conn->output, "NOTFOUND\n");
+		o_stream_nsend_str(conn->output, "NOTFOUND\n");
 	else {
 		director_flush_host(conn->dir, conn->dir->self_host,
 				    NULL, host);
-		o_stream_send(conn->output, "OK\n", 3);
+		o_stream_nsend(conn->output, "OK\n", 3);
 	}
 	return TRUE;
 }
@@ -307,7 +307,7 @@
 		str_append(str, "\t");
 	else
 		str_printfa(str, "\t%s\n", net_ip2addr(&host->ip));
-	o_stream_send(conn->output, str_data(str), str_len(str));
+	o_stream_nsend(conn->output, str_data(str), str_len(str));
 	return TRUE;
 }
 
@@ -334,14 +334,14 @@
 			unsigned int expire_time = user->timestamp +
 				conn->dir->set->director_user_expire;
 
-			o_stream_send_str(conn->output, t_strdup_printf(
+			o_stream_nsend_str(conn->output, t_strdup_printf(
 				"%u\t%u\t%s\n",
 				user->username_hash, expire_time,
 				net_ip2addr(&user->host->ip)));
 		} T_END;
 	}
 	user_directory_iter_deinit(&iter);
-	o_stream_send(conn->output, "\n", 1);
+	o_stream_nsend(conn->output, "\n", 1);
 	return TRUE;
 }
 
@@ -362,7 +362,7 @@
 	}
 	host = mail_host_lookup(conn->dir->mail_hosts, &ip);
 	if (host == NULL) {
-		o_stream_send_str(conn->output, "NOTFOUND\n");
+		o_stream_nsend_str(conn->output, "NOTFOUND\n");
 		return TRUE;
 	}
 
@@ -370,13 +370,13 @@
 		username_hash = user_directory_get_username_hash(conn->dir->users, line);
 	user = user_directory_lookup(conn->dir->users, username_hash);
 	if (user != NULL && user->kill_state != USER_KILL_STATE_NONE) {
-		o_stream_send_str(conn->output, "TRYAGAIN\n");
+		o_stream_nsend_str(conn->output, "TRYAGAIN\n");
 		return TRUE;
 	}
 
 	director_move_user(conn->dir, conn->dir->self_host, NULL,
 			   username_hash, host);
-	o_stream_send(conn->output, "OK\n", 3);
+	o_stream_nsend(conn->output, "OK\n", 3);
 	return TRUE;
 }
 
@@ -453,8 +453,9 @@
 	conn->dir = dir;
 	conn->input = i_stream_create_fd(conn->fd, 1024, FALSE);
 	conn->output = o_stream_create_fd(conn->fd, (size_t)-1, FALSE);
+	o_stream_set_no_error_handling(conn->output, TRUE);
 	conn->io = io_add(conn->fd, IO_READ, doveadm_connection_input, conn);
-	o_stream_send_str(conn->output, DOVEADM_HANDSHAKE);
+	o_stream_nsend_str(conn->output, DOVEADM_HANDSHAKE);
 
 	DLLIST_PREPEND(&doveadm_connections, conn);
 	return conn;