Removed memory leak by releasing the items when I'm done using them
authorTrond Norbye <trond.norbye@sun.com>
Fri, 25 Sep 2009 10:41:02 +0000 (12:41 +0200)
committerTrond Norbye <trond.norbye@sun.com>
Fri, 25 Sep 2009 10:41:02 +0000 (12:41 +0200)
example/interface_v0.c
example/interface_v1.c
example/storage.c
example/storage_innodb.c

index 71c827c906da6cf5dc75f1b183dc75bcb1e77eaa..1fb5a0a998d04acc946fe89602db65ed59657eab 100644 (file)
@@ -92,6 +92,7 @@ static protocol_binary_response_status get_command_handler(const void *cookie,
     msg.response.message.header.response.bodylen= htonl(bodysize);
     msg.response.message.header.response.extlen= 4;
 
+    release_item(item);
     return response_handler(cookie, header, (void*)&msg);
   }
   else if (opcode == PROTOCOL_BINARY_CMD_GET || opcode == PROTOCOL_BINARY_CMD_GETK)
@@ -175,55 +176,47 @@ static protocol_binary_response_status arithmetic_command_handler(const void *co
   uint64_t initial= ntohll(req->message.body.initial);
   uint64_t delta= ntohll(req->message.body.delta);
   uint32_t expiration= ntohl(req->message.body.expiration);
+  uint32_t flags= 0;
   void *key= req->bytes + sizeof(req->bytes);
   protocol_binary_response_status rval= PROTOCOL_BINARY_RESPONSE_SUCCESS;
 
+  uint64_t value= initial;
+
   struct item *item= get_item(key, keylen);
-  if (item == NULL)
-  {
-    item= create_item(key, keylen, NULL, sizeof(initial), 0, (time_t)expiration);
-    if (item == NULL)
-    {
-      rval= PROTOCOL_BINARY_RESPONSE_ENOMEM;
-    }
-    else
-    {
-      memcpy(item->data, &initial, sizeof(initial));
-      put_item(item);
-    }
-  }
-  else
+  if (item != NULL)
   {
     if (header->request.opcode == PROTOCOL_BINARY_CMD_INCREMENT ||
         header->request.opcode == PROTOCOL_BINARY_CMD_INCREMENTQ)
     {
-      (*(uint64_t*)item->data) += delta;
+      value= (*(uint64_t*)item->data) + delta;
     }
     else
     {
       if (delta > *(uint64_t*)item->data)
       {
-        *(uint64_t*)item->data= 0;
+        value= 0;
       }
       else
       {
-        *(uint64_t*)item->data -= delta;
+        value= *(uint64_t*)item->data - delta;
       }
     }
+    expiration= (uint32_t)item->exp;
+    flags= item->flags;
 
-    struct item *nitem= create_item(key, keylen, NULL, sizeof(initial), 0, item->exp);
-    if (item == NULL)
-    {
-      rval= PROTOCOL_BINARY_RESPONSE_ENOMEM;
-      delete_item(key, keylen);
-    }
-    else
-    {
-      memcpy(nitem->data, item->data, item->size);
-      delete_item(key, keylen);
-      put_item(nitem);
-      item = nitem;
-    }
+    release_item(item);
+    delete_item(key, keylen);
+  }
+
+  item= create_item(key, keylen, NULL, sizeof(value), flags, (time_t)expiration);
+  if (item == NULL)
+  {
+    rval= PROTOCOL_BINARY_RESPONSE_ENOMEM;
+  }
+  else
+  {
+    memcpy(item->data, &value, sizeof(value));
+    put_item(item);
   }
 
   response.message.header.response.status= htons(rval);
@@ -233,6 +226,7 @@ static protocol_binary_response_status arithmetic_command_handler(const void *co
     response.message.body.value= ntohll((*(uint64_t*)item->data));
     response.message.header.response.cas= ntohll(item->cas);
 
+    release_item(item);
     if (header->request.opcode == PROTOCOL_BINARY_CMD_INCREMENTQ ||
         header->request.opcode == PROTOCOL_BINARY_CMD_DECREMENTQ)
     {
@@ -278,7 +272,8 @@ static protocol_binary_response_status concat_command_handler(const void *cookie
   void *val= (char*)key + keylen;
 
   struct item *item= get_item(key, keylen);
-  struct item *nitem;
+  struct item *nitem= NULL;
+
   if (item == NULL)
   {
     rval= PROTOCOL_BINARY_RESPONSE_KEY_ENOENT;
@@ -290,6 +285,7 @@ static protocol_binary_response_status concat_command_handler(const void *cookie
   else if ((nitem= create_item(key, keylen, NULL, item->size + vallen,
                                item->flags, item->exp)) == NULL)
   {
+    release_item(item);
     rval= PROTOCOL_BINARY_RESPONSE_ENOMEM;
   }
   else
@@ -305,8 +301,12 @@ static protocol_binary_response_status concat_command_handler(const void *cookie
       memcpy(nitem->data, val, vallen);
       memcpy(((char*)(nitem->data)) + vallen, item->data, item->size);
     }
+    release_item(item);
     delete_item(key, keylen);
     put_item(nitem);
+    cas= nitem->cas;
+    release_item(nitem);
+
     if (header->request.opcode == PROTOCOL_BINARY_CMD_APPEND ||
         header->request.opcode == PROTOCOL_BINARY_CMD_PREPEND)
     {
@@ -317,7 +317,7 @@ static protocol_binary_response_status concat_command_handler(const void *cookie
             .opcode= header->request.opcode,
             .status= htons(rval),
             .opaque= header->request.opaque,
-            .cas= htonll(nitem->cas),
+            .cas= htonll(cas),
           }
         }
       };
@@ -355,16 +355,21 @@ static protocol_binary_response_status set_command_handler(const void *cookie,
   {
     /* validate cas */
     struct item* item= get_item(key, keylen);
-    if (item != NULL && item->cas != ntohll(header->request.cas))
+    if (item != NULL)
     {
-      response.message.header.response.status= htons(PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS);
-      return response_handler(cookie, header, (void*)&response);
+      if (item->cas != ntohll(header->request.cas))
+      {
+        release_item(item);
+        response.message.header.response.status= htons(PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS);
+        return response_handler(cookie, header, (void*)&response);
+      }
+      release_item(item);
     }
   }
 
   delete_item(key, keylen);
   struct item* item= create_item(key, keylen, data, datalen, flags, timeout);
-  if (item == 0)
+  if (item == NULL)
   {
     response.message.header.response.status= htons(PROTOCOL_BINARY_RESPONSE_ENOMEM);
   }
@@ -375,8 +380,11 @@ static protocol_binary_response_status set_command_handler(const void *cookie,
     if (header->request.opcode == PROTOCOL_BINARY_CMD_SET)
     {
       response.message.header.response.cas= htonll(item->cas);
+      release_item(item);
       return response_handler(cookie, header, (void*)&response);
     }
+    release_item(item);
+
     return PROTOCOL_BINARY_RESPONSE_SUCCESS;
   }
 
@@ -410,7 +418,7 @@ static protocol_binary_response_status add_command_handler(const void *cookie,
   if (item == NULL)
   {
     item= create_item(key, keylen, data, datalen, flags, timeout);
-    if (item == 0)
+    if (item == NULL)
       response.message.header.response.status= htons(PROTOCOL_BINARY_RESPONSE_ENOMEM);
     else
     {
@@ -419,13 +427,16 @@ static protocol_binary_response_status add_command_handler(const void *cookie,
       if (header->request.opcode == PROTOCOL_BINARY_CMD_ADD)
       {
         response.message.header.response.cas= htonll(item->cas);
+        release_item(item);
         return response_handler(cookie, header, (void*)&response);
       }
+      release_item(item);
       return PROTOCOL_BINARY_RESPONSE_SUCCESS;
     }
   }
   else
   {
+    release_item(item);
     response.message.header.response.status= htons(PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS);
   }
 
@@ -460,9 +471,10 @@ static protocol_binary_response_status replace_command_handler(const void *cooki
     response.message.header.response.status= htons(PROTOCOL_BINARY_RESPONSE_KEY_ENOENT);
   else if (header->request.cas == 0 || ntohll(header->request.cas) == item->cas)
   {
+    release_item(item);
     delete_item(key, keylen);
     item= create_item(key, keylen, data, datalen, flags, timeout);
-    if (item == 0)
+    if (item == NULL)
       response.message.header.response.status= htons(PROTOCOL_BINARY_RESPONSE_ENOMEM);
     else
     {
@@ -471,13 +483,18 @@ static protocol_binary_response_status replace_command_handler(const void *cooki
       if (header->request.opcode == PROTOCOL_BINARY_CMD_REPLACE)
       {
         response.message.header.response.cas= htonll(item->cas);
+        release_item(item);
         return response_handler(cookie, header, (void*)&response);
       }
+      release_item(item);
       return PROTOCOL_BINARY_RESPONSE_SUCCESS;
     }
   }
   else
+  {
     response.message.header.response.status= htons(PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS);
+    release_item(item);
+  }
 
   return response_handler(cookie, header, (void*)&response);
 }
index a1a1a22aa558eb8820df16b90319919b7b137823..bab1cd974f9e303826b610ec0b8d3212307490ab 100644 (file)
@@ -47,6 +47,7 @@ static protocol_binary_response_status add_handler(const void *cookie,
     {
       put_item(item);
       *cas= item->cas;
+      release_item(item);
     }
   }
   else
@@ -81,15 +82,18 @@ static protocol_binary_response_status append_handler(const void *cookie,
   else if ((nitem= create_item(key, keylen, NULL, item->size + vallen,
                                item->flags, item->exp)) == NULL)
   {
+    release_item(item);
     rval= PROTOCOL_BINARY_RESPONSE_ENOMEM;
   }
   else
   {
     memcpy(nitem->data, item->data, item->size);
     memcpy(((char*)(nitem->data)) + item->size, val, vallen);
+    release_item(item);
     delete_item(key, keylen);
     put_item(nitem);
     *result_cas= nitem->cas;
+    release_item(nitem);
   }
 
   return rval;
@@ -116,6 +120,7 @@ static protocol_binary_response_status decrement_handler(const void *cookie,
       val= *(uint64_t*)item->data - delta;
 
     expiration= (uint32_t)item->exp;
+    release_item(item);
     delete_item(key, keylen);
   }
 
@@ -130,6 +135,7 @@ static protocol_binary_response_status decrement_handler(const void *cookie,
     put_item(item);
     *result= val;
     *result_cas= item->cas;
+    release_item(item);
   }
 
   return rval;
@@ -145,9 +151,14 @@ static protocol_binary_response_status delete_handler(const void *cookie,
   if (cas != 0)
   {
     struct item *item= get_item(key, keylen);
-    if (item != NULL && item->cas != cas)
+    if (item != NULL)
     {
-      return PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS;
+      if (item->cas != cas)
+      {
+        release_item(item);
+        return PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS;
+      }
+      release_item(item);
     }
   }
 
@@ -179,9 +190,12 @@ static protocol_binary_response_status get_handler(const void *cookie,
     return PROTOCOL_BINARY_RESPONSE_KEY_ENOENT;
   }
 
-  return response_handler(cookie, key, (uint16_t)keylen,
+  protocol_binary_response_status rc;
+  rc= response_handler(cookie, key, (uint16_t)keylen,
                           item->data, (uint32_t)item->size, item->flags,
                           item->cas);
+  release_item(item);
+  return rc;
 }
 
 static protocol_binary_response_status increment_handler(const void *cookie,
@@ -201,6 +215,7 @@ static protocol_binary_response_status increment_handler(const void *cookie,
   {
     val= (*(uint64_t*)item->data) + delta;
     expiration= (uint32_t)item->exp;
+    release_item(item);
     delete_item(key, keylen);
   }
 
@@ -217,6 +232,7 @@ static protocol_binary_response_status increment_handler(const void *cookie,
     put_item(item);
     *result= val;
     *result_cas= item->cas;
+    release_item(item);
   }
 
   return rval;
@@ -238,7 +254,8 @@ static protocol_binary_response_status prepend_handler(const void *cookie,
   protocol_binary_response_status rval= PROTOCOL_BINARY_RESPONSE_SUCCESS;
 
   struct item *item= get_item(key, keylen);
-  struct item *nitem;
+  struct item *nitem= NULL;
+
   if (item == NULL)
   {
     rval= PROTOCOL_BINARY_RESPONSE_KEY_ENOENT;
@@ -256,11 +273,19 @@ static protocol_binary_response_status prepend_handler(const void *cookie,
   {
     memcpy(nitem->data, val, vallen);
     memcpy(((char*)(nitem->data)) + vallen, item->data, item->size);
+    release_item(item);
+    item= NULL;
     delete_item(key, keylen);
     put_item(nitem);
     *result_cas= nitem->cas;
   }
 
+  if (item)
+    release_item(item);
+
+  if (nitem)
+    release_item(nitem);
+
   return rval;
 }
 
@@ -288,6 +313,7 @@ static protocol_binary_response_status replace_handler(const void *cookie,
   }
   else if (cas == 0 || cas == item->cas)
   {
+    release_item(item);
     delete_item(key, keylen);
     item= create_item(key, keylen, data, datalen, flags, (time_t)exptime);
     if (item == 0)
@@ -298,11 +324,13 @@ static protocol_binary_response_status replace_handler(const void *cookie,
     {
       put_item(item);
       *result_cas= item->cas;
+      release_item(item);
     }
   }
   else
   {
     rval= PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS;
+    release_item(item);
   }
 
   return rval;
@@ -326,6 +354,7 @@ static protocol_binary_response_status set_handler(const void *cookie,
     if (item != NULL && cas != item->cas)
     {
       /* Invalid CAS value */
+      release_item(item);
       return PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS;
     }
   }
@@ -340,6 +369,7 @@ static protocol_binary_response_status set_handler(const void *cookie,
   {
     put_item(item);
     *result_cas= item->cas;
+    release_item(item);
   }
 
   return rval;
index e450774edefab99d36732066f911722510886650..72439361bde166d990819f130016382e254f3d2c 100644 (file)
@@ -153,3 +153,7 @@ void flush(uint32_t when) {
 void update_cas(struct item* item) {
   item->cas= ++cas;
 }
+
+void release_item(struct item* item __attribute__((unused))) {
+  /* EMPTY */
+}
index 1d7b9cb65ff652ce45e5c672e80213ec6f32ca38..f11d1267ec3feef4653ad926ba435b452df66c21 100644 (file)
@@ -486,3 +486,13 @@ void flush(uint32_t when __attribute__((unused))) {
 void update_cas(struct item* item) {
   item->cas= ++cas;
 }
+
+/**
+ * Release all the resources allocated by the item
+ * @param item the item to release
+ */
+void release_item(struct item* item) {
+  free(item->key);
+  free(item->data);
+  free(item);
+}