[Pkg-javascript-commits] [node-leveldown] 01/02: backport memory leak fixes from 0.4.1 & 0.4.2

Andrew Kelley andrewrk-guest at moszumanska.debian.org
Sun Jul 6 17:17:22 UTC 2014


This is an automated email from the git hooks/post-receive script.

andrewrk-guest pushed a commit to tag 0.2.3
in repository node-leveldown.

commit d6a6e1d9b23e937204317fd7a941a6fafc0f6093
Author: Rod Vagg <rod at vagg.org>
Date:   Fri May 17 13:24:22 2013 +1000

    backport memory leak fixes from 0.4.1 & 0.4.2
---
 package.json          |  2 +-
 src/batch.cc          | 36 +++++++++++++++---------------------
 src/batch.h           |  2 +-
 src/database.cc       | 27 +++++++++++++--------------
 src/database.h        | 19 +++++++++++++++++++
 src/database_async.cc | 18 ++++++------------
 src/database_async.h  |  4 ++--
 src/leveldown.h       | 12 ++++++++++++
 8 files changed, 69 insertions(+), 51 deletions(-)

diff --git a/package.json b/package.json
index 418075d..ea9ae96 100644
--- a/package.json
+++ b/package.json
@@ -25,7 +25,7 @@
       , "rimraf"             : "~2.1.4"
       , "mkfiletree"         : "~0.0.0"
       , "readfiletree"       : "~0.0.0"
