=== modified file 'storage/ndb/include/ndbapi/ndb_cluster_connection.hpp'
--- a/storage/ndb/include/ndbapi/ndb_cluster_connection.hpp	2007-04-02 20:37:34 +0000
+++ b/storage/ndb/include/ndbapi/ndb_cluster_connection.hpp	2008-09-10 00:32:18 +0000
@@ -166,6 +166,7 @@
   friend class Ndb;
   friend class NdbImpl;
   friend class Ndb_cluster_connection_impl;
+  friend class SignalSender;
   class Ndb_cluster_connection_impl & m_impl;
   Ndb_cluster_connection(Ndb_cluster_connection_impl&);
 };

=== modified file 'storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp'
--- a/storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp	2008-09-04 15:45:21 +0000
+++ b/storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp	2008-09-10 00:32:18 +0000
@@ -1101,7 +1101,9 @@
 
   if (arg == DumpStateOrd::CmvmiTestLongSigWithDelay) {
     unsigned i;
-    Uint32 loopCount = dumpState->args[1];
+    Uint32 testType = dumpState->args[1];
+    Uint32 loopCount = dumpState->args[2];
+    Uint32 print = dumpState->args[3];
     const unsigned len0 = 11;
     const unsigned len1 = 123;
     Uint32 sec0[len0];
@@ -1112,9 +1114,9 @@
       sec1[i] = 16 * i;
     Uint32* sig = signal->getDataPtrSend();
     sig[0] = reference();
-    sig[1] = 20; // test type
+    sig[1] = testType;
     sig[2] = 0;
-    sig[3] = 0;
+    sig[3] = print;
     sig[4] = loopCount;
     sig[5] = len0;
     sig[6] = len1;
@@ -1243,6 +1245,15 @@
 static Uint32 g_print;
 static LinearSectionPtr g_test[3];
 
+/* See above for how to generate TESTSIG using DUMP 2603
+ * (e.g. : <All/NodeId> DUMP 2603 <TestId> <LoopCount> <Print>
+ *   LoopCount : How many times test should loop (0-n)
+ *   Print : Whether signals should be printed : 0=no 1=yes
+ * 
+ * TestIds
+ *   20 : Test sendDelayed with 1 milli delay, LoopCount times
+ *   1-16 : See vm/testLongSig.cpp
+ */
 void
 Cmvmi::execTESTSIG(Signal* signal){
   Uint32 i;
@@ -1308,10 +1319,14 @@
       return;
     }
     signal->theData[4]--;
-    sendSignalWithDelay(reference(), GSN_TESTSIG, signal, 100, 8);
+    sendSignalWithDelay(reference(), GSN_TESTSIG, signal, 100, 8, &handle);
     return;
   }
-  
+
+  if (g_print)
+    ndbout_c("TestType=%u signal->theData[4]=%u, sendersBlockRef=%u ref=%u\n",
+             testType, signal->theData[4], signal->getSendersBlockRef(), ref);
+
   NodeReceiverGroup rg(CMVMI, c_dbNodes);
 
   if(signal->getSendersBlockRef() == ref){
@@ -1319,19 +1334,23 @@
      * Signal from API (not via NodeReceiverGroup)
      */
     if((testType % 2) == 1){
-      signal->theData[4] = 1;
+      signal->theData[4] = 1; // No further signals after this
     } else {
+      // Change testType to UniCast, and set loopCount to the
+      // number of nodes.
       signal->theData[1] --;
       signal->theData[4] = rg.m_nodes.count();
     }
-  } 
+  }
   
   switch(testType){
   case 1:
+    /* Unicast to self */
     sendSignal(ref, GSN_TESTSIG,  signal, signal->length(), JBB,
 	       &handle);
     break;
   case 2:
+    /* Multicast to all nodes */
     sendSignal(rg, GSN_TESTSIG,  signal, signal->length(), JBB,
 	       &handle);
     break;
@@ -1348,8 +1367,10 @@
     }
     
     if(testType == 3){
+      /* Unicast linear sections to self */
       sendSignal(ref, GSN_TESTSIG, signal, signal->length(), JBB, ptr, secs);
     } else {
+      /* Boradcast linear sections to all nodes */
       sendSignal(rg, GSN_TESTSIG, signal, signal->length(), JBB, ptr, secs);
     }
     for(Uint32 i = 0; i<secs; i++){
@@ -1358,13 +1379,16 @@
     releaseSections(handle);
     break;
   }
