From eef29b68a2cd94de1f03aa1b7891af75f5cabae2 Mon Sep 17 00:00:00 2001 From: Gabi Ganam Date: Sun, 8 Jan 2023 11:02:48 +0200 Subject: [PATCH] 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. --- src/timeout.c | 4 +++- tests/unit/type/list.tcl | 10 ++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/timeout.c b/src/timeout.c index b62423a9e..eb971dcdc 100644 --- a/src/timeout.c +++ b/src/timeout.c @@ -29,6 +29,8 @@ #include "server.h" #include "cluster.h" +#include + /* ========================== Clients timeouts ============================= */ /* Check if this blocked client timedout (does nothing if the client is @@ -175,7 +177,7 @@ int getTimeoutFromObjectOrReply(client *c, robj *object, mstime_t *timeout, int addReplyError(c, "timeout is out of range"); return C_ERR; } - tval = (long long) ftval; + tval = (long long) ceill(ftval); } 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 f7e043f99..7a3768025 100644 --- a/tests/unit/type/list.tcl +++ b/tests/unit/type/list.tcl @@ -1263,6 +1263,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}