diff options
author | Egor Tensin <Egor.Tensin@gmail.com> | 2023-06-12 01:23:24 +0200 |
---|---|---|
committer | Egor Tensin <Egor.Tensin@gmail.com> | 2023-06-12 01:23:26 +0200 |
commit | 8d719f8e923f469a5395d58559177b35d54df24d (patch) | |
tree | f7ca520d1501aff0f4a8e237840230a6707d2901 /src | |
parent | sqlite: fix generate-sql-header.py (diff) | |
download | cimple-8d719f8e923f469a5395d58559177b35d54df24d.tar.gz cimple-8d719f8e923f469a5395d58559177b35d54df24d.zip |
command: fix a race condition
Modifying cmd_dispatcher fields like that make it inherently unsafe to
call cmd_dispatcher_handle_conn concurrently.
Diffstat (limited to 'src')
-rw-r--r-- | src/command.c | 18 |
1 files changed, 10 insertions, 8 deletions
diff --git a/src/command.c b/src/command.c index 55d60da..bd58f05 100644 --- a/src/command.c +++ b/src/command.c @@ -103,8 +103,8 @@ void cmd_dispatcher_destroy(struct cmd_dispatcher *dispatcher) free(dispatcher); } -int cmd_dispatcher_handle(const struct cmd_dispatcher *dispatcher, const struct msg *command, - struct msg **result) +static int cmd_dispatcher_handle_internal(const struct cmd_dispatcher *dispatcher, + const struct msg *command, struct msg **result, void *arg) { const char *actual_cmd = msg_get_first_string(command); @@ -114,7 +114,7 @@ int cmd_dispatcher_handle(const struct cmd_dispatcher *dispatcher, const struct if (strcmp(cmd->name, actual_cmd)) continue; - return cmd->handler(command, result, dispatcher->ctx); + return cmd->handler(command, result, arg); } log_err("Received an unknown command\n"); @@ -122,6 +122,12 @@ int cmd_dispatcher_handle(const struct cmd_dispatcher *dispatcher, const struct return -1; } +int cmd_dispatcher_handle(const struct cmd_dispatcher *dispatcher, const struct msg *command, + struct msg **result) +{ + return cmd_dispatcher_handle_internal(dispatcher, command, result, dispatcher->ctx); +} + int cmd_dispatcher_handle_conn(int conn_fd, void *_dispatcher) { struct cmd_dispatcher *dispatcher = (struct cmd_dispatcher *)_dispatcher; @@ -141,11 +147,7 @@ int cmd_dispatcher_handle_conn(int conn_fd, void *_dispatcher) if (ret < 0) goto free_ctx; - void *old_ctx = dispatcher->ctx; - dispatcher->ctx = new_ctx; - ret = cmd_dispatcher_handle(dispatcher, request, &response); - dispatcher->ctx = old_ctx; - + ret = cmd_dispatcher_handle_internal(dispatcher, request, &response, new_ctx); if (ret < 0) goto free_response; |