+  /* Send fragmented segmented sections direct send */
   case 5:
   case 6:{
     
     NodeReceiverGroup tmp;
     if(testType == 5){
+      /* Unicast */
       tmp  = ref;
     } else {
+      /* Multicast */
       tmp = rg;
     }
     
@@ -1388,6 +1412,7 @@
     }
     break;
   }
+  /* Send fragmented linear sections direct send */
   case 7:
   case 8:{
     LinearSectionPtr ptr[3];
@@ -1402,8 +1427,10 @@
 
     NodeReceiverGroup tmp;
     if(testType == 7){
+      /* Unicast */
       tmp  = ref;
     } else {
+      /* Multicast */
       tmp = rg;
     }
 
@@ -1432,6 +1459,7 @@
     releaseSections(handle);
     break;
   }
+  /* Test fragmented segmented send with callback */
   case 9:
   case 10:{
 
@@ -1440,6 +1468,7 @@
       safe_cast(&Cmvmi::sendFragmentedComplete);
     
     if(testType == 9){
+      /* Unicast */
       m_callBack.m_callbackData = 9;
       sendFragmentedSignal(ref,
 			   GSN_TESTSIG, signal, signal->length(), JBB, 
@@ -1447,6 +1476,7 @@
 			   m_callBack,
 			   fragmentLength);
     } else {
+      /* Multicast */
       m_callBack.m_callbackData = 10;
       sendFragmentedSignal(rg,
 			   GSN_TESTSIG, signal, signal->length(), JBB, 
@@ -1456,6 +1486,7 @@
     }
     break;
   }
+  /* Test fragmented linear send with callback */
   case 11:
   case 12:{
 
@@ -1469,12 +1500,14 @@
       copy(g_test[i].p, sptr);
     }
     
+    releaseSections(handle);
     
     Callback m_callBack;
     m_callBack.m_callbackFunction = 
       safe_cast(&Cmvmi::sendFragmentedComplete);
     
     if(testType == 11){
+      /* Unicast */
       m_callBack.m_callbackData = 11;
       sendFragmentedSignal(ref,
 			   GSN_TESTSIG, signal, signal->length(), JBB, 
@@ -1482,6 +1515,7 @@
 			   m_callBack,
 			   fragmentLength);
     } else {
+      /* Multicast */
       m_callBack.m_callbackData = 12;
       sendFragmentedSignal(rg,
 			   GSN_TESTSIG, signal, signal->length(), JBB, 
@@ -1491,7 +1525,46 @@
     }
     break;
   }
-  case 13:{
+  /* Send fragmented segmented sections direct send no-release */
+  case 13:
+  case 14:{
+    NodeReceiverGroup tmp;
+    if(testType == 13){
+      /* Unicast */
+      tmp  = ref;
+    } else {
+      /* Multicast */
+      tmp = rg;
+    }
+    
+    FragmentSendInfo fragSend;
+    sendFirstFragment(fragSend,
+		      tmp,
+		      GSN_TESTSIG,
+		      signal,
+		      signal->length(),
+		      JBB,
+		      &handle,
+		      true, // Don't release sections
+                      fragmentLength);
+
+    int count = 1;
+    while(fragSend.m_status != FragmentSendInfo::SendComplete){
+      count++;
+      if(g_print)
+	ndbout_c("Sending fragment %d", count);
+      sendNextSegmentedFragment(signal, fragSend);
+    }
+
+    if (g_print)
+      ndbout_c("Free sections : %u\n", g_sectionSegmentPool.getNoOfFree());
+    releaseSections(handle);
+    //handle.clear(); // Use instead of releaseSections to Leak sections 
+    break;
+  }
+  /* Loop decrementing signal->theData[9] */
+  case 15:{
+    releaseSections(handle);
     ndbrequire(signal->getNoOfSections() == 0);
     Uint32 loop = signal->theData[9];
     if(loop > 0){
@@ -1502,7 +1575,8 @@
     sendSignal(ref, GSN_TESTSIG, signal, signal->length(), JBB);
     return;
   }
-  case 14:{
+  case 16:{
+    releaseSections(handle);
     Uint32 count = signal->theData[8];
     signal->theData[10] = count * rg.m_nodes.count();
     for(i = 0; i<count; i++){

=== modified file 'storage/ndb/src/kernel/vm/Makefile.am'
--- a/storage/ndb/src/kernel/vm/Makefile.am	2008-07-25 05:48:32 +0000
+++ b/storage/ndb/src/kernel/vm/Makefile.am	2008-09-10 00:32:18 +0000
@@ -75,7 +75,9 @@
 	@$(top_srcdir)/storage/ndb/config/win-sources $@ $(libkernel_a_SOURCES)
 	@$(top_srcdir)/storage/ndb/config/win-libraries $@ LIB $(LDADD)
 
-EXTRA_PROGRAMS = ndbd_malloc_impl_test bench_pool testDynArr256
+EXTRA_PROGRAMS = ndbd_malloc_impl_test bench_pool testDynArr256 \
+                 testSectionReader testLongSignals
+
 ndbd_malloc_impl_test_CXXFLAGS = -DUNIT_TEST
 ndbd_malloc_impl_test_SOURCES = ndbd_malloc_impl.cpp
 ndbd_malloc_impl_test_LDFLAGS = @ndb_bin_am_ldflags@ \
@@ -101,3 +103,20 @@
   $(top_builddir)/dbug/libdbuglt.la \
   $(top_builddir)/strings/libmystringslt.la
 
+testSectionReader_CXXFLAGS = -DUNIT_TEST
+testSectionReader_SOURCES = SectionReader.cpp
+testSectionReader_LDFLAGS = @ndb_bin_am_ldflags@ \
+  $(top_builddir)/storage/ndb/src/libndbclient.la \
+  $(top_builddir)/mysys/libmysyslt.la \
+  $(top_builddir)/dbug/libdbuglt.la \
+  $(top_builddir)/strings/libmystringslt.la
+
+testLongSignals_CXXFLAGS = -DUNIT_TEST
+testLongSignals_SOURCES = testLongSig/testLongSig.cpp
+testLongSignals_LDFLAGS = @ndb_bin_am_ldflags@ \
+  $(top_builddir)/storage/ndb/src/libndbclient.la \
+  $(top_builddir)/mysys/libmysyslt.la \
+  $(top_builddir)/dbug/libdbuglt.la \
+  $(top_builddir)/strings/libmystringslt.la \
+  @readline_link@ @TERMCAP_LIB@
+

=== modified file 'storage/ndb/src/kernel/vm/SectionReader.cpp'
--- a/storage/ndb/src/kernel/vm/SectionReader.cpp	2008-09-04 15:45:21 +0000
+++ b/storage/ndb/src/kernel/vm/SectionReader.cpp	2008-09-10 00:32:18 +0000
@@ -13,6 +13,7 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
+
 #include <SectionReader.hpp>
 #include <TransporterDefinitions.hpp>
 #include "LongSignal.hpp"
@@ -186,14 +187,15 @@
    * there's another one, move onto it ready for 
    * next time
    */
+  m_pos += actualLen;
+
   if (((startInd + actualLen) == SectionSegment::DataLength) &&
-      (p->m_nextSegment != RNIL))
+      (m_pos < m_len))
   {
     m_currI= p->m_nextSegment;
     m_currentSegment= m_pool.getPtr(m_currI);
   }
 
-  m_pos += actualLen;
   return true;
 };
 
@@ -267,3 +269,339 @@
 
   return (IVal == posInfo.currIVal);
 }
+
+
+#ifdef UNIT_TEST
+
+#define VERIFY(x) if ((x) == 0) { printf("VERIFY failed at Line %u : %s\n",__LINE__, #x);  return -1; }
+
+/* Redefine ArrayPool dependencies to enable standalone Unit-test compile */
+void ErrorReporter::handleAssert(const char* message, const char* file, int line, int ec)
+{
+  printf("Error :\"%s\" at file : %s line %u ec %u\n",
+         message, file, line, ec);
+  abort();
+}
+
+void* ndbd_malloc(size_t size)
+{
+  return malloc(size);
+}
+
+void ndbd_free(void* p, size_t size)
+{
+  free(p);
+}
+
+SectionSegmentPool g_sectionSegmentPool;
+
+/* Create a section of word length given from the
+ * Segment Pool supplied
+ */
+Uint32 createSection(SectionSegmentPool* pool,
+                     Uint32 length)
+{
+  Uint32 pos= 0; 
+  
+  VERIFY(length > 0);
+
+  Ptr<SectionSegment> first, current;
+
+  VERIFY(pool->seize(first));
+
+  first.p->m_sz= length;
+  current= first;
+  
+  while (length > SectionSegment::DataLength)
+  {
+    for (Uint32 i=0; i<SectionSegment::DataLength; i++)
+      current.p->theData[i]= pos+i;
+    
+    pos+= SectionSegment::DataLength;
+    length-= SectionSegment::DataLength;
+    
+    SectionSegment* prev= current.p;
+    VERIFY(pool->seize(current));
+    prev->m_nextSegment= current.i;
+  }
+  
+  if (length > 0)
+  {
+    for (Uint32 i=0; i< length; i++)
+      current.p->theData[i]= pos+i;
+  };
+
+  first.p->m_lastSegment= current.i;
+
+  return first.i;
+};
+
+bool freeSection(SectionSegmentPool* pool,
+                 Uint32 firstIVal)
+{
+  Ptr<SectionSegment> p;
+
+  p.i= firstIVal;
+  pool->getPtr(p);
+
+  const Uint32 segs= (p.p->m_sz + SectionSegment::DataLength -1) / 
+    SectionSegment::DataLength;
+  
+  pool->releaseList(segs, p.i, p.p->m_lastSegment);
+
+  return true;
+}
+
+int checkBuffer(const Uint32* buffer,
+                Uint32 start,
+                Uint32 len)
+{
+  for (Uint32 i=0; i<len; i++)
+  {
+    if (buffer[i] != start + i)
+      printf("i=%u buffer[i]=%u, start=%u\n",
+             i, buffer[i], start);
+    VERIFY(buffer[i] == start + i);
+  }
+  return 0;
+};
+
+#include <random.h>
+
+int testSR(Uint32 iVal, SectionSegmentPool* ssp, Uint32 len)
+{
+  SectionReader srStepPeek(iVal, *ssp);
+  SectionReader srGetWord(iVal, *ssp);
+  SectionReader srPosSource(iVal, *ssp);
+  SectionReader srPosDest(iVal, *ssp);
+  SectionReader srPtrWord(iVal, *ssp);
+
+  VERIFY(srStepPeek.getSize() == len);
+
+  /* Reset the section readers at a random position */
+  const Uint32 noResetPos= 9999999;
+  Uint32 resetAt= len> 10 ? myRandom48(len) : noResetPos;
+
+  /* Read from the section readers, 1 word at a time */
+  for (Uint32 i=0; i < len; i++)
+  {
+    Uint32 peekWord;
+    Uint32 getWord;
+    const Uint32* ptrWord;
+    Uint32 ptrReadSize;
+
+    /* Check that peek, getWord and getWordsPtr return
+     * the same, correct value
+     */
+    VERIFY(srStepPeek.peekWord(&peekWord));
+    if (i < (len -1))
+        VERIFY(srStepPeek.step(1));
+    VERIFY(srGetWord.getWord(&getWord));
+    VERIFY(srPtrWord.getWordsPtr(1, ptrWord, ptrReadSize));
+    VERIFY(ptrReadSize == 1);
+    //printf("PeekWord=%u, i=%u\n",
+    //       peekWord, i);
+    VERIFY(peekWord == i);
+    VERIFY(peekWord == getWord);
+    VERIFY(peekWord == *ptrWord);
+
+    /* Check that one sectionReader with it's position
+     * set from the first returns the same, correct word
+     */
+    SectionReader::PosInfo p= srPosSource.getPos();
+    srPosDest.setPos(p);
+    
+    Uint32 srcWord, destWord;
+
+    VERIFY(srPosSource.getWord(&srcWord));
+    VERIFY(srPosDest.getWord(&destWord));
+    
+    VERIFY(srcWord == peekWord);
+    VERIFY(srcWord == destWord);
+
+    /* Reset the readers */
+    if (i == resetAt)
+    {
+      //printf("Resetting\n");
+      resetAt= noResetPos;
+      i= (Uint32) -1;
+      srStepPeek.reset();
+      srGetWord.reset();
+      srPosSource.reset();
+      srPosDest.reset();
+      srPtrWord.reset();
+    }
+    else
+    {
+      if ((myRandom48(400) == 1) &&
+          (i < len -1))
+      {
+        /* Step all readers forward by some amount */
+        Uint32 stepSize= myRandom48((len - i) -1 );
+        //printf("Stepping %u words\n", stepSize);
+        VERIFY(srStepPeek.step(stepSize));
+        VERIFY(srGetWord.step(stepSize));
+        VERIFY(srPosSource.step(stepSize));
+        VERIFY(srPosDest.step(stepSize));
+        VERIFY(srPtrWord.step(stepSize));
+        i+= stepSize;
+      }
+    }
+  }
+
+  /* Check that there's nothing left in any reader */
+  VERIFY(!srStepPeek.step(1));
+  VERIFY(!srGetWord.step(1));
+  VERIFY(!srPosSource.step(1));
+  VERIFY(!srPosDest.step(1));
+  VERIFY(!srPtrWord.step(1));
+
+  srStepPeek.reset();
+  srGetWord.reset();
+  srPosSource.reset();
+  srPosDest.reset();
+  srPtrWord.reset();
+  
+  /* Now read larger chunks of words */
+  Uint32 pos= 0;
+  Uint32* buffer= (Uint32*) malloc(len * 4);
+
+  VERIFY(buffer != NULL);
+
+  while (pos < len)
+  {
+    const Uint32 remain= len-pos;
+    const Uint32 readSize= remain == 1 ? 1 : myRandom48(remain);
+    //printf("Pos=%u Len=%u readSize=%u \n", pos, len, readSize);
+    /* Check that peek + step get the correct words */
+    VERIFY(srStepPeek.peekWords(buffer, readSize));
+    if (len > pos + readSize)
+    {
+      VERIFY(srStepPeek.step(readSize));
+    }
+    else
+      VERIFY(srStepPeek.step((len - pos) - 1));
+    
+    VERIFY(checkBuffer(buffer, pos, readSize) == 0);
+
+    /* Check that getWords gets the correct words */
+    VERIFY(srGetWord.getWords(buffer, readSize));
+    VERIFY(checkBuffer(buffer, pos, readSize) == 0);
+
+    /* Check that using getPos + setPos gets the correct words */
+    VERIFY(srPosDest.setPos(srPosSource.getPos()));
+    VERIFY(srPosSource.getWords(buffer, readSize));
+    VERIFY(checkBuffer(buffer, pos, readSize) == 0);
+
+    VERIFY(srPosDest.getWords(buffer, readSize));
+    VERIFY(checkBuffer(buffer, pos, readSize) == 0);
+
+    /* Check that getWordsPtr gets the correct words */
+    Uint32 ptrWordsRead= 0;
+    
+    //printf("Reading from ptr\n");
+    while (ptrWordsRead < readSize)
+    {
+      const Uint32* ptr= NULL;
+      Uint32 readLen;
+      VERIFY(srPtrWord.getWordsPtr((readSize - ptrWordsRead), 
+                                   ptr, 
+                                   readLen));
+      VERIFY(readLen <= readSize);
+      //printf("Read %u words, from pos %u, offset %u\n",
+      //       readLen, pos, ptrWordsRead);
+      VERIFY(checkBuffer(ptr, pos+ ptrWordsRead, readLen) == 0);
+      ptrWordsRead+= readLen;
+    }
+
+    pos += readSize;
+  }
+  
+  /* Check that there's no more words in any reader */
+  VERIFY(!srStepPeek.step(1));
+  VERIFY(!srGetWord.step(1));
+  VERIFY(!srPosSource.step(1));
+  VERIFY(!srPosDest.step(1));
+  VERIFY(!srPtrWord.step(1));
+
+  /* Verify that ptr-fetch variants do not fetch beyond
+   * the length, even if we ask for more
+   */
+  srPtrWord.reset();
+  Uint32 readWords= 0;
+  while (readWords < len)
+  {
+    const Uint32* readPtr;
+    Uint32 wordsRead= 0;
+    VERIFY(srPtrWord.getWordsPtr(20, readPtr, wordsRead));
+    readWords+= wordsRead;
+    VERIFY(readWords <= len);
+  }
+
+  free(buffer);
+  return 0;
+}
+
+
+int main(int arg, char** argv)
+{
+  /* Test SectionReader
+   * -------------------
+   * To run this code : 
+   *   cd storage/ndb/src/kernel/vm
+   *   make testSectionReader
+   *   ./testSectionReader
+   *
+   * Will print "OK" in success case and return 0
+   */
+
+  g_sectionSegmentPool.setSize(1024);
+  
+  printf("g_sectionSegmentPool size is %u\n",
+         g_sectionSegmentPool.getSize());
+
+  const Uint32 Iterations= 2000;
+  const Uint32 Sections= 5;
+  Uint32 sizes[ Sections ];
+  Uint32 iVals[ Sections ];
+
+  for (Uint32 t=0; t < Iterations; t++)
+  {
+    for (Uint32 i=0; i<Sections; i++)
+    {
+      Uint32 available= g_sectionSegmentPool.getNoOfFree();
+      sizes[i] = available ? 
+        myRandom48(SectionSegment::DataLength * 
+                   available)
+        : 0;
+
+      //if (0 == (sizes[i] % 60))
+      //  printf("Iteration %u, section %u, allocating %u words\n",
+      //         t, i, sizes[i]);
+      if (t % 100 == 0)
+        if (i==0)
+          printf("\nIteration %u", t);
+      
+      if (sizes[i] > 0)
+      {
+        iVals[i]= createSection(&g_sectionSegmentPool, sizes[i]);
+
+        VERIFY(testSR(iVals[i], &g_sectionSegmentPool, sizes[i]) == 0);
+      }
+      else
+        iVals[i]= RNIL;
+    }
+
+    
+    for (Uint32 i=0; i < Sections; i++)
+    {
+      if (sizes[i] > 0)
+        freeSection(&g_sectionSegmentPool, iVals[i]);
+    }
+  }
+  
+  printf("\nOK\n");
+  return 0;
+}
+
+#endif

=== removed file 'storage/ndb/src/kernel/vm/testLongSig/Makefile'
--- a/storage/ndb/src/kernel/vm/testLongSig/Makefile	2005-04-27 01:19:54 +0000
+++ b/storage/ndb/src/kernel/vm/testLongSig/Makefile	1970-01-01 00:00:00 +0000
@@ -1,9 +0,0 @@
-include .defs.mk	
-
-TYPE := signalsender 
-
-BIN_TARGET := testLongSig
-
-SOURCES = testLongSig.cpp
-
-include $(NDB_TOP)/Epilogue.mk

=== modified file 'storage/ndb/src/kernel/vm/testLongSig/testLongSig.cpp'
--- a/storage/ndb/src/kernel/vm/testLongSig/testLongSig.cpp	2006-12-23 19:20:40 +0000
+++ b/storage/ndb/src/kernel/vm/testLongSig/testLongSig.cpp	2008-09-10 00:32:18 +0000
@@ -15,8 +15,9 @@
 
 
 #include <ndb_global.h>
+#include <NdbApi.hpp>
 #include <editline/editline.h>
-#include <SignalSender.hpp>
+#include <../../ndbapi/SignalSender.hpp>
 
 void
 print_help(){
@@ -38,11 +39,13 @@
   ndbout << "11 - Sending of CONTINUEB fragmented signals w/ linear sections" 
 	 << endl;
   ndbout << "12 - As but using receiver group" << endl;
-  ndbout << "13 - Send 100 * 1000 25 len signals wo/ sections" << endl;
+  ndbout << "13 - As 5 but with no release" << endl;
+  ndbout << "14 - As 13 but using receiver group" << endl;
+  ndbout << "15 - Send 100 * 1000 25 len signals wo/ sections" << endl;
   ndbout << "r - Recive signal from anyone" << endl;
-  ndbout << "a - Run tests 1 - 12 with variable sizes - 10 loops" << endl;
-  ndbout << "b - Run tests 1 - 12 with variable sizes - 100 loops" << endl;
-  ndbout << "c - Run tests 1 - 12 with variable sizes - 1000k loops" << endl;
+  ndbout << "a - Run tests 1 - 14 with variable sizes - 10 loops" << endl;
+  ndbout << "b - Run tests 1 - 14 with variable sizes - 100 loops" << endl;
+  ndbout << "c - Run tests 1 - 14 with variable sizes - 1000k loops" << endl;
 }
 
 void runTest(SignalSender &, Uint32 i, bool verbose);
@@ -70,8 +73,17 @@
   return i - 1;
 }
 
+/**
+ * testLongSignals
+ * To run this code :
+ *   cd storage/ndb/src/kernel
+ *   make testLongSignals
+ *   ./testLongSignals <connectstring>
+ *
+ */
 int
-main(void){
+main(int argc, char** argv) {
+  ndb_init();
 
   srand(NdbTick_CurrentMillisecond());
 #if 0
@@ -79,14 +91,30 @@
     ndbout_c("randRange(0, 3) = %d", randRange(0, 3));
   return 0;
 #endif
-  SignalSender ss;
+
+  if (argc != 2)
+  {
+    ndbout << "No connectstring given, usage : " << argv[0] 
+           << " <connectstring>" << endl;
+    return -1;
+  }
+  Ndb_cluster_connection con(argv[1]);
   
   ndbout << "Connecting...";
-  if(!ss.connect(30)){
-    ndbout << "failed" << endl << "Exiting" << endl;
-    return 0;
+  if (con.connect(12,5,1) != 0)
+  {
+    ndbout << "Unable to connect to management server." << endl;
+    return -1;
+  }
+  if (con.wait_until_ready(30,0) < 0)
+  {
+    ndbout << "Cluster nodes not ready in 30 seconds." << endl;
+    return -1;
   }
   ndbout << "done" << endl;
+
+  SignalSender ss(&con);
+
   ndbout_c("Connected as block=%d node=%d",
 	   refToBlock(ss.getOwnRef()), refToNode(ss.getOwnRef()));
   
@@ -155,7 +183,6 @@
     if(strcmp(buf, "r") == 0){
       SimpleSignal * ret1 = ss.waitFor();
       (* ret1).print();
-      delete ret1;
       continue;
     }
     if(strcmp(buf, "a") == 0){
@@ -174,7 +201,7 @@
       continue;
     }
     
-    if(data[1] >= 1 && data[1] <= 12){
+    if(data[1] >= 1 && data[1] <= 14){
       Uint32 nodeId = ss.getAliveNode();
       ndbout_c("Sending 2 fragmented to node %d", nodeId);
       ss.sendSignal(nodeId, &signal1);
@@ -188,17 +215,15 @@
       SimpleSignal * ret1 = ss.waitFor((Uint16)nodeId);
       (* ret1).print();
       Uint32 count = ret1->theData[4] - 1;
-      delete ret1;
       while(count > 0){
 	ndbout << "Waiting for " << count << " signals... ";
 	SimpleSignal * ret1 = ss.waitFor();
 	ndbout_c("received from node %d", 
 		 refToNode(ret1->header.theSendersBlockRef));
 	(* ret1).print();
-	delete ret1;
 	count--;
       }
-    } else if (data[1] == 13) {
+    } else if (data[1] == 15) {
       const Uint32 count = 3500;
       const Uint32 loop = 1000;
 
@@ -219,7 +244,6 @@
 	ndbout_c("received from node %d", 
 		 refToNode(ret1->header.theSendersBlockRef));
 	total = ret1->theData[10] - 1;
-	delete ret1;
       }
 
       do {
@@ -227,7 +251,6 @@
 	SimpleSignal * ret1 = ss.waitFor((Uint16)nodeId);
 	ndbout_c("received from node %d", 
 		 refToNode(ret1->header.theSendersBlockRef));
-	delete ret1;
 	total --;
       } while(total > 0);
     } else {
@@ -235,6 +258,7 @@
     }
   }
   ndbout << "Exiting" << endl;
+  ndb_end(0);
 };
 
 void
@@ -282,7 +306,7 @@
       sig.theData[5+i] = sz;
     }
     ndbout_c("] len = %d", len);
-    for(int test = 1; test <= 12; test++){
+    for(int test = 1; test <= 14; test++){
       sig.theData[1] = test;
       Uint32 nodeId = ss.getAliveNode();
       if(verbose){
@@ -294,11 +318,9 @@
       if(test < 5){
 	SimpleSignal * ret1 = ss.waitFor((Uint16)nodeId);
 	Uint32 count = ret1->theData[4] - 1;
-	delete ret1;
 
 	while(count > 0){
-	  SimpleSignal * ret1 = ss.waitFor();
-	  delete ret1;
+	  ret1 = ss.waitFor();
 	  count--;
 	}
 	if(verbose)
@@ -322,7 +344,6 @@
 	     ret->header.m_fragmentInfo == 3){
 	    nodes--;
 	  }
-	  delete ret;
 	}
 	if(verbose)
 	  ndbout_c("done sum=%d sum2=%d", sum, sum2);

=== modified file 'storage/ndb/src/ndbapi/SignalSender.cpp'
--- a/storage/ndb/src/ndbapi/SignalSender.cpp	2008-08-04 20:59:33 +0000
+++ b/storage/ndb/src/ndbapi/SignalSender.cpp	2008-09-10 00:32:18 +0000
@@ -81,6 +81,16 @@
   assert(m_blockNo > 0);
 }
 
+SignalSender::SignalSender(Ndb_cluster_connection* connection)
+{
+  m_cond = NdbCondition_Create();
+  theFacade = connection->m_impl.m_transporter_facade;
+  lock();
+  m_blockNo = theFacade->open(this, execSignal, execNodeStatus, -1);
+  unlock();
+  assert(m_blockNo > 0);
+}
+
 SignalSender::~SignalSender(){
   int i;
   if (m_lock)

=== modified file 'storage/ndb/src/ndbapi/SignalSender.hpp'
--- a/storage/ndb/src/ndbapi/SignalSender.hpp	2008-06-10 14:15:53 +0000
+++ b/storage/ndb/src/ndbapi/SignalSender.hpp	2008-09-10 00:32:18 +0000
@@ -44,6 +44,7 @@
 class SignalSender {
 public:
   SignalSender(TransporterFacade *facade, int blockNo = -1);
+  SignalSender(Ndb_cluster_connection* connection);
   virtual ~SignalSender();
   
   int lock();

=== modified file 'storage/ndb/src/ndbapi/TransporterFacade.cpp'
--- a/storage/ndb/src/ndbapi/TransporterFacade.cpp	2008-08-28 10:52:49 +0000
+++ b/storage/ndb/src/ndbapi/TransporterFacade.cpp	2008-09-10 00:32:18 +0000
@@ -1983,6 +1983,7 @@
   return NULL;
 }
 
+#ifdef UNIT_TEST
 
 // Unit test code starts
 #include <random.h>
@@ -2214,9 +2215,6 @@
   return 0;
 }
 
-//#define WANT_TESTSECTIONITERATORS 1
-
-#ifdef WANT_TESTSECTIONITERATORS
 int main(int arg, char** argv)
 {
   /* Test Section Iterators

=== modified file 'storage/ndb/src/ndbapi/ndb_cluster_connection_impl.hpp'
--- a/storage/ndb/src/ndbapi/ndb_cluster_connection_impl.hpp	2007-04-12 05:49:09 +0000
+++ b/storage/ndb/src/ndbapi/ndb_cluster_connection_impl.hpp	2008-09-10 00:32:18 +0000
@@ -55,6 +55,7 @@
   friend void* run_ndb_cluster_connection_connect_thread(void*);
   friend class Ndb_cluster_connection;
   friend class NdbEventBuffer;
+  friend class SignalSender;
   
   struct Node
   {


