]> git.saurik.com Git - redis.git/commitdiff
resolved conflict merging pietern/bpop-timeout
authorantirez <antirez@gmail.com>
Tue, 31 Aug 2010 09:23:12 +0000 (11:23 +0200)
committerantirez <antirez@gmail.com>
Tue, 31 Aug 2010 09:23:12 +0000 (11:23 +0200)
src/t_list.c
tests/unit/type/list.tcl

index 6b4a611e47e257ad4a8b09f90610f96533a995a8..add1bee167691b1fcc382c1292c728832f6c65bd 100644 (file)
@@ -782,9 +782,20 @@ int handleClientsWaitingListPush(redisClient *c, robj *key, robj *ele) {
 /* Blocking RPOP/LPOP */
 void blockingPopGenericCommand(redisClient *c, int where) {
     robj *o;
+    long long lltimeout;
     time_t timeout;
     int j;
 
+    /* Make sure timeout is an integer value */
+    if (getLongLongFromObjectOrReply(c,c->argv[c->argc-1],&lltimeout,
+            "timeout is not an integer") != REDIS_OK) return;
+
+    /* Make sure the timeout is not negative */
+    if (lltimeout < 0) {
+        addReplySds(c,sdsnew("-ERR timeout is negative\r\n"));
+        return;
+    }
+
     for (j = 1; j < c->argc-1; j++) {
         o = lookupKeyWrite(c->db,c->argv[j]);
         if (o != NULL) {
@@ -823,6 +834,7 @@ void blockingPopGenericCommand(redisClient *c, int where) {
             }
         }
     }
+
     /* If we are inside a MULTI/EXEC and the list is empty the only thing
      * we can do is treating it as a timeout (even with timeout 0). */
     if (c->flags & REDIS_MULTI) {
@@ -831,7 +843,7 @@ void blockingPopGenericCommand(redisClient *c, int where) {
     }
 
     /* If the list is empty or the key does not exists we must block */
-    timeout = strtol(c->argv[c->argc-1]->ptr,NULL,10);
+    timeout = lltimeout;
     if (timeout > 0) timeout += time(NULL);
     blockForKeys(c,c->argv+1,c->argc-2,timeout);
 }
index ca0da764470f73957a2202f04bdfb0853497dc0b..bf188fd709534d366df7d5c79949247a512aca14 100644 (file)
@@ -139,6 +139,28 @@ start_server {
             assert_equal 0 [r exists blist1]
         }
 
+        test "$pop: with negative timeout" {
+            set rd [redis_deferring_client]
+            $rd $pop blist1 -1
+            assert_error "ERR*is negative*" {$rd read}
+        }
+
+        test "$pop: with non-integer timeout" {
+            set rd [redis_deferring_client]
+            $rd $pop blist1 1.1
+            assert_error "ERR*not an integer*" {$rd read}
+        }
+
+        test "$pop: with zero timeout should block indefinitely" {
+            # To test this, use a timeout of 0 and wait a second.
+            # The blocking pop should still be waiting for a push.
+            set rd [redis_deferring_client]
+            $rd $pop blist1 0
+            after 1000
+            r rpush blist1 foo
+            assert_equal {blist1 foo} [$rd read]
+        }
+
         test "$pop: second argument is not a list" {
             set rd [redis_deferring_client]
             r del blist1 blist2