From 0e2589521c6a8d658e14884aeb7656946b94c6b2 Mon Sep 17 00:00:00 2001 From: "zhaozhao.zz" Date: Wed, 28 Aug 2024 20:46:39 +0800 Subject: [PATCH] free client's multi state when it becomes dirty Signed-off-by: zhaozhao.zz --- src/multi.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/multi.c b/src/multi.c index 14688f80b43..5ff94d190a9 100644 --- a/src/multi.c +++ b/src/multi.c @@ -106,6 +106,10 @@ void discardTransaction(client *c) { * Should be called every time there is an error while queueing a command. */ void flagTransaction(client *c) { if (c->flag.multi) c->flag.dirty_exec = 1; + if (c->mstate.commands) { + freeClientMultiState(c); + initClientMultiState(c); + } } void multiCommand(client *c) { @@ -391,6 +395,10 @@ void touchWatchedKey(serverDb *db, robj *key) { } c->flag.dirty_cas = 1; + if (c->mstate.commands) { + freeClientMultiState(c); + initClientMultiState(c); + } /* As the client is marked as dirty, there is no point in getting here * again in case that key (or others) are modified again (or keep the * memory overhead till EXEC). */ @@ -442,6 +450,10 @@ void touchAllWatchedKeysInDb(serverDb *emptied, serverDb *replaced_with) { } client *c = wk->client; c->flag.dirty_cas = 1; + if (c->mstate.commands) { + freeClientMultiState(c); + initClientMultiState(c); + } /* Note - we could potentially call unwatchAllKeys for this specific client in order to reduce * the total number of iterations. BUT this could also free the current next entry pointer * held by the iterator and can lead to use-after-free. */