Mercurial > dovecot > core-2.2
changeset 22996:fd4e4582ff6c
lib-master: ipc-client: Support aborting commands
author | Timo Sirainen <timo.sirainen@dovecot.fi> |
---|---|
date | Thu, 05 Jul 2018 14:42:30 +0300 |
parents | 80ba6e7551ee |
children | 0a2614a38fc6 |
files | src/lib-master/ipc-client.c src/lib-master/ipc-client.h |
diffstat | 2 files changed, 44 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-master/ipc-client.c Thu Jul 05 14:41:38 2018 +0300 +++ b/src/lib-master/ipc-client.c Thu Jul 05 14:42:30 2018 +0300 @@ -29,6 +29,7 @@ struct istream *input; struct ostream *output; struct ipc_client_cmd *cmds_head, *cmds_tail; + unsigned int aborted_cmds_count; }; static void ipc_client_disconnect(struct ipc_client *client); @@ -39,7 +40,10 @@ enum ipc_client_cmd_state state; bool disconnect = FALSE; - if (cmd == NULL) { + if (client->aborted_cmds_count > 0) { + /* the command was already aborted */ + cmd = NULL; + } else if (cmd == NULL) { i_error("IPC proxy sent unexpected input: %s", line); return; } @@ -62,10 +66,17 @@ break; } - if (state != IPC_CLIENT_CMD_STATE_REPLY) - DLLIST2_REMOVE(&client->cmds_head, &client->cmds_tail, cmd); - cmd->callback(state, line, cmd->context); - i_free(cmd); + if (state != IPC_CLIENT_CMD_STATE_REPLY) { + if (cmd != NULL) + DLLIST2_REMOVE(&client->cmds_head, + &client->cmds_tail, cmd); + else + client->aborted_cmds_count--; + } + if (cmd != NULL) { + cmd->callback(state, line, cmd->context); + i_free(cmd); + } if (disconnect) ipc_client_disconnect(client); } @@ -159,8 +170,9 @@ 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_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]; @@ -185,4 +197,24 @@ iov[1].iov_len = 1; o_stream_nsendv(client->output, iov, N_ELEMENTS(iov)); } + return ipc_cmd; } + +void ipc_client_cmd_abort(struct ipc_client *client, + struct ipc_client_cmd **_cmd) +{ + struct ipc_client_cmd *cmd = *_cmd; + + *_cmd = NULL; + cmd->callback = NULL; + /* Free the command only if it's the oldest. Free also other such + commands in case they were aborted earlier. */ + while (client->cmds_head != NULL && + client->cmds_head->callback == NULL) { + struct ipc_client_cmd *head = client->cmds_head; + + client->aborted_cmds_count++; + DLLIST2_REMOVE(&client->cmds_head, &client->cmds_tail, head); + i_free(head); + } +}
--- a/src/lib-master/ipc-client.h Thu Jul 05 14:41:38 2018 +0300 +++ b/src/lib-master/ipc-client.h Thu Jul 05 14:42:30 2018 +0300 @@ -14,8 +14,11 @@ ipc_client_init(const char *ipc_socket_path); void ipc_client_deinit(struct ipc_client **client); -void ipc_client_cmd(struct ipc_client *client, const char *cmd, - ipc_client_callback_t *callback, void *context) +struct ipc_client_cmd * +ipc_client_cmd(struct ipc_client *client, const char *cmd, + ipc_client_callback_t *callback, void *context) ATTR_NULL(4); +void ipc_client_cmd_abort(struct ipc_client *client, + struct ipc_client_cmd **cmd); #endif