From 9dc361c4f910276cf5299e48502361308de90de5 Mon Sep 17 00:00:00 2001
From: unknown <pekka@mysql.com>
Date: Wed, 1 Feb 2006 18:09:38 +0100
Subject: [PATCH] ndb - wl#2972 fix some mem leaks

storage/ndb/src/ndbapi/NdbBlob.cpp:
  fix some mem leaks (event ops however are never dtor-ed yet)
storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp:
  fix some mem leaks (event ops however are never dtor-ed yet)
storage/ndb/test/ndbapi/test_event_merge.cpp:
  fix some mem leaks (event ops however are never dtor-ed yet)
---
 storage/ndb/src/ndbapi/NdbBlob.cpp            |  1 +
 .../ndb/src/ndbapi/NdbEventOperationImpl.cpp  | 11 +++-
 storage/ndb/test/ndbapi/test_event_merge.cpp  | 50 ++++++++++++++++---
 3 files changed, 54 insertions(+), 8 deletions(-)

diff --git a/storage/ndb/src/ndbapi/NdbBlob.cpp b/storage/ndb/src/ndbapi/NdbBlob.cpp
index 19a86cbf557..349ec6f4a7b 100644
--- a/storage/ndb/src/ndbapi/NdbBlob.cpp
+++ b/storage/ndb/src/ndbapi/NdbBlob.cpp
@@ -158,6 +158,7 @@ NdbBlob::getBlobEventName(char* bename, Ndb* anNdb, const char* eventName, const
   if (c == NULL)
     return -1;
   getBlobEventName(bename, e, c);
+  delete e; // it is from new NdbEventImpl
   return 0;
 }
 
diff --git a/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp b/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp
index 822a223cf5a..e0b4204465d 100644
--- a/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp
+++ b/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp
@@ -159,7 +159,8 @@ NdbEventOperationImpl::~NdbEventOperationImpl()
   ; // ToDo? We should send stop signal here
   
   m_ndb->theImpl->theNdbObjectIdMap.unmap(m_oid, this);
-  DBUG_PRINT("exit",("this: 0x%x/0x%x oid: %u", this, m_facade, m_oid));
+  DBUG_PRINT("exit",("this: %p/%p oid: %u main: %p",
+             this, m_facade, m_oid, theMainOp));
 
   if (m_eventImpl)
   {
@@ -2028,6 +2029,14 @@ NdbEventBuffer::dropEventOperation(NdbEventOperation* tOp)
       tBlobOp->stop();
       tBlobOp = tBlobOp->m_next;
     }
+
+    // release blob handles now, further access is user error
+    while (op->theBlobList != NULL)
+    {
+      NdbBlob* tBlob = op->theBlobList;
+      op->theBlobList = tBlob->theNext;
+      m_ndb->releaseNdbBlob(tBlob);
+    }
   }
 
   // ToDo, take care of these to be deleted at the
diff --git a/storage/ndb/test/ndbapi/test_event_merge.cpp b/storage/ndb/test/ndbapi/test_event_merge.cpp
index d3c1ee70ce7..ea1ec43da1a 100644
--- a/storage/ndb/test/ndbapi/test_event_merge.cpp
+++ b/storage/ndb/test/ndbapi/test_event_merge.cpp
@@ -366,11 +366,12 @@ struct Data {
     noop = 0;
     ppeq = 0;
   }
-  void free() {
+  void freemem() {
     delete [] tx1.val;
     delete [] tx2.val;
     delete [] bl1.val;
-    init();
+    tx1.val = tx2.val = bl1.val = 0;
+    tx1.len = tx2.len = bl1.len = 0;
   }
 };
 
@@ -469,6 +470,12 @@ operator<<(NdbOut& out, const Data& d)
   return out;
 }
 
+// some random os may define these
+#undef NUL
+#undef INS
+#undef DEL
+#undef UPD
+
 static const uint g_optypes = 3; // real ops 0-2
 
 /*
@@ -504,6 +511,10 @@ struct Op { // single or composite
     match = false;
     gci = 0;
   }
+  void freemem() {
+    data[0].freemem();
+    data[1].freemem();
+  }
 };
 
 static NdbOut&
@@ -583,7 +594,7 @@ getop(Op::Kind a_kind)
     assert(g_freeops == 0);
     Op* op = new Op;
     assert(op != 0);
-    op->next_free = g_opfree;
+    op->next_free = g_opfree; // 0
     g_opfree = op;
     op->free = true;
     g_freeops++;
@@ -594,6 +605,7 @@ getop(Op::Kind a_kind)
   g_freeops--;
   g_usedops++;
   op->init(a_kind);
+  op->free = false;
   return op;
 }
 
@@ -601,8 +613,7 @@ static void
 freeop(Op* op)
 {
   assert(! op->free);
-  op->data[0].free();
-  op->data[1].free();
+  op->freemem();
   op->free = true;
   op->next_free = g_opfree;
   g_opfree = op;
@@ -665,6 +676,18 @@ resetmem()
   g_num_gci = g_num_ev = 0;
 }
 
+static void
+deleteops() // for memleak checks
+{
+  while (g_opfree != 0) {
+    Op* tmp_op = g_opfree;
+    g_opfree = g_opfree->next_free;
+    delete tmp_op;
+    g_freeops--;
+  }
+  assert(g_freeops == 0);
+}
+
 struct Comp {
   Op::Type t1, t2, t3;
 };
@@ -1312,6 +1335,10 @@ runops()
     Op* tot_op = g_pk_op[pk1];
     if (tot_op == 0)
       continue;
+    if (tot_op->next_gci == 0) {
+      assert(g_loop != 0 && tot_op->type == Op::INS);
+      continue;
+    }
     // first commit chain
     assert(tot_op->next_gci != 0);
     gci_op[pk1] = tot_op->next_gci;
@@ -1361,7 +1388,10 @@ mergeops()
     if (tot_op == 0)
       continue;
     Op* gci_op = tot_op->next_gci;
-    assert(gci_op != 0);
+    if (gci_op == 0) {
+      assert(g_loop != 0 && tot_op->type == Op::INS);
+      continue;
+    }
     while (gci_op != 0) {
       Op* com_op = gci_op->next_com;
       assert(com_op != 0 && com_op->next_com == 0);
@@ -1648,6 +1678,7 @@ runevents()
       // copy and add
       Op* ev = getop(Op::EV);
       copyop(g_rec_ev, ev);
+      g_rec_ev->freemem();
       last_ev->next_ev = ev;
       g_num_ev++;
     }
@@ -1706,6 +1737,8 @@ runtest()
   }
   chkrc(dropevent() == 0);
   chkrc(droptable() == 0);
+  resetmem();
+  deleteops();
   return 0;
 }
 
@@ -1836,8 +1869,11 @@ main(int argc, char** argv)
   if (g_ncc->connect(30) == 0) {
     g_ndb = new Ndb(g_ncc, "TEST_DB");
     if (g_ndb->init() == 0 && g_ndb->waitUntilReady(30) == 0) {
-      if (runtest() == 0)
+      if (runtest() == 0) {
+        delete g_ndb;
+        delete g_ncc;
         return NDBT_ProgramExit(NDBT_OK);
+      }
     }
   }
   if (g_evt_op != 0) {