diff options
author | Gabi Ganam <gabiganam@gmail.com> | 2023-01-08 11:02:48 +0200 |
---|---|---|
committer | Oran Agra <oran@redislabs.com> | 2023-01-16 18:40:35 +0200 |
commit | 574a49b96c02f6833bef3b15501aafda1e0fb031 (patch) | |
tree | 1dd2ca191cb7371477fda86ad263c0bf49796cf5 | |
parent | 61a1d4540de18b82f800bdfdc138057f7145451f (diff) | |
download | redis-574a49b96c02f6833bef3b15501aafda1e0fb031.tar.gz |
Blocking command with a 0.001 seconds timeout blocks indefinitely (#11688)
Any value in the range of [0-1) turns to 0 when being cast from double to long long. This change rounds up instead of down for values that can't be stored precisely as long doubles.
(cherry picked from commit eef29b68a2cd94de1f03aa1b7891af75f5cabae2)
-rw-r--r-- | src/timeout.c | 4 | ||||
-rw-r--r-- | tests/unit/type/list.tcl | 10 |
2 files changed, 13 insertions, 1 deletions
diff --git a/src/timeout.c b/src/timeout.c index 36cea7c26..90d0fe796 100644 --- a/src/timeout.c +++ b/src/timeout.c @@ -29,6 +29,8 @@ #include "server.h" #include "cluster.h" +#include <math.h> + /* ========================== Clients timeouts ============================= */ /* Check if this blocked client timedout (does nothing if the client is @@ -169,7 +171,7 @@ int getTimeoutFromObjectOrReply(client *c, robj *object, mstime_t *timeout, int if (getLongDoubleFromObjectOrReply(c,object,&ftval, "timeout is not a float or out of range") != C_OK) return C_ERR; - tval = (long long) (ftval * 1000.0); + tval = (long long) ceill(ftval * 1000.0); } else { if (getLongLongFromObjectOrReply(c,object,&tval, "timeout is not an integer or out of range") != C_OK) diff --git a/tests/unit/type/list.tcl b/tests/unit/type/list.tcl index 3133923d6..0c52dd8f5 100644 --- a/tests/unit/type/list.tcl +++ b/tests/unit/type/list.tcl @@ -1256,6 +1256,16 @@ foreach {pop} {BLPOP BLMPOP_LEFT} { $rd close } + test "$pop: with 0.001 timeout should not block indefinitely" { + # Use a timeout of 0.001 and wait for the number of blocked clients to equal 0. + # Validate the empty read from the deferring client. + set rd [redis_deferring_client] + bpop_command $rd $pop blist1 0.001 + wait_for_blocked_clients_count 0 + assert_equal {} [$rd read] + $rd close + } + test "$pop: second argument is not a list" { set rd [redis_deferring_client] r del blist1{t} blist2{t} |