]> git.saurik.com Git - redis.git/commitdiff
Merge branch 'smallkeys' of github.com:antirez/redis into smallkeys
authorantirez <antirez@gmail.com>
Tue, 1 Jun 2010 12:18:38 +0000 (14:18 +0200)
committerantirez <antirez@gmail.com>
Tue, 1 Jun 2010 12:18:38 +0000 (14:18 +0200)
1  2 
redis.c

diff --combined redis.c
index f5a437837f93587b17abf554b17f272bee08a67e,2d4dddfb7317c04bf1ed1b37b67a632fbaaa2a69..b5e10d4666e9cb34123d1237df94633aabd16086
+++ b/redis.c
@@@ -90,7 -90,7 +90,7 @@@
  #define REDIS_STATIC_ARGS       8
  #define REDIS_DEFAULT_DBNUM     16
  #define REDIS_CONFIGLINE_MAX    1024
- #define REDIS_OBJFREELIST_MAX   1000000 /* Max number of objects to cache */
+ #define REDIS_OBJFREELIST_MAX   0 /* Max number of objects to cache */
  #define REDIS_MAX_SYNC_TIME     60      /* Slave can't take more to sync */
  #define REDIS_EXPIRELOOKUPS_PER_CRON    10 /* lookup 10 expires per loop */
  #define REDIS_MAX_WRITE_PER_EVENT (1024*64)
@@@ -3099,10 -3099,18 +3099,18 @@@ static void decrRefCount(void *obj) 
      }
  
      if (o->refcount <= 0) redisPanic("decrRefCount against refcount <= 0");
-     /* Object is in memory, or in the process of being swapped out. */
+     /* Object is in memory, or in the process of being swapped out.
+      *
+      * If the object is being swapped out, abort the operation on
+      * decrRefCount even if the refcount does not drop to 0: the object
+      * is referenced at least two times, as value of the key AND as
+      * job->val in the iojob. So if we don't invalidate the iojob, when it is
+      * done but the relevant key was removed in the meantime, the
+      * complete jobs handler will not find the key about the job and the
+      * assert will fail. */
+     if (server.vm_enabled && o->storage == REDIS_VM_SWAPPING)
+         vmCancelThreadedIOJob(o);
      if (--(o->refcount) == 0) {
-         if (server.vm_enabled && o->storage == REDIS_VM_SWAPPING)
-             vmCancelThreadedIOJob(obj);
          switch(o->type) {
          case REDIS_STRING: freeStringObject(o); break;
          case REDIS_LIST: freeListObject(o); break;
@@@ -9120,12 -9128,10 +9128,12 @@@ static int vmWriteObjectOnSwap(robj *o
      return REDIS_OK;
  }
  
 -/* Swap the 'val' object relative to 'key' into disk. Store all the information
 - * needed to later retrieve the object into the key object.
 +/* Transfers the 'val' object to disk. Store all the information
 + * a 'vmpointer' object containing all the information needed to load the
 + * object back later is returned.
 + *
   * If we can't find enough contiguous empty pages to swap the object on disk
 - * REDIS_ERR is returned. */
 + * NULL is returned. */
  static vmpointer *vmSwapObjectBlocking(robj *val) {
      off_t pages = rdbSavedObjectPages(val,NULL);
      off_t page;
@@@ -9411,11 -9417,9 +9419,9 @@@ static void freeIOJob(iojob *j) 
          j->type == REDIS_IOJOB_DO_SWAP ||
          j->type == REDIS_IOJOB_LOAD) && j->val != NULL)
      {
-         /* Our value object was successfully swapped if
-          * refcount == 1 and storage == REDIS_VM_SWAPPING,
-          * we fix the storage type, otherwise decrRefCount() will try to
-          * kill the I/O thread Job (that does no longer exists). */
-         if (j->val->refcount == 1 && j->val->storage == REDIS_VM_SWAPPING)
+          /* we fix the storage type, otherwise decrRefCount() will try to
+           * kill the I/O thread Job (that does no longer exists). */
+         if (j->val->storage == REDIS_VM_SWAPPING)
              j->val->storage = REDIS_VM_MEMORY;
          decrRefCount(j->val);
      }
@@@ -9464,7 -9468,7 +9470,7 @@@ static void vmThreadedIOCompletedJob(ae
           * can do just here to avoid race conditions and/or invasive locks */
          redisLog(REDIS_DEBUG,"COMPLETED Job type: %d, ID %p, key: %s", j->type, (void*)j->id, (unsigned char*)j->key->ptr);
          de = dictFind(j->db->dict,j->key);
-         assert(de != NULL);
+         redisAssert(de != NULL);
          if (j->type == REDIS_IOJOB_LOAD) {
              redisDb *db;
              vmpointer *vp = dictGetEntryVal(de);
              vp->page = j->page;
              vp->usedpages = j->pages;
              dictGetEntryVal(de) = vp;
+             /* Fix the storage otherwise decrRefCount will attempt to
+              * remove the associated I/O job */
+             j->val->storage = REDIS_VM_MEMORY;
              decrRefCount(j->val);
              redisLog(REDIS_DEBUG,
                  "VM: object %s swapped out at %lld (%lld pages) (threaded)",
@@@ -9638,6 -9645,7 +9647,7 @@@ again
                  else if (o->storage == REDIS_VM_SWAPPING)
                      o->storage = REDIS_VM_MEMORY;
                  unlockThreadedIO();
+                 redisLog(REDIS_DEBUG,"*** DONE");
                  return;
              }
          }