crypto: free excessive memory in NodeBIO
authorFedor Indutny <fedor.indutny@gmail.com>
Fri, 7 Jun 2013 11:31:24 +0000 (15:31 +0400)
committerFedor Indutny <fedor.indutny@gmail.com>
Sat, 8 Jun 2013 11:40:57 +0000 (15:40 +0400)
Before this commit NodeBIO never shrank, possibly consuming a lot of
memory (depending on reader's haste).

All buffers between write_head's child and read_head should be
deallocated on read, leaving only space left in write_head and in the
next buffer.

src/node_crypto_bio.cc
src/node_crypto_bio.h

index 52e5e78..64d9efa 100644 (file)
@@ -210,10 +210,34 @@ size_t NodeBIO::Read(char* out, size_t size) {
   assert(expected == bytes_read);
   length_ -= bytes_read;
 
+  // Free all empty buffers, but write_head's child
+  FreeEmpty();
+
   return bytes_read;
 }
 
 
+void NodeBIO::FreeEmpty() {
+  Buffer* child = write_head_->next_;
+  if (child == write_head_ || child == read_head_)
+    return;
+  Buffer* cur = child->next_;
+  if (cur == write_head_ || cur == read_head_)
+    return;
+
+  while (cur != read_head_) {
+    assert(cur != write_head_);
+    assert(cur->write_pos_ == cur->read_pos_);
+
+    Buffer* next = cur->next_;
+    child->next_ = next;
+    delete cur;
+
+    cur = next;
+  }
+}
+
+
 size_t NodeBIO::IndexOf(char delim, size_t limit) {
   size_t bytes_read = 0;
   size_t max = Length() > limit ? limit : Length();
index 9411b3b..e565b7f 100644 (file)
@@ -62,6 +62,10 @@ class NodeBIO {
   // Read `len` bytes maximum into `out`, return actual number of read bytes
   size_t Read(char* out, size_t size);
 
+  // Memory optimization:
+  // Deallocate children of write head's child if they're empty
+  void FreeEmpty();
+
   // Find first appearance of `delim` in buffer or `limit` if `delim`
   // wasn't found.
   size_t IndexOf(char delim, size_t limit);