aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorEgor Tensin <Egor.Tensin@gmail.com>2023-06-12 01:23:24 +0200
committerEgor Tensin <Egor.Tensin@gmail.com>2023-06-12 01:23:26 +0200
commit8d719f8e923f469a5395d58559177b35d54df24d (patch)
treef7ca520d1501aff0f4a8e237840230a6707d2901
parentsqlite: fix generate-sql-header.py (diff)
downloadcimple-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.
-rw-r--r--src/command.c18
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;