diff options
author | 郭伟光 <warriorguo@gmail.com> | 2022-03-20 21:18:53 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-03-20 15:18:53 +0200 |
commit | fae5b1a19d0972c2f4274004f15be3d2f90c856c (patch) | |
tree | 8685562c618f29df9d6bd1918d6f7706fdc92ea6 /src/blocked.c | |
parent | b9656adbd9c6a670e5c89b19c7721057c7d89c24 (diff) | |
download | redis-fae5b1a19d0972c2f4274004f15be3d2f90c856c.tar.gz |
unblockClient: avoid to reset client when the client was shutdown-blocked (#10440)
fix #10439. see https://github.com/redis/redis/pull/9872
When executing SHUTDOWN we pause the client so we can un-pause it
if the shutdown fails.
this could happen during the timeout, if the shutdown is aborted, but could
also happen from withing the initial `call()` to shutdown, if the rdb save fails.
in that case when we return to `call()`, we'll crash if `c->cmd` has been set to NULL.
The call stack is:
```
unblockClient(c)
replyToClientsBlockedOnShutdown()
cancelShutdown()
finishShutdown()
prepareForShutdown()
shutdownCommand()
```
what's special about SHUTDOWN in that respect is that it can be paused,
and then un-paused before the original `call()` returns.
tests where added for both failed shutdown, and a followup successful one.
Diffstat (limited to 'src/blocked.c')
-rw-r--r-- | src/blocked.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/src/blocked.c b/src/blocked.c index a982884c4..2754da9e0 100644 --- a/src/blocked.c +++ b/src/blocked.c @@ -204,7 +204,7 @@ void unblockClient(client *c) { * we do not do it immediately after the command returns (when the * client got blocked) in order to be still able to access the argument * vector from module callbacks and updateStatsOnUnblock. */ - if (c->btype != BLOCKED_POSTPONE) { + if (c->btype != BLOCKED_POSTPONE && c->btype != BLOCKED_SHUTDOWN) { freeClientOriginalArgv(c); resetClient(c); } |