Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/phpredis/phpredis.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormichael-grunder <michael.grunder@gmail.com>2022-09-23 20:41:55 +0300
committerMichael Grunder <michael.grunder@gmail.com>2022-09-27 21:35:40 +0300
commita98605f216449479cf27599244c25cbf415ed226 (patch)
treede325fcf6bc5972c3ca4dbab2749a80999806907
parentb7bf22d4c95ebb275702b9c93ae46c45f21faae2 (diff)
BLPOP with a float timeout
See #2157
-rw-r--r--redis.stub.php4
-rw-r--r--redis_arginfo.h12
-rw-r--r--redis_commands.c34
-rw-r--r--redis_legacy_arginfo.h2
-rw-r--r--tests/RedisTest.php22
5 files changed, 46 insertions, 28 deletions
diff --git a/redis.stub.php b/redis.stub.php
index 57e48d01..3a754901 100644
--- a/redis.stub.php
+++ b/redis.stub.php
@@ -52,9 +52,9 @@ class Redis {
/** @return int|Redis */
public function bitpos(string $key, int $bit, int $start = 0, int $end = -1);
- public function blPop(string|array $key, string|int $timeout_or_key, mixed ...$extra_args): array;
+ public function blPop(string|array $key, string|double|int $timeout_or_key, mixed ...$extra_args): array;
- public function brPop(string|array $key, string|int $timeout_or_key, mixed ...$extra_args): array;
+ public function brPop(string|array $key, string|double|int $timeout_or_key, mixed ...$extra_args): array;
public function brpoplpush(string $src, string $dst, int $timeout): string;
diff --git a/redis_arginfo.h b/redis_arginfo.h
index ea5ee288..e05c4b9f 100644
--- a/redis_arginfo.h
+++ b/redis_arginfo.h
@@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
- * Stub hash: 2b1fc18e5c464c551df8572363972769b2ec1096 */
+ * Stub hash: 28b297e0067c033cea6e2c42fb1f42d4585234ac */
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis___construct, 0, 0, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_ARRAY, 0, "null")
@@ -72,7 +72,7 @@ ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Redis_blPop, 0, 2, IS_ARRAY, 0)
ZEND_ARG_TYPE_MASK(0, key, MAY_BE_STRING|MAY_BE_ARRAY, NULL)
- ZEND_ARG_TYPE_MASK(0, timeout_or_key, MAY_BE_STRING|MAY_BE_LONG, NULL)
+ ZEND_ARG_OBJ_TYPE_MASK(0, timeout_or_key, double, MAY_BE_STRING|MAY_BE_LONG, NULL)
ZEND_ARG_VARIADIC_TYPE_INFO(0, extra_args, IS_MIXED, 0)
ZEND_END_ARG_INFO()
@@ -84,9 +84,13 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Redis_brpoplpush, 0, 3, IS
ZEND_ARG_TYPE_INFO(0, timeout, IS_LONG, 0)
ZEND_END_ARG_INFO()
-#define arginfo_class_Redis_bzPopMax arginfo_class_Redis_blPop
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Redis_bzPopMax, 0, 2, IS_ARRAY, 0)
+ ZEND_ARG_TYPE_MASK(0, key, MAY_BE_STRING|MAY_BE_ARRAY, NULL)
+ ZEND_ARG_TYPE_MASK(0, timeout_or_key, MAY_BE_STRING|MAY_BE_LONG, NULL)
+ ZEND_ARG_VARIADIC_TYPE_INFO(0, extra_args, IS_MIXED, 0)
+ZEND_END_ARG_INFO()
-#define arginfo_class_Redis_bzPopMin arginfo_class_Redis_blPop
+#define arginfo_class_Redis_bzPopMin arginfo_class_Redis_bzPopMax
#define arginfo_class_Redis_clearLastError arginfo_class_Redis_bgSave
diff --git a/redis_commands.c b/redis_commands.c
index 39c7941d..35152b7c 100644
--- a/redis_commands.c
+++ b/redis_commands.c
@@ -1461,14 +1461,13 @@ static int gen_varkey_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
char *kw, int kw_len, int min_argc, int has_timeout,
char **cmd, int *cmd_len, short *slot)
{
- zval *z_args, *z_ele;
+ zval *z_args, *z_ele, ztimeout = {0};
HashTable *ht_arr;
char *key;
int key_free, i, tail;
size_t key_len;
int single_array = 0, argc = ZEND_NUM_ARGS();
smart_string cmdstr = {0};
- long timeout = 0;
short kslot = -1;
zend_string *zstr;
@@ -1489,8 +1488,9 @@ static int gen_varkey_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
single_array = argc==1 && Z_TYPE(z_args[0]) == IS_ARRAY;
} else {
single_array = argc==2 && Z_TYPE(z_args[0]) == IS_ARRAY &&
- Z_TYPE(z_args[1]) == IS_LONG;
- timeout = Z_LVAL(z_args[1]);
+ (Z_TYPE(z_args[1]) == IS_LONG || Z_TYPE(z_args[1]) == IS_DOUBLE);
+ if (single_array)
+ ZVAL_COPY_VALUE(&ztimeout, &z_args[1]);
}
// If we're running a single array, rework args
@@ -1533,17 +1533,22 @@ static int gen_varkey_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
zend_string_release(zstr);
if (key_free) efree(key);
} ZEND_HASH_FOREACH_END();
- if (has_timeout) {
- redis_cmd_append_sstr_long(&cmdstr, timeout);
+ if (Z_TYPE(ztimeout) == IS_LONG) {
+ redis_cmd_append_sstr_long(&cmdstr, Z_LVAL(ztimeout));
+ } else if (Z_TYPE(ztimeout) == IS_DOUBLE) {
+ redis_cmd_append_sstr_dbl(&cmdstr, Z_DVAL(ztimeout));
}
} else {
- if (has_timeout && Z_TYPE(z_args[argc-1])!=IS_LONG) {
- php_error_docref(NULL, E_ERROR,
- "Timeout value must be a LONG");
- efree(z_args);
- return FAILURE;
+ if (has_timeout) {
+ zend_uchar type = Z_TYPE(z_args[argc - 1]);
+ if (type == IS_LONG || type == IS_DOUBLE) {
+ ZVAL_COPY_VALUE(&ztimeout, &z_args[argc - 1]);
+ } else {
+ php_error_docref(NULL, E_ERROR, "Timeout value must be a long or double");
+ efree(z_args);
+ return FAILURE;
+ }
}
-
tail = has_timeout ? argc-1 : argc;
for(i = 0; i < tail; i++) {
zstr = zval_get_string(&z_args[i]);
@@ -1571,7 +1576,10 @@ static int gen_varkey_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
zend_string_release(zstr);
if (key_free) efree(key);
}
- if (has_timeout) {
+
+ if (Z_TYPE(ztimeout) == IS_DOUBLE) {
+ redis_cmd_append_sstr_dbl(&cmdstr, Z_DVAL(z_args[tail]));
+ } else if (Z_TYPE(ztimeout) == IS_LONG) {
redis_cmd_append_sstr_long(&cmdstr, Z_LVAL(z_args[tail]));
}
diff --git a/redis_legacy_arginfo.h b/redis_legacy_arginfo.h
index cacf75f3..b26cd9e6 100644
--- a/redis_legacy_arginfo.h
+++ b/redis_legacy_arginfo.h
@@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
- * Stub hash: 2b1fc18e5c464c551df8572363972769b2ec1096 */
+ * Stub hash: 28b297e0067c033cea6e2c42fb1f42d4585234ac */
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis___construct, 0, 0, 0)
ZEND_ARG_INFO(0, options)
diff --git a/tests/RedisTest.php b/tests/RedisTest.php
index 49383d47..6ef56490 100644
--- a/tests/RedisTest.php
+++ b/tests/RedisTest.php
@@ -963,18 +963,24 @@ class Redis_Test extends TestSuite
}
public function testblockingPop() {
+ /* Test with a double timeout in Redis >= 6.0.0 */
+ if (version_compare($this->version, "6.0.0") >= 0) {
+ $this->redis->del('list');
+ $this->redis->lpush('list', 'val1', 'val2');
+ $this->assertEquals(['list', 'val2'], $this->redis->blpop(['list'], .1));
+ $this->assertEquals(['list', 'val1'], $this->redis->blpop(['list'], .1));
+ }
+
// non blocking blPop, brPop
$this->redis->del('list');
- $this->redis->lPush('list', 'val1');
- $this->redis->lPush('list', 'val2');
- $this->assertTrue($this->redis->blPop(['list'], 2) === ['list', 'val2']);
- $this->assertTrue($this->redis->blPop(['list'], 2) === ['list', 'val1']);
+ $this->redis->lPush('list', 'val1', 'val2');
+ $this->assertEquals(['list', 'val2'], $this->redis->blPop(['list'], 2));
+ $this->assertEquals(['list', 'val1'], $this->redis->blPop(['list'], 2));
$this->redis->del('list');
- $this->redis->lPush('list', 'val1');
- $this->redis->lPush('list', 'val2');
- $this->assertTrue($this->redis->brPop(['list'], 1) === ['list', 'val1']);
- $this->assertTrue($this->redis->brPop(['list'], 1) === ['list', 'val2']);
+ $this->redis->lPush('list', 'val1', 'val2');
+ $this->assertEquals(['list', 'val1'], $this->redis->brPop(['list'], 1));
+ $this->assertEquals(['list', 'val2'], $this->redis->brPop(['list'], 1));
// blocking blpop, brpop
$this->redis->del('list');