changeset 22994:ed789b38da96

lib-master: ipc-client: Never call callback directly from ipc_client_cmd() This may simplify the calling code, especially after the following commit that returns the command pointer.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Thu, 05 Jul 2018 14:38:51 +0300
parents 962bbc45c99c
children 80ba6e7551ee
files src/lib-master/ipc-client.c
diffstat 1 files changed, 23 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-master/ipc-client.c	Thu Jul 05 14:35:51 2018 +0300
+++ b/src/lib-master/ipc-client.c	Thu Jul 05 14:38:51 2018 +0300
@@ -25,7 +25,7 @@
 
 	int fd;
 	struct io *io;
-	struct timeout *to;
+	struct timeout *to_failed;
 	struct istream *input;
 	struct ostream *output;
 	struct ipc_client_cmd *cmds_head, *cmds_tail;
@@ -117,11 +117,12 @@
 
 static void ipc_client_disconnect(struct ipc_client *client)
 {
+	timeout_remove(&client->to_failed);
+	ipc_client_abort_commands(client, "Disconnected");
+
 	if (client->fd == -1)
 		return;
 
-	ipc_client_abort_commands(client, "Disconnected");
-
 	io_remove(&client->io);
 	i_stream_destroy(&client->input);
 	o_stream_destroy(&client->output);
@@ -152,15 +153,31 @@
 	i_free(client);
 }
 
+static void ipc_client_cmd_connect_failed(struct ipc_client *client)
+{
+	ipc_client_abort_commands(client, "ipc connect failed");
+	timeout_remove(&client->to_failed);
+}
+
 void ipc_client_cmd(struct ipc_client *client, const char *cmd,
 		    ipc_client_callback_t *callback, void *context)
 {
 	struct ipc_client_cmd *ipc_cmd;
 	struct const_iovec iov[2];
 
-	if (ipc_client_connect(client) < 0) {
-		callback(IPC_CLIENT_CMD_STATE_ERROR,
-			 "ipc connect failed", context);
+	ipc_cmd = i_new(struct ipc_client_cmd, 1);
+	ipc_cmd->callback = callback;
+	ipc_cmd->context = context;
+	DLLIST2_APPEND(&client->cmds_head, &client->cmds_tail, ipc_cmd);
+
+	if (client->to_failed != NULL ||
+	    ipc_client_connect(client) < 0) {
+		/* Delay calling the failure callback. Fail all commands until
+		   the callback is called. */
+		if (client->to_failed == NULL) {
+			client->to_failed = timeout_add_short(0,
+				ipc_client_cmd_connect_failed, client);
+		}
 		return;
 	}
 
@@ -169,9 +186,4 @@
 	iov[1].iov_base = "\n";
 	iov[1].iov_len = 1;
 	o_stream_nsendv(client->output, iov, N_ELEMENTS(iov));
-
-	ipc_cmd = i_new(struct ipc_client_cmd, 1);
-	ipc_cmd->callback = callback;
-	ipc_cmd->context = context;
-	DLLIST2_APPEND(&client->cmds_head, &client->cmds_tail, ipc_cmd);
 }