-      , "abstract-leveldown" : "git://github.com/rvagg/node-abstract-leveldown.git"
+      , "abstract-leveldown" : "~0.4.0"
     }
   , "repository"      : {
         "type"            : "git"
diff --git a/src/batch.cc b/src/batch.cc
index 0436599..3f43e53 100644
--- a/src/batch.cc
+++ b/src/batch.cc
@@ -13,17 +13,11 @@ Batch::Batch (leveldown::Database* database, bool sync) : database(database) {
   options = new leveldb::WriteOptions();
   options->sync = sync;
   batch = new leveldb::WriteBatch();
-  references = new std::vector< v8::Persistent<v8::Value> >;
+  references = new std::vector<Reference>;
 }
 
 Batch::~Batch () {
-  for (std::vector< v8::Persistent<v8::Value> >::iterator it = references->begin()
-      ; it != references->end()
-      ; ) {
-    it->Dispose(LD_NODE_ISOLATE);
-    it = references->erase(it);
-  }
-  delete references;
+  ClearReferences(references);
   delete options;
   delete batch;
 }
@@ -108,14 +102,14 @@ v8::Handle<v8::Value> Batch::Put (const v8::Arguments& args) {
   LD_STRING_OR_BUFFER_TO_SLICE(key, keyBuffer, key)
   LD_STRING_OR_BUFFER_TO_SLICE(value, valueBuffer, value)
 
-  if (node::Buffer::HasInstance(keyBuffer->ToObject()))
-    batch->references->push_back(v8::Persistent<v8::Value>::New(
-        LD_NODE_ISOLATE_PRE
-        keyBuffer));
-  if (node::Buffer::HasInstance(valueBuffer->ToObject()))
-    batch->references->push_back(v8::Persistent<v8::Value>::New(
-        LD_NODE_ISOLATE_PRE
-        valueBuffer));
+  batch->references->push_back(Reference(
+      v8::Persistent<v8::Value>::New(LD_NODE_ISOLATE_PRE keyBuffer)
+    , key
+  ));
+  batch->references->push_back(Reference(
+      v8::Persistent<v8::Value>::New(LD_NODE_ISOLATE_PRE valueBuffer)
+    , value
+  ));
 
   batch->batch->Put(key, value);
 
@@ -133,10 +127,10 @@ v8::Handle<v8::Value> Batch::Del (const v8::Arguments& args) {
   v8::Local<v8::Value> keyBuffer = args[0];
   LD_STRING_OR_BUFFER_TO_SLICE(key, keyBuffer, key)
 
-  if (node::Buffer::HasInstance(keyBuffer->ToObject()))
-    batch->references->push_back(v8::Persistent<v8::Value>::New(
-        LD_NODE_ISOLATE_PRE
-        keyBuffer));
+  batch->references->push_back(Reference(
+      v8::Persistent<v8::Value>::New(LD_NODE_ISOLATE_PRE keyBuffer)
+    , key
+  ));
 
   batch->batch->Delete(key);
 
@@ -169,4 +163,4 @@ v8::Handle<v8::Value> Batch::Write (const v8::Arguments& args) {
   return v8::Undefined();
 }
 
-} // namespace leveldown
\ No newline at end of file
+} // namespace leveldown
diff --git a/src/batch.h b/src/batch.h
index 4655b05..1077670 100644
--- a/src/batch.h
+++ b/src/batch.h
@@ -26,7 +26,7 @@ private:
   leveldown::Database* database;
   leveldb::WriteOptions* options;
   leveldb::WriteBatch* batch;
-  std::vector< v8::Persistent<v8::Value> >* references;
+  std::vector<Reference>* references;
 
   static v8::Persistent<v8::Function> constructor;
 
diff --git a/src/database.cc b/src/database.cc
index 0eacb15..9b64e00 100644
--- a/src/database.cc
+++ b/src/database.cc
@@ -411,8 +411,7 @@ v8::Handle<v8::Value> Database::Batch (const v8::Arguments& args) {
 
   v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(args[0]);
 
-  std::vector< v8::Persistent<v8::Value> >* references =
-      new std::vector< v8::Persistent<v8::Value> >;
+  std::vector<Reference>* references = new std::vector<Reference>;
   leveldb::WriteBatch* batch = new leveldb::WriteBatch();
 
   for (unsigned int i = 0; i < array->Length(); i++) {
@@ -430,10 +429,10 @@ v8::Handle<v8::Value> Database::Batch (const v8::Arguments& args) {
       LD_STRING_OR_BUFFER_TO_SLICE(key, keyBuffer, key)
 
       batch->Delete(key);
-      if (node::Buffer::HasInstance(keyBuffer->ToObject()))
-        references->push_back(v8::Persistent<v8::Value>::New(
-            LD_NODE_ISOLATE_PRE
-            keyBuffer));
+      references->push_back(Reference(
+          v8::Persistent<v8::Value>::New(LD_NODE_ISOLATE_PRE keyBuffer)
+        , key
+      ));
     } else if (obj->Get(str_type)->StrictEquals(str_put)) {
       v8::Local<v8::Value> valueBuffer = obj->Get(str_value);
       LD_CB_ERR_IF_NULL_OR_UNDEFINED(valueBuffer, value)
@@ -442,14 +441,14 @@ v8::Handle<v8::Value> Database::Batch (const v8::Arguments& args) {
       LD_STRING_OR_BUFFER_TO_SLICE(value, valueBuffer, value)
 
       batch->Put(key, value);
-      if (node::Buffer::HasInstance(keyBuffer->ToObject()))
-        references->push_back(v8::Persistent<v8::Value>::New(
-            LD_NODE_ISOLATE_PRE
-            keyBuffer));
-      if (node::Buffer::HasInstance(valueBuffer->ToObject()))
-        references->push_back(v8::Persistent<v8::Value>::New(
-            LD_NODE_ISOLATE_PRE
-            valueBuffer));
+      references->push_back(Reference(
+          v8::Persistent<v8::Value>::New(LD_NODE_ISOLATE_PRE keyBuffer)
+        , key
+      ));
+      references->push_back(Reference(
+          v8::Persistent<v8::Value>::New(LD_NODE_ISOLATE_PRE valueBuffer)
+        , value
+      ));
     }
   }
 
diff --git a/src/database.h b/src/database.h
index b2f2377..5a5a32a 100644
--- a/src/database.h
+++ b/src/database.h
@@ -7,6 +7,7 @@
 #define LD_DATABASE_H
 
 #include <map>
+#include <vector>
 #include <node.h>
 
 #include "leveldb/db.h"
@@ -31,6 +32,24 @@ struct AsyncDescriptor;
 
 v8::Handle<v8::Value> LevelDOWN (const v8::Arguments& args);
 
+struct Reference {
+  v8::Persistent<v8::Value> ptr;
+  leveldb::Slice slice;
+  Reference(v8::Persistent<v8::Value> ptr, leveldb::Slice slice) :
+      ptr(ptr)
+    , slice(slice) { };
+};
+
+static inline void ClearReferences (std::vector<Reference>* references) {
+  for (std::vector<Reference>::iterator it = references->begin()
+      ; it != references->end()
+      ; ) {
+    DisposeStringOrBufferFromSlice(it->ptr, it->slice);
+    it = references->erase(it);
+  }
+  delete references;
+}
+
 class Database : public node::ObjectWrap {
 public:
   static void Init ();
diff --git a/src/database_async.cc b/src/database_async.cc
index 2644f7c..ef24498 100644
--- a/src/database_async.cc
+++ b/src/database_async.cc
@@ -85,7 +85,7 @@ IOWorker::~IOWorker () {}
 
 void IOWorker::WorkComplete () {
   AsyncWorker::WorkComplete();
-  keyPtr.Dispose(LD_NODE_ISOLATE);
+  DisposeStringOrBufferFromSlice(keyPtr, key);
 }
 
 /** READ WORKER **/
@@ -172,7 +172,7 @@ void WriteWorker::Execute () {
 
 void WriteWorker::WorkComplete () {
   IOWorker::WorkComplete();
-  valuePtr.Dispose(LD_NODE_ISOLATE);
+  DisposeStringOrBufferFromSlice(valuePtr, value);
 }
 
 /** BATCH WORKER **/
@@ -181,7 +181,7 @@ BatchWorker::BatchWorker (
     Database* database
   , v8::Persistent<v8::Function> callback
   , leveldb::WriteBatch* batch
-  , std::vector< v8::Persistent<v8::Value> >* references
+  , std::vector<Reference>* references
   , bool sync
 ) : AsyncWorker(database, callback)
   , batch(batch)
@@ -192,13 +192,7 @@ BatchWorker::BatchWorker (
 };
 
 BatchWorker::~BatchWorker () {
-  for (std::vector< v8::Persistent<v8::Value> >::iterator it = references->begin()
-      ; it != references->end()
-      ; ) {
-    it->Dispose(LD_NODE_ISOLATE);
-    it = references->erase(it);
-  }
-  delete references;
+  ClearReferences(references);
   delete options;
 }
 
@@ -229,8 +223,8 @@ void ApproximateSizeWorker::Execute () {
 
 void ApproximateSizeWorker::WorkComplete() {
   AsyncWorker::WorkComplete();
-  startPtr.Dispose(LD_NODE_ISOLATE);
-  endPtr.Dispose(LD_NODE_ISOLATE);
+  DisposeStringOrBufferFromSlice(startPtr, range.start);
+  DisposeStringOrBufferFromSlice(endPtr, range.limit);
 }
 
 void ApproximateSizeWorker::HandleOKCallback () {
diff --git a/src/database_async.h b/src/database_async.h
index 8ca9fdd..80dafff 100644
--- a/src/database_async.h
+++ b/src/database_async.h
@@ -131,7 +131,7 @@ public:
       Database* database
     , v8::Persistent<v8::Function> callback
     , leveldb::WriteBatch* batch
-    , std::vector< v8::Persistent<v8::Value> >* references
+    , std::vector<Reference>* references
     , bool sync
   );
 
@@ -141,7 +141,7 @@ public:
 private:
   leveldb::WriteOptions* options;
   leveldb::WriteBatch* batch;
-  std::vector< v8::Persistent<v8::Value> >* references;
+  std::vector<Reference>* references;
 };
 
 class ApproximateSizeWorker : public AsyncWorker {
diff --git a/src/leveldown.h b/src/leveldown.h
index 49fd2fe..67d0c80 100644
--- a/src/leveldown.h
+++ b/src/leveldown.h
@@ -7,6 +7,7 @@
 
 #include <node.h>
 #include <node_buffer.h>
+#include <leveldb/slice.h>
 
 static inline char* FromV8String(v8::Local<v8::Value> from) {
   size_t sz_;
@@ -79,6 +80,17 @@ static inline uint32_t UInt32OptionValue(
     LD_RETURN_CALLBACK_OR_ERROR(callback, #name " cannot be `null` or `undefined`") \
   }
 
+// NOTE: this MUST be called on objects created by
+// LD_STRING_OR_BUFFER_TO_SLICE
+static inline void DisposeStringOrBufferFromSlice(v8::Persistent<v8::Value> ptr
+      , leveldb::Slice slice) {
+
+  if (!node::Buffer::HasInstance(ptr))
+    delete slice.data();
+  ptr.Dispose(LD_NODE_ISOLATE);
+}
+
+// NOTE: must call DisposeStringOrBufferFromSlice() on objects created here
 #define LD_STRING_OR_BUFFER_TO_SLICE(to, from, name)                           \
   size_t to ## Sz_;                                                            \
   char* to ## Ch_;                                                             \

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-leveldown.git



More information about the Pkg-javascript-commits mailing list