]> 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)
1  2 
src/t_list.c
tests/unit/type/list.tcl

diff --combined src/t_list.c
index 6b4a611e47e257ad4a8b09f90610f96533a995a8,43d292b6d6642ff7b40a40ac33f2c7191235716b..add1bee167691b1fcc382c1292c728832f6c65bd
@@@ -782,9 -782,20 +782,20 @@@ int handleClientsWaitingListPush(redisC
  /* 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) {
              }
          }
      }
 +    /* 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) {
 +        addReply(c,shared.nullmultibulk);
 +        return;
 +    }
 +
      /* 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);
  }
diff --combined tests/unit/type/list.tcl
index ca0da764470f73957a2202f04bdfb0853497dc0b,1a85c809c7ae3e5e2ac6b3126d8ad4468a194cff..bf188fd709534d366df7d5c79949247a512aca14
@@@ -139,6 -139,28 +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
          }
      }
  
 +    test {BLPOP inside a transaction} {
 +        r del xlist
 +        r lpush xlist foo
 +        r lpush xlist bar
 +        r multi
 +        r blpop xlist 0
 +        r blpop xlist 0
 +        r blpop xlist 0
 +        r exec
 +    } {{xlist bar} {xlist foo} {}}
 +
      test {LPUSHX, RPUSHX - generic} {
          r del xlist
          assert_equal 0 [r lpushx xlist a]