changeset 22809:9d921404799f

doveadm: dsync: Switch ioloop for input/output streams while making TCP connection. This task is performed in a sub-ioloop, and when returning from that ioloop, the output stream would sometimes still have an object on the sub-ioloop that was just destroyed.
author Stephan Bosch <stephan.bosch@dovecot.fi>
date Mon, 29 Jan 2018 19:10:38 +0100
parents 1bf8b3a77a92
children 41c67443c1c5
files src/doveadm/doveadm-dsync.c
diffstat 1 files changed, 15 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/doveadm/doveadm-dsync.c	Mon Jan 29 18:28:25 2018 +0100
+++ b/src/doveadm/doveadm-dsync.c	Mon Jan 29 19:10:38 2018 +0100
@@ -113,6 +113,14 @@
 
 static bool legacy_dsync = FALSE;
 
+static void dsync_cmd_switch_ioloop(struct dsync_cmd_context *ctx)
+{
+	if (ctx->input != NULL)
+		i_stream_switch_ioloop(ctx->input);
+	if (ctx->output != NULL)
+		o_stream_switch_ioloop(ctx->output);
+}
+
 static void remote_error_input(struct dsync_cmd_context *ctx)
 {
 	const unsigned char *data;
@@ -799,7 +807,7 @@
 {
 	struct doveadm_server *server;
 	struct server_connection *conn;
-	struct ioloop *ioloop;
+	struct ioloop *prev_ioloop, *ioloop;
 	string_t *cmd;
 	const char *error;
 
@@ -816,7 +824,9 @@
 	p_array_init(&server->connections, ctx->ctx.pool, 1);
 	p_array_init(&server->queue, ctx->ctx.pool, 1);
 
+	prev_ioloop = current_ioloop;
 	ioloop = io_loop_create();
+	dsync_cmd_switch_ioloop(ctx);
 
 	if (doveadm_verbose_proctitle) {
 		process_title_set(t_strdup_printf(
@@ -852,6 +862,10 @@
 
 	if (array_count(&server->connections) > 0)
 		server_connection_destroy(&conn);
+
+	io_loop_set_current(prev_ioloop);
+	dsync_cmd_switch_ioloop(ctx);
+	io_loop_set_current(ioloop);
 	io_loop_destroy(&ioloop);
 
 	if (ctx->error != NULL) {