List:Commits« Previous MessageNext Message »
From:knielsen Date:September 24 2007 5:09pm
Subject:bk commit into 5.1 tree (knielsen:1.2609)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of knielsen. When knielsen does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2007-09-24 17:09:29+02:00, knielsen@ymer.(none) +25 -0
  Long signal refactoring.

  storage/ndb/include/debugger/SignalLoggerManager.hpp@stripped, 2007-09-24 17:09:25+02:00, knielsen@ymer.(none) +19 -2
    Long signal refactoring.

  storage/ndb/src/kernel/blocks/backup/Backup.cpp@stripped, 2007-09-24 17:09:25+02:00, knielsen@ymer.(none) +5 -4
    Long signal refactoring.

  storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp@stripped, 2007-09-24 17:09:25+02:00, knielsen@ymer.(none) +25 -15
    Long signal refactoring.

  storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp@stripped, 2007-09-24 17:09:25+02:00, knielsen@ymer.(none) +532 -500
    Long signal refactoring.

  storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp@stripped, 2007-09-24 17:09:26+02:00, knielsen@ymer.(none) +4 -2
    Long signal refactoring.

  storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp@stripped, 2007-09-24 17:09:26+02:00, knielsen@ymer.(none) +3 -4
    Long signal refactoring.

  storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp@stripped, 2007-09-24 17:09:26+02:00, knielsen@ymer.(none) +35 -32
    Long signal refactoring.

  storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp@stripped, 2007-09-24 17:09:26+02:00, knielsen@ymer.(none) +8 -9
    Long signal refactoring.

  storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp@stripped, 2007-09-24 17:09:26+02:00, knielsen@ymer.(none) +3 -2
    Long signal refactoring.

  storage/ndb/src/kernel/blocks/dbutil/DbUtil.cpp@stripped, 2007-09-24 17:09:26+02:00, knielsen@ymer.(none) +18 -23
    Long signal refactoring.

  storage/ndb/src/kernel/blocks/dbutil/DbUtil.hpp@stripped, 2007-09-24 17:09:26+02:00, knielsen@ymer.(none) +1 -1
    Long signal refactoring.

  storage/ndb/src/kernel/blocks/lgman.cpp@stripped, 2007-09-24 17:09:25+02:00, knielsen@ymer.(none) +17 -9
    Long signal refactoring.

  storage/ndb/src/kernel/blocks/lgman.hpp@stripped, 2007-09-24 17:09:25+02:00, knielsen@ymer.(none) +1 -1
    Long signal refactoring.

  storage/ndb/src/kernel/blocks/ndbfs/AsyncFile.cpp@stripped, 2007-09-24 17:09:26+02:00, knielsen@ymer.(none) +3 -2
    Long signal refactoring.

  storage/ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp@stripped, 2007-09-24 17:09:26+02:00, knielsen@ymer.(none) +3 -2
    Long signal refactoring.

  storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp@stripped, 2007-09-24 17:09:26+02:00, knielsen@ymer.(none) +3 -1
    Long signal refactoring.

  storage/ndb/src/kernel/blocks/suma/Suma.cpp@stripped, 2007-09-24 17:09:26+02:00, knielsen@ymer.(none) +19 -18
    Long signal refactoring.

  storage/ndb/src/kernel/blocks/trix/Trix.cpp@stripped, 2007-09-24 17:09:26+02:00, knielsen@ymer.(none) +13 -12
    Long signal refactoring.

  storage/ndb/src/kernel/blocks/tsman.cpp@stripped, 2007-09-24 17:09:25+02:00, knielsen@ymer.(none) +20 -8
    Long signal refactoring.

  storage/ndb/src/kernel/blocks/tsman.hpp@stripped, 2007-09-24 17:09:25+02:00, knielsen@ymer.(none) +2 -1
    Long signal refactoring.

  storage/ndb/src/kernel/vm/FastScheduler.cpp@stripped, 2007-09-24 17:09:26+02:00, knielsen@ymer.(none) +11 -32
    Long signal refactoring.

  storage/ndb/src/kernel/vm/FastScheduler.hpp@stripped, 2007-09-24 17:09:26+02:00, knielsen@ymer.(none) +1 -5
    Long signal refactoring.

  storage/ndb/src/kernel/vm/SimulatedBlock.cpp@stripped, 2007-09-24 17:09:26+02:00, knielsen@ymer.(none) +405 -118
    Long signal refactoring.

  storage/ndb/src/kernel/vm/SimulatedBlock.hpp@stripped, 2007-09-24 17:09:26+02:00, knielsen@ymer.(none) +49 -6
    Long signal refactoring.

  storage/ndb/src/kernel/vm/VMSignal.hpp@stripped, 2007-09-24 17:09:26+02:00, knielsen@ymer.(none) +67 -25
    Long signal refactoring.

diff -Nrup a/storage/ndb/include/debugger/SignalLoggerManager.hpp b/storage/ndb/include/debugger/SignalLoggerManager.hpp
--- a/storage/ndb/include/debugger/SignalLoggerManager.hpp	2006-12-23 20:20:02 +01:00
+++ b/storage/ndb/include/debugger/SignalLoggerManager.hpp	2007-09-24 17:09:25 +02:00
@@ -56,6 +56,11 @@ public:
   /**
    * For input signals
    */
+  void executeSignal(const SignalHeader& sh, Uint8 prio,
+		     const Uint32 * theData, Uint32 node) {
+    executeSignal(sh, prio, theData, node, (LinearSectionPtr*)0, 0);
+  }
+
   void executeSignal(const SignalHeader&, Uint8 prio,
                      const Uint32 * theData, Uint32 node,
                      const SegmentedSectionPtr ptr[3], Uint32 secs);
@@ -67,7 +72,12 @@ public:
   /**
    * For output signals
    */
-  void sendSignal(const SignalHeader&, Uint8 prio, 
+  void sendSignal(const SignalHeader& sh, Uint8 prio,
+		  const Uint32 * theData, Uint32 node) {
+    sendSignal(sh, prio, theData, node, (LinearSectionPtr*)0, 0);
+  }
+
+  void sendSignal(const SignalHeader&, Uint8 prio,
 		  const Uint32 * theData, Uint32 node,
                   const SegmentedSectionPtr ptr[3], Uint32 secs);
 
@@ -79,7 +89,14 @@ public:
    * For output signals
    */
   void sendSignalWithDelay(Uint32 delayInMilliSeconds, 
-			   const SignalHeader&, 
+			   const SignalHeader& sh,
+			   Uint8 prio, const Uint32 * data, Uint32 node){
+    sendSignalWithDelay(delayInMilliSeconds, sh, prio, data, node,
+			(SegmentedSectionPtr*)0, 0);
+  }
+
+  void sendSignalWithDelay(Uint32 delayInMilliSeconds,
+			   const SignalHeader&,
 			   Uint8 prio, const Uint32 * data, Uint32 node,
                            const SegmentedSectionPtr ptr[3], Uint32 secs);
   
diff -Nrup a/storage/ndb/src/kernel/blocks/backup/Backup.cpp b/storage/ndb/src/kernel/blocks/backup/Backup.cpp
--- a/storage/ndb/src/kernel/blocks/backup/Backup.cpp	2007-06-12 10:55:16 +02:00
+++ b/storage/ndb/src/kernel/blocks/backup/Backup.cpp	2007-09-24 17:09:25 +02:00
@@ -3163,9 +3163,10 @@ Backup::execGET_TABINFO_CONF(Signal* sig
 
   BackupRecordPtr ptr LINT_SET_PTR;
   c_backupPool.getPtr(ptr, senderData);
-  
+
+  SectionHandle handle(this, signal);
   SegmentedSectionPtr dictTabInfoPtr;
-  signal->getSection(dictTabInfoPtr, GetTabInfoConf::DICT_TAB_INFO);
+  handle.getSection(dictTabInfoPtr, GetTabInfoConf::DICT_TAB_INFO);
   ndbrequire(dictTabInfoPtr.sz == len);
 
   TablePtr tabPtr ;
@@ -3181,7 +3182,7 @@ Backup::execGET_TABINFO_CONF(Signal* sig
       jam();
       ndbrequire(false);
       ptr.p->setErrorCode(DefineBackupRef::FailedAllocateTableMem);
-      releaseSections(signal);
+      releaseSections(handle);
       defineBackupRef(signal, ptr);
       return;
     }//if
@@ -3200,7 +3201,7 @@ Backup::execGET_TABINFO_CONF(Signal* sig
     }//if
   }
 
-  releaseSections(signal);
+  releaseSections(handle);
 
   if(ptr.p->checkError()) {
     jam();
diff -Nrup a/storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp b/storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp
--- a/storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp	2007-07-02 18:26:39 +02:00
+++ b/storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp	2007-09-24 17:09:25 +02:00
@@ -1214,6 +1214,8 @@ Cmvmi::execTESTSIG(Signal* signal){
   g_print = signal->theData[3];
 //  Uint32 returnCount = signal->theData[4];
   Uint32 * secSizes = &signal->theData[5];
+
+  SectionHandle handle(this, signal);
   
   if(g_print){
     SignalLoggerManager::printSignalHeader(stdout, 
@@ -1229,10 +1231,10 @@ Cmvmi::execTESTSIG(Signal* signal){
     }
     fprintf(stdout, "\n");
     
-    for(i = 0; i<signal->header.m_noOfSections; i++){
+    for(i = 0; i<handle.m_cnt; i++){
       SegmentedSectionPtr ptr(0,0,0);
       ndbout_c("-- Section %d --", i);
-      signal->getSection(ptr, i);
+      handle.getSection(ptr, i);
       ndbrequire(ptr.p != 0);
       print(ptr, stdout);
       ndbrequire(ptr.sz == secSizes[i]);
@@ -1242,9 +1244,9 @@ Cmvmi::execTESTSIG(Signal* signal){
   /**
    * Validate length:s
    */
-  for(i = 0; i<signal->header.m_noOfSections; i++){
+  for(i = 0; i<handle.m_cnt; i++){
     SegmentedSectionPtr ptr;
-    signal->getSection(ptr, i);
+    handle.getSection(ptr, i);
     ndbrequire(ptr.p != 0);
     ndbrequire(ptr.sz == secSizes[i]);
   }
@@ -1254,7 +1256,7 @@ Cmvmi::execTESTSIG(Signal* signal){
    */
   if (testType == 20) {
     if (signal->theData[4] == 0) {
-      releaseSections(signal);
+      releaseSections(handle);
       return;
     }
     signal->theData[4]--;
@@ -1278,31 +1280,34 @@ Cmvmi::execTESTSIG(Signal* signal){
   
   switch(testType){
   case 1:
-    sendSignal(ref, GSN_TESTSIG,  signal, signal->length(), JBB);      
+    sendSignal(ref, GSN_TESTSIG,  signal, signal->length(), JBB,
+	       &handle);
     break;
   case 2:
-    sendSignal(rg, GSN_TESTSIG,  signal, signal->length(), JBB);
+    sendSignal(rg, GSN_TESTSIG,  signal, signal->length(), JBB,
+	       &handle);
     break;
   case 3:
   case 4:{
     LinearSectionPtr ptr[3];
-    const Uint32 secs = signal->getNoOfSections();
+    const Uint32 secs = handle.m_cnt;
     for(i = 0; i<secs; i++){
       SegmentedSectionPtr sptr(0,0,0);
-      signal->getSection(sptr, i);
+      handle.getSection(sptr, i);
       ptr[i].sz = sptr.sz;
       ptr[i].p = new Uint32[sptr.sz];
       copy(ptr[i].p, sptr);
     }
     
     if(testType == 3){
-      sendSignal(ref, GSN_TESTSIG,  signal, signal->length(), JBB, ptr, secs); 
+      sendSignal(ref, GSN_TESTSIG, signal, signal->length(), JBB, ptr, secs);
     } else {
-      sendSignal(rg, GSN_TESTSIG,  signal, signal->length(), JBB, ptr, secs); 
+      sendSignal(rg, GSN_TESTSIG, signal, signal->length(), JBB, ptr, secs);
     }
     for(Uint32 i = 0; i<secs; i++){
       delete[] ptr[i].p;
     }
+    releaseSections(handle);
     break;
   }
   case 5:
@@ -1322,7 +1327,9 @@ Cmvmi::execTESTSIG(Signal* signal){
 		      signal,
 		      signal->length(),
 		      JBB,
+		      &handle,
 		      fragmentLength);
+
     int count = 1;
     while(fragSend.m_status != FragmentSendInfo::SendComplete){
       count++;
@@ -1335,10 +1342,10 @@ Cmvmi::execTESTSIG(Signal* signal){
   case 7:
   case 8:{
     LinearSectionPtr ptr[3];
-    const Uint32 secs = signal->getNoOfSections();
+    const Uint32 secs = handle.m_cnt;
     for(i = 0; i<secs; i++){
       SegmentedSectionPtr sptr(0,0,0);
-      signal->getSection(sptr, i);
+      handle.getSection(sptr, i);
       ptr[i].sz = sptr.sz;
       ptr[i].p = new Uint32[sptr.sz];
       copy(ptr[i].p, sptr);
@@ -1373,6 +1380,7 @@ Cmvmi::execTESTSIG(Signal* signal){
     for(i = 0; i<secs; i++){
       delete[] ptr[i].p;
     }
+    releaseSections(handle);
     break;
   }
   case 9:
@@ -1386,12 +1394,14 @@ Cmvmi::execTESTSIG(Signal* signal){
       m_callBack.m_callbackData = 9;
       sendFragmentedSignal(ref,
 			   GSN_TESTSIG, signal, signal->length(), JBB, 
+			   &handle,
 			   m_callBack,
 			   fragmentLength);
     } else {
       m_callBack.m_callbackData = 10;
       sendFragmentedSignal(rg,
 			   GSN_TESTSIG, signal, signal->length(), JBB, 
+			   &handle,
 			   m_callBack,
 			   fragmentLength);
     }
@@ -1400,11 +1410,11 @@ Cmvmi::execTESTSIG(Signal* signal){
   case 11:
   case 12:{
 
-    const Uint32 secs = signal->getNoOfSections();
+    const Uint32 secs = handle.m_cnt;
     memset(g_test, 0, sizeof(g_test));
     for(i = 0; i<secs; i++){
       SegmentedSectionPtr sptr(0,0,0);
-      signal->getSection(sptr, i);
+      handle.getSection(sptr, i);
       g_test[i].sz = sptr.sz;
       g_test[i].p = new Uint32[sptr.sz];
       copy(g_test[i].p, sptr);
diff -Nrup a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
--- a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp	2007-09-14 08:04:47 +02:00
+++ b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp	2007-09-24 17:09:25 +02:00
@@ -2589,14 +2589,15 @@ void Dbdict::execSCHEMA_INFO(Signal* sig
     CRASH_INSERTION(6001);
   }
 
+  SectionHandle handle(this, signal);
   SegmentedSectionPtr schemaDataPtr;
-  signal->getSection(schemaDataPtr, 0);
+  handle.getSection(schemaDataPtr, 0);
 
   XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
   ndbrequire(schemaDataPtr.sz % NDB_SF_PAGE_SIZE_IN_WORDS == 0);
   xsf->noOfPages = schemaDataPtr.sz / NDB_SF_PAGE_SIZE_IN_WORDS;
   copy((Uint32*)&xsf->schemaPage[0], schemaDataPtr);
-  releaseSections(signal);
+  releaseSections(handle);
   
   SchemaFile * sf0 = &xsf->schemaPage[0];
   if (sf0->NdbVersion < NDB_SF_VERSION_5_0_6) {
@@ -3108,8 +3109,9 @@ Dbdict::execGET_TABINFO_CONF(Signal* sig
   const Uint32 tableId = conf->tableId;
   const Uint32 senderData = conf->senderData;
 
+  SectionHandle handle(this, signal);
   SegmentedSectionPtr tabInfoPtr;
-  signal->getSection(tabInfoPtr, GetTabInfoConf::DICT_TAB_INFO);
+  handle.getSection(tabInfoPtr, GetTabInfoConf::DICT_TAB_INFO);
 
   CreateTableRecordPtr createTabPtr;  
   ndbrequire(c_opCreateTable.find(createTabPtr, senderData));
@@ -3139,10 +3141,9 @@ Dbdict::execGET_TABINFO_CONF(Signal* sig
   callback.m_callbackFunction = 
     safe_cast(&Dbdict::restartCreateTab_writeTableConf);
   
-  signal->header.m_noOfSections = 0;
   writeTableFile(signal, createTabPtr.p->m_tablePtrI, tabInfoPtr, &callback);
-  signal->setSection(tabInfoPtr, 0);
-  releaseSections(signal);
+
+  releaseSections(handle);
 }
 
 void
@@ -3216,10 +3217,8 @@ Dbdict::releaseCreateTableOp(Signal* sig
   if (createTabPtr.p->m_tabInfoPtrI != RNIL)
   {
     jam();
-    SegmentedSectionPtr tabInfoPtr;
-    getSection(tabInfoPtr, createTabPtr.p->m_tabInfoPtrI);
-    signal->setSection(tabInfoPtr, 0);
-    releaseSections(signal);
+    SectionHandle handle(this, createTabPtr.p->m_tabInfoPtrI);
+    releaseSections(handle);
   }
   c_opCreateTable.release(createTabPtr);
 }
@@ -3371,16 +3370,17 @@ Dbdict::restartCreateObj_getTabInfoConf(
 
   const Uint32 objId = conf->tableId;
   const Uint32 senderData = conf->senderData;
-  
+
+  SectionHandle handle(this, signal);
   SegmentedSectionPtr objInfoPtr;
-  signal->getSection(objInfoPtr, GetTabInfoConf::DICT_TAB_INFO);
-  
+  handle.getSection(objInfoPtr, GetTabInfoConf::DICT_TAB_INFO);
+  handle.clear();
+
   CreateObjRecordPtr createObjPtr;  
   ndbrequire(c_opCreateObj.find(createObjPtr, senderData));
   ndbrequire(createObjPtr.p->m_obj_id == objId);
   
   createObjPtr.p->m_obj_info_ptr_i= objInfoPtr.i;
-  signal->header.m_noOfSections = 0;
   
   (this->*f_dict_op[createObjPtr.p->m_vt_index].m_prepare_start)
     (signal, createObjPtr.p);
@@ -3445,10 +3445,8 @@ Dbdict::restartCreateObj_write_complete(
   ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
   ndbrequire(createObjPtr.p->m_errorCode == 0);
   
-  SegmentedSectionPtr objInfoPtr;
-  getSection(objInfoPtr, createObjPtr.p->m_obj_info_ptr_i);
-  signal->setSection(objInfoPtr, 0);
-  releaseSections(signal);
+  SectionHandle handle(this, createObjPtr.p->m_obj_info_ptr_i);
+  releaseSections(handle);
   createObjPtr.p->m_obj_info_ptr_i = RNIL;
   
   createObjPtr.p->m_callback.m_callbackFunction = 
@@ -3852,6 +3850,8 @@ Dbdict::execCREATE_TABLE_REQ(Signal* sig
   if(!assembleFragments(signal)){
     return;
   }
+
+  SectionHandle handle(this, signal);
   
   CreateTableReq* const req = (CreateTableReq*)signal->getDataPtr();
   const Uint32 senderRef = req->senderRef;
@@ -3897,11 +3897,11 @@ Dbdict::execCREATE_TABLE_REQ(Signal* sig
     parseRecord.errorCode = 0;
     
     SegmentedSectionPtr ptr;
-    signal->getSection(ptr, CreateTableReq::DICT_TAB_INFO);
+    handle.getSection(ptr, CreateTableReq::DICT_TAB_INFO);
     SimplePropertiesSectionReader r(ptr, getSectionSegmentPool());
     
     handleTabInfoInit(r, &parseRecord);
-    releaseSections(signal);
+    releaseSections(handle);
     
     if(parseRecord.errorCode != 0){
       jam();
@@ -3977,7 +3977,8 @@ Dbdict::execCREATE_TABLE_REQ(Signal* sig
    * Something went wrong
    */
 
-  releaseSections(signal);
+  releaseSections(handle);
+
   CreateTableRef * ref = (CreateTableRef*)signal->getDataPtrSend();
   ref->senderData = senderData;
   ref->senderRef = reference();
@@ -4034,150 +4035,180 @@ Dbdict::execALTER_TABLE_REQ(Signal* sign
   if(!assembleFragments(signal)){
     return;
   }
+
+  SectionHandle handle(this, signal);
+
   AlterTableReq* const req = (AlterTableReq*)signal->getDataPtr();
   const Uint32 senderRef = req->senderRef;
   const Uint32 senderData = req->senderData;
   const Uint32 changeMask = req->changeMask;
   const Uint32 tableId = req->tableId;
   const Uint32 tableVersion = req->tableVersion;
-  ParseDictTabInfoRecord* aParseRecord;
-  
+
+  ParseDictTabInfoRecord aParseRecord;
+  aParseRecord.errorCode = 0;
+
   // Get table definition
   TableRecordPtr tablePtr;
   c_tableRecordPool.getPtr(tablePtr, tableId, false);
-  if(tablePtr.isNull()){
-    jam();
-    alterTableRef(signal, req, AlterTableRef::NoSuchTable);
-    return;
-  }
-  
-  if(getOwnNodeId() != c_masterNodeId){
-    jam();
-    alterTableRef(signal, req, AlterTableRef::NotMaster);
-    return;
-  }
+
+  do {
+    if(tablePtr.isNull())
+    {
+      jam();
+      aParseRecord.errorCode = AlterTableRef::NoSuchTable;
+      break;
+    }
   
-  if(c_blockState == BS_NODE_RESTART){
-    jam();
-    alterTableRef(signal, req, AlterTableRef::BusyWithNR);
-    return;
-  }
+    if(getOwnNodeId() != c_masterNodeId)
+    {
+      jam();
+      aParseRecord.errorCode = AlterTableRef::NotMaster;
+      break;
+    }
   
-  if(c_blockState != BS_IDLE){
-    jam();
-    alterTableRef(signal, req, AlterTableRef::Busy);
-    return;
-  }
+    if(c_blockState == BS_NODE_RESTART)
+    {
+      jam();
+      aParseRecord.errorCode = AlterTableRef::BusyWithNR;
+      break;
+    }
 
-  if (!check_ndb_versions())
-  {
-    jam();
-    alterTableRef(signal, req, AlterTableRef::IncompatibleVersions);
-    return;
-  }
-  
-  if (checkSingleUserMode(signal->getSendersBlockRef()))
-  {
-    jam();
-    alterTableRef(signal, req, AlterTableRef::SingleUser);
-    return;
-  }
+    if(c_blockState != BS_IDLE)
+    {
+      jam();
+      aParseRecord.errorCode = AlterTableRef::Busy;
+      break;
+    }
 
-  const TableRecord::TabState tabState = tablePtr.p->tabState;
-  bool ok = false;
-  switch(tabState){
-  case TableRecord::NOT_DEFINED:
-  case TableRecord::REORG_TABLE_PREPARED:
-  case TableRecord::DEFINING:
-  case TableRecord::CHECKED:
-    jam();
-    alterTableRef(signal, req, AlterTableRef::NoSuchTable);
-    return;
-  case TableRecord::DEFINED:
-    ok = true;
-    jam();
-    break;
-  case TableRecord::BACKUP_ONGOING:
-    jam();
-    alterTableRef(signal, req, AlterTableRef::BackupInProgress);
-    return;
-  case TableRecord::PREPARE_DROPPING:
-  case TableRecord::DROPPING:
-    jam();
-    alterTableRef(signal, req, AlterTableRef::DropInProgress);
-    return;
-  }
-  ndbrequire(ok);
+    if (!check_ndb_versions())
+    {
+      jam();
+      aParseRecord.errorCode = AlterTableRef::IncompatibleVersions;
+      break;
+    }
 
-  if(tablePtr.p->tableVersion != tableVersion){
-    jam();
-    alterTableRef(signal, req, AlterTableRef::InvalidTableVersion);
-    return;
-  }
-  // Parse new table defintion
-  ParseDictTabInfoRecord parseRecord;
-  aParseRecord = &parseRecord;
+    if (checkSingleUserMode(signal->getSendersBlockRef()))
+    {
+      jam();
+      aParseRecord.errorCode = AlterTableRef::SingleUser;
+      break;
+    }
+
+    const TableRecord::TabState tabState = tablePtr.p->tabState;
+    bool ok = false;
+    switch(tabState){
+    case TableRecord::NOT_DEFINED:
+    case TableRecord::REORG_TABLE_PREPARED:
+    case TableRecord::DEFINING:
+    case TableRecord::CHECKED:
+      jam();
+      aParseRecord.errorCode = AlterTableRef::NoSuchTable;
+      break;
+    case TableRecord::DEFINED:
+      ok = true;
+      jam();
+      break;
+    case TableRecord::BACKUP_ONGOING:
+      jam();
+      aParseRecord.errorCode = AlterTableRef::BackupInProgress;
+      break;
+    case TableRecord::PREPARE_DROPPING:
+    case TableRecord::DROPPING:
+      jam();
+      aParseRecord.errorCode = AlterTableRef::DropInProgress;
+      break;
+    }
+    if (aParseRecord.errorCode)
+    {
+      jam();
+      break;
+    }
+
+    ndbrequire(ok);
+
+    if(tablePtr.p->tableVersion != tableVersion)
+    {
+      jam();
+      aParseRecord.errorCode = AlterTableRef::InvalidTableVersion;
+      break;
+    }
+
+    CreateTableRecordPtr alterTabPtr; // Reuse create table records
+    c_opCreateTable.seize(alterTabPtr);
     
-  CreateTableRecordPtr alterTabPtr; // Reuse create table records
-  c_opCreateTable.seize(alterTabPtr);
-  
-  if(alterTabPtr.isNull()){
-    jam();
-    alterTableRef(signal, req, AlterTableRef::Busy);
-    return;
-  }
+    if(alterTabPtr.isNull())
+    {
+      jam();
+      aParseRecord.errorCode = AlterTableRef::Busy;
+      break;
+    }
 
-  alterTabPtr.p->m_changeMask = changeMask;
-  parseRecord.requestType = DictTabInfo::AlterTableFromAPI;
-  parseRecord.errorCode = 0;
+    alterTabPtr.p->m_changeMask = changeMask;
+    aParseRecord.requestType = DictTabInfo::AlterTableFromAPI;
   
-  SegmentedSectionPtr ptr;
-  signal->getSection(ptr, AlterTableReq::DICT_TAB_INFO);
-  SimplePropertiesSectionReader r(ptr, getSectionSegmentPool());
+    SegmentedSectionPtr ptr;
+    handle.getSection(ptr, AlterTableReq::DICT_TAB_INFO);
+    SimplePropertiesSectionReader r(ptr, getSectionSegmentPool());
 
-  handleTabInfoInit(r, &parseRecord, false); // Will not save info
+    handleTabInfoInit(r, &aParseRecord, false); // Will not save info
   
-  if(parseRecord.errorCode != 0){
-    jam();
-    c_opCreateTable.release(alterTabPtr);
-    alterTableRef(signal, req, 
-		  (AlterTableRef::ErrorCode) parseRecord.errorCode, 
-		  aParseRecord);
-    return;
-  }
+    if(aParseRecord.errorCode != 0)
+    {
+      jam();
+      c_opCreateTable.release(alterTabPtr);
+      break;
+    }
   
-  releaseSections(signal);
-  alterTabPtr.p->key = ++c_opRecordSequence;
-  c_opCreateTable.add(alterTabPtr);
-  ndbrequire(c_opCreateTable.find(alterTabPtr, alterTabPtr.p->key));
-  alterTabPtr.p->m_errorCode = 0;
-  alterTabPtr.p->m_senderRef = senderRef;
-  alterTabPtr.p->m_senderData = senderData;
-  alterTabPtr.p->m_tablePtrI = parseRecord.tablePtr.i;
-  alterTabPtr.p->m_alterTableFailed = false;
-  alterTabPtr.p->m_coordinatorRef = reference();
-  alterTabPtr.p->m_tupAlterTabPtr= RNIL;
-  alterTabPtr.p->m_fragmentsPtrI = RNIL;
-  alterTabPtr.p->m_dihAddFragPtr = RNIL;
-  alterTabPtr.p->m_alterTableId = tablePtr.p->tableId;
+    releaseSections(handle);
 
-  // Send prepare request to all alive nodes
-  SimplePropertiesSectionWriter w(getSectionSegmentPool());
-  packTableIntoPages(w, parseRecord.tablePtr);
-  
-  SegmentedSectionPtr tabInfoPtr;
-  w.getPtr(tabInfoPtr);
-  
-  alterTabPtr.p->m_tabInfoPtrI = tabInfoPtr.i;
+    alterTabPtr.p->key = ++c_opRecordSequence;
+    c_opCreateTable.add(alterTabPtr);
+    ndbrequire(c_opCreateTable.find(alterTabPtr, alterTabPtr.p->key));
+    alterTabPtr.p->m_errorCode = 0;
+    alterTabPtr.p->m_senderRef = senderRef;
+    alterTabPtr.p->m_senderData = senderData;
+    alterTabPtr.p->m_tablePtrI = aParseRecord.tablePtr.i;
+    alterTabPtr.p->m_alterTableFailed = false;
+    alterTabPtr.p->m_coordinatorRef = reference();
+    alterTabPtr.p->m_tupAlterTabPtr= RNIL;
+    alterTabPtr.p->m_fragmentsPtrI = RNIL;
+    alterTabPtr.p->m_dihAddFragPtr = RNIL;
+    alterTabPtr.p->m_alterTableId = tablePtr.p->tableId;
+
+    // Send prepare request to all alive nodes
+    SimplePropertiesSectionWriter w(getSectionSegmentPool());
+    packTableIntoPages(w, aParseRecord.tablePtr);
 
-  // Alter table on all nodes
-  c_blockState = BS_BUSY;
+    SegmentedSectionPtr tabInfoPtr;
+    w.getPtr(tabInfoPtr);
 
-  Mutex mutex(signal, c_mutexMgr, alterTabPtr.p->m_startLcpMutex);
-  Callback c = { safe_cast(&Dbdict::alterTable_backup_mutex_locked),
-		 alterTabPtr.p->key };
-  
-  ndbrequire(mutex.lock(c));
+    alterTabPtr.p->m_tabInfoPtrI = tabInfoPtr.i;
+
+    // Alter table on all nodes
+    c_blockState = BS_BUSY;
+
+    Mutex mutex(signal, c_mutexMgr, alterTabPtr.p->m_startLcpMutex);
+    Callback c = { safe_cast(&Dbdict::alterTable_backup_mutex_locked),
+		   alterTabPtr.p->key };
+
+    ndbrequire(mutex.lock(c));
+    return;
+
+  } while (0);
+
+  releaseSections(handle);
+
+  AlterTableRef * ref = (AlterTableRef*)signal->getDataPtrSend();
+  ref->senderData = senderData;
+  ref->senderRef = reference();
+  ref->masterNodeId = c_masterNodeId;
+  ref->errorCode = aParseRecord.errorCode;
+  ref->errorLine = aParseRecord.errorLine;
+  ref->errorKey = aParseRecord.errorKey;
+  ref->status = aParseRecord.status;
+  sendSignal(senderRef, GSN_ALTER_TABLE_REF, signal,
+	     AlterTableRef::SignalLength, JBB);
 }
 
 void
@@ -4198,25 +4229,30 @@ Dbdict::alterTable_backup_mutex_locked(S
   Mutex mutex(signal, c_mutexMgr, alterTabPtr.p->m_startLcpMutex);
   mutex.unlock(); // ignore response
 
-  SegmentedSectionPtr tabInfoPtr;
-  getSection(tabInfoPtr, alterTabPtr.p->m_tabInfoPtrI);
-  signal->setSection(tabInfoPtr, AlterTabReq::DICT_TAB_INFO);
-  
+  SectionHandle handle(this, alterTabPtr.p->m_tabInfoPtrI);
   alterTabPtr.p->m_tabInfoPtrI = RNIL;
   
   if(tablePtr.p->tabState == TableRecord::BACKUP_ONGOING)
   {
     jam();
-    AlterTableReq* req = (AlterTableReq*)signal->getDataPtr();
-    req->senderData = alterTabPtr.p->m_senderData;
-    req->senderRef = alterTabPtr.p->m_senderRef;
-    alterTableRef(signal, req, AlterTableRef::BackupInProgress);
+
+    AlterTableRef * ref = (AlterTableRef*)signal->getDataPtrSend();
+    ref->senderData = alterTabPtr.p->m_senderData;
+    ref->senderRef = reference();
+    ref->masterNodeId = c_masterNodeId;
+    ref->errorCode = AlterTableRef::BackupInProgress;
+    ref->errorLine = __LINE__;
+    ref->errorKey = 0;
+    ref->status = 0;
+    sendSignal(alterTabPtr.p->m_senderRef, GSN_ALTER_TABLE_REF, signal,
+	       AlterTableRef::SignalLength, JBB);
 
     c_tableRecordPool.getPtr(tablePtr, alterTabPtr.p->m_tablePtrI);  
     releaseTableObject(tablePtr.i, false);
 
     c_opCreateTable.release(alterTabPtr);
     c_blockState = BS_IDLE;
+    releaseSections(handle);
     return;
   }
   
@@ -4238,35 +4274,8 @@ Dbdict::alterTable_backup_mutex_locked(S
   lreq->requestType = AlterTabReq::AlterTablePrepare;
   
   sendFragmentedSignal(rg, GSN_ALTER_TAB_REQ, signal, 
-		       AlterTabReq::SignalLength, JBB);
-}
-
-void Dbdict::alterTableRef(Signal * signal, 
-			   AlterTableReq * req, 
-			   AlterTableRef::ErrorCode errCode,
-			   ParseDictTabInfoRecord* parseRecord)
-{
-  jam();
-  releaseSections(signal);
-  AlterTableRef * ref = (AlterTableRef*)signal->getDataPtrSend();
-  Uint32 senderRef = req->senderRef;
-  ref->senderData = req->senderData;
-  ref->senderRef = reference();
-  ref->masterNodeId = c_masterNodeId;
-  if (parseRecord) {
-    ref->errorCode = parseRecord->errorCode;
-    ref->errorLine = parseRecord->errorLine;
-    ref->errorKey = parseRecord->errorKey;
-    ref->status = parseRecord->status;
-  }
-  else {
-    ref->errorCode = errCode;
-    ref->errorLine = 0;
-    ref->errorKey = 0;
-    ref->status = 0;
-  }
-  sendSignal(senderRef, GSN_ALTER_TABLE_REF, signal, 
-	     AlterTableRef::SignalLength, JBB);
+		       AlterTabReq::SignalLength, JBB,
+		       &handle);
 }
 
 void
@@ -4288,8 +4297,9 @@ Dbdict::execALTER_TAB_REQ(Signal * signa
   AlterTabReq::RequestType requestType = 
     (AlterTabReq::RequestType) req->requestType;
 
+  SectionHandle handle(this, signal);
   SegmentedSectionPtr tabInfoPtr;
-  signal->getSection(tabInfoPtr, AlterTabReq::DICT_TAB_INFO);
+  handle.getSection(tabInfoPtr, AlterTabReq::DICT_TAB_INFO);
 
   CreateTableRecordPtr alterTabPtr; // Reuse create table records
 
@@ -4308,241 +4318,236 @@ Dbdict::execALTER_TAB_REQ(Signal * signa
     jam();
     ndbrequire(c_opCreateTable.find(alterTabPtr, senderData));
   }
-  if(alterTabPtr.isNull()){
-    jam();
-    alterTabRef(signal, req, AlterTableRef::Busy);
-    return;
-  }
 
-  if (!check_ndb_versions())
+  ParseDictTabInfoRecord parseRecord;
+  parseRecord.errorCode = 0;
+  do
   {
-    jam();
-    alterTabRef(signal, req, AlterTableRef::IncompatibleVersions);
-    return;
-  }
-
-  alterTabPtr.p->m_alterTableId = tableId;
-  alterTabPtr.p->m_coordinatorRef = senderRef;
-  
-  // Get table definition
-  TableRecordPtr tablePtr;
-  c_tableRecordPool.getPtr(tablePtr, tableId, false);
-  if(tablePtr.isNull()){
-    jam();
-    alterTabRef(signal, req, AlterTableRef::NoSuchTable);
-    return;
-  }
-    
-  switch(requestType) {
-  case(AlterTabReq::AlterTablePrepare): {
-    ParseDictTabInfoRecord* aParseRecord;
-  
-    const TableRecord::TabState tabState = tablePtr.p->tabState;
-    bool ok = false;
-    switch(tabState){
-    case TableRecord::NOT_DEFINED:
-    case TableRecord::REORG_TABLE_PREPARED:
-    case TableRecord::DEFINING:
-    case TableRecord::CHECKED:
-      jam();
-      alterTabRef(signal, req, AlterTableRef::NoSuchTable);
-      return;
-    case TableRecord::DEFINED:
-      ok = true;
+    if(alterTabPtr.isNull())
+    {
       jam();
+      parseRecord.errorCode = AlterTableRef::Busy;
       break;
-    case TableRecord::PREPARE_DROPPING:
-    case TableRecord::DROPPING:
-      jam();
-      alterTabRef(signal, req, AlterTableRef::DropInProgress);
-      return;
-    case TableRecord::BACKUP_ONGOING:
-      jam();
-      alterTabRef(signal, req, AlterTableRef::BackupInProgress);
-      return;
     }
-    ndbrequire(ok);
 
-    if(alter_obj_inc_schema_version(tablePtr.p->tableVersion) != tableVersion){
+    if (!check_ndb_versions())
+    {
       jam();
-      alterTabRef(signal, req, AlterTableRef::InvalidTableVersion);
-      return;
+      parseRecord.errorCode = AlterTableRef::IncompatibleVersions;
+      break;
     }
-    TableRecordPtr newTablePtr;
-    if (senderRef  != reference()) {
+
+    alterTabPtr.p->m_alterTableId = tableId;
+    alterTabPtr.p->m_coordinatorRef = senderRef;
+
+    // Get table definition
+    TableRecordPtr tablePtr;
+    c_tableRecordPool.getPtr(tablePtr, tableId, false);
+    if(tablePtr.isNull())
+    {
       jam();
-      // Parse altered table defintion
-      ParseDictTabInfoRecord parseRecord;
-      aParseRecord = &parseRecord;
-      
-      parseRecord.requestType = DictTabInfo::AlterTableFromAPI;
-      parseRecord.errorCode = 0;
-      
-      SimplePropertiesSectionReader r(tabInfoPtr, getSectionSegmentPool());
-      
-      handleTabInfoInit(r, &parseRecord, false); // Will not save info
+      parseRecord.errorCode = AlterTableRef::NoSuchTable;
+      break;
+    }
+
+    switch(requestType) {
+    case(AlterTabReq::AlterTablePrepare): {
       
-      if(parseRecord.errorCode != 0){
+      const TableRecord::TabState tabState = tablePtr.p->tabState;
+      bool ok = false;
+      switch(tabState){
+      case TableRecord::NOT_DEFINED:
+      case TableRecord::REORG_TABLE_PREPARED:
+      case TableRecord::DEFINING:
+      case TableRecord::CHECKED:
+	jam();
+	parseRecord.errorCode = AlterTableRef::NoSuchTable;
+	break;
+      case TableRecord::DEFINED:
+	ok = true;
+	jam();
+	break;
+      case TableRecord::PREPARE_DROPPING:
+      case TableRecord::DROPPING:
+	jam();
+	parseRecord.errorCode = AlterTableRef::DropInProgress;
+	break;
+      case TableRecord::BACKUP_ONGOING:
+	jam();
+	parseRecord.errorCode = AlterTableRef::BackupInProgress;
+	break;
+      }
+      if (parseRecord.errorCode)
+      {
+	jam();
+	break;
+      }
+      ndbrequire(ok);
+
+      if(alter_obj_inc_schema_version(tablePtr.p->tableVersion)!= tableVersion)
+      {
+	jam();
+	parseRecord.errorCode = AlterTableRef::InvalidTableVersion;
+	break;
+      }
+      TableRecordPtr newTablePtr;
+
+      if (senderRef  != reference())
+      {
+	jam();
+	// Parse altered table defintion
+	parseRecord.requestType = DictTabInfo::AlterTableFromAPI;
+	SimplePropertiesSectionReader r(tabInfoPtr, getSectionSegmentPool());
+
+	handleTabInfoInit(r, &parseRecord, false); // Will not save info
+
+	if(parseRecord.errorCode != 0)
+	{
+	  jam();
+	  c_opCreateTable.release(alterTabPtr);
+	  break;
+	}
+
+	alterTabPtr.p->key = senderData;
+	c_opCreateTable.add(alterTabPtr);
+	alterTabPtr.p->m_errorCode = 0;
+	alterTabPtr.p->m_senderRef = senderRef;
+	alterTabPtr.p->m_senderData = senderData;
+	alterTabPtr.p->m_tablePtrI = parseRecord.tablePtr.i;
+	alterTabPtr.p->m_tupAlterTabPtr= RNIL;
+	alterTabPtr.p->m_fragmentsPtrI = RNIL;
+	alterTabPtr.p->m_dihAddFragPtr = RNIL;
+	newTablePtr = parseRecord.tablePtr;
+	newTablePtr.p->tableVersion = tableVersion;
+	ndbrequire(newTablePtr.p->noOfAttributes>= tablePtr.p->noOfAttributes);
+      }
+      else { // (req->senderRef  == reference())
+	jam();
+	c_tableRecordPool.getPtr(newTablePtr, alterTabPtr.p->m_tablePtrI);
+	newTablePtr.p->tableVersion = tableVersion;
+      }
+      Uint32 oldNoOfAttributes = tablePtr.p->noOfAttributes;
+      alterTabPtr.p->m_new_cols = newTablePtr.p->noOfAttributes-oldNoOfAttributes;
+      if (handleAlterTab(req, alterTabPtr.p, tablePtr, newTablePtr) == -1)
+      {
 	jam();
 	c_opCreateTable.release(alterTabPtr);
-	alterTabRef(signal, req, 
-		    (AlterTableRef::ErrorCode) parseRecord.errorCode, 
-		    aParseRecord);
-	return;
+	parseRecord.errorCode = AlterTableRef::UnsupportedChange;
+	break;
       }
-      alterTabPtr.p->key = senderData;
-      c_opCreateTable.add(alterTabPtr);
-      alterTabPtr.p->m_errorCode = 0;
-      alterTabPtr.p->m_senderRef = senderRef;
-      alterTabPtr.p->m_senderData = senderData;
-      alterTabPtr.p->m_tablePtrI = parseRecord.tablePtr.i;
-      alterTabPtr.p->m_tupAlterTabPtr= RNIL;
-      alterTabPtr.p->m_fragmentsPtrI = RNIL;
-      alterTabPtr.p->m_dihAddFragPtr = RNIL;
-      newTablePtr = parseRecord.tablePtr;
-      newTablePtr.p->tableVersion = tableVersion;
-      ndbrequire(newTablePtr.p->noOfAttributes >= tablePtr.p->noOfAttributes);
-    }
-    else { // (req->senderRef  == reference())
-      jam();
-      c_tableRecordPool.getPtr(newTablePtr, alterTabPtr.p->m_tablePtrI);
-      newTablePtr.p->tableVersion = tableVersion;
-    }
-    Uint32 oldNoOfAttributes= tablePtr.p->noOfAttributes;
-    alterTabPtr.p->m_new_cols= newTablePtr.p->noOfAttributes-oldNoOfAttributes;
-    if (handleAlterTab(req, alterTabPtr.p, tablePtr, newTablePtr) == -1) {
-      jam();
-      c_opCreateTable.release(alterTabPtr);
-      alterTabRef(signal, req, AlterTableRef::UnsupportedChange);
-      return;
-    }
-    releaseSections(signal);
+      releaseSections(handle);
 
-    // Propagate alter table to other local blocks
-    // First to TUP, which is the only one that needs info about added attrs
+      // Propagate alter table to other local blocks
+      // First to TUP, which is the only one that needs info about added attrs
 
-    /* Copy out descriptor and charset for any new attributes. */
-    Uint32 *attrData= &(signal->theData[0])+25;
-    Uint32 *p= attrData;
-    LocalDLFifoList<AttributeRecord> list(c_attributeRecordPool, 
-                                          tablePtr.p->m_attributes);
-    AttributeRecordPtr attrPtr;
-    list.first(attrPtr);
-    for(Uint32 i= 0; i<tablePtr.p->noOfAttributes; i++)
-    {
-      if (i >= oldNoOfAttributes)
+      /* Copy out descriptor and charset for any new attributes. */
+      Uint32 *attrData= &(signal->theData[0])+25;
+      Uint32 *p= attrData;
+      LocalDLFifoList<AttributeRecord> list(c_attributeRecordPool,
+					    tablePtr.p->m_attributes);
+      AttributeRecordPtr attrPtr;
+      list.first(attrPtr);
+      for(Uint32 i= 0; i<tablePtr.p->noOfAttributes; i++)
       {
-        *p++= attrPtr.p->attributeDescriptor;
-        *p++= attrPtr.p->extPrecision & ~0xFFFF;
+	if (i >= oldNoOfAttributes)
+	{
+	  *p++= attrPtr.p->attributeDescriptor;
+	  *p++= attrPtr.p->extPrecision & ~0xFFFF;
+	}
+	list.next(attrPtr);
       }
-      list.next(attrPtr);
-    }
 
-    AlterTabReq *req= (AlterTabReq *)signal->getDataPtrSend();
-    req->senderRef= reference();
-    req->changeMask= changeMask;
-    req->senderData= senderData;
-    req->tableId = tableId;
-    req->tableVersion = tableVersion;
-    req->gci = gci;
-    req->requestType = requestType;
-    req->noOfNewAttr= alterTabPtr.p->m_new_cols;
-    req->newNoOfCharsets= newTablePtr.p->noOfCharsets;
-    req->newNoOfKeyAttrs= newTablePtr.p->noOfPrimkey;
-
-    if (req->noOfNewAttr>0)
-    {
-      ndbrequire(AlterTableReq::getAddAttrFlag(changeMask));
-      /* Send long signal with info for all attributes to TUP. */
-      LinearSectionPtr ptr[3];
-      ptr[0].p= attrData;
-      ptr[0].sz= 2*req->noOfNewAttr;
-      sendSignal(DBTUP_REF, GSN_ALTER_TAB_REQ, signal,
-                 AlterTabReq::SignalLength, JBB, ptr, 1);
+      AlterTabReq *req= (AlterTabReq *)signal->getDataPtrSend();
+      req->senderRef= reference();
+      req->changeMask= changeMask;
+      req->senderData= senderData;
+      req->tableId = tableId;
+      req->tableVersion = tableVersion;
+      req->gci = gci;
+      req->requestType = requestType;
+      req->noOfNewAttr= alterTabPtr.p->m_new_cols;
+      req->newNoOfCharsets= newTablePtr.p->noOfCharsets;
+      req->newNoOfKeyAttrs= newTablePtr.p->noOfPrimkey;
+
+      if (req->noOfNewAttr>0)
+      {
+	ndbrequire(AlterTableReq::getAddAttrFlag(changeMask));
+	/* Send long signal with info for all attributes to TUP. */
+	LinearSectionPtr ptr[3];
+	ptr[0].p= attrData;
+	ptr[0].sz= 2*req->noOfNewAttr;
+	sendSignal(DBTUP_REF, GSN_ALTER_TAB_REQ, signal,
+		   AlterTabReq::SignalLength, JBB, ptr, 1);
+      }
+      else
+      {
+	ndbrequire(!AlterTableReq::getAddAttrFlag(changeMask));
+	/* No linear section since no attributes to send. */
+	sendSignal(DBTUP_REF, GSN_ALTER_TAB_REQ, signal,
+		   AlterTabReq::SignalLength, JBB);
+      }
+      return;
     }
-    else
-    {
-      ndbrequire(!AlterTableReq::getAddAttrFlag(changeMask));
-      /* No linear section since no attributes to send. */
+    case(AlterTabReq::AlterTableCommit): {
+      jam();
+
+      alterTabPtr.p->m_tabInfoPtrI = tabInfoPtr.i;
+      handle.clear();
+
+      /* Send alter table commit to TUP. */
+      AlterTabReq *req= (AlterTabReq *)signal->getDataPtrSend();
+      req->senderRef= reference();
+      req->changeMask= changeMask;
+      req->senderData= senderData;
+      req->clientData= alterTabPtr.p->m_tupAlterTabPtr;
+      req->tableId = tableId;
+      req->tableVersion = tableVersion;
+      req->gci = gci;
+      req->requestType = requestType;
       sendSignal(DBTUP_REF, GSN_ALTER_TAB_REQ, signal,
-                 AlterTabReq::SignalLength, JBB);
-    }
-    return;
-  }
-  case(AlterTabReq::AlterTableCommit): {
-    jam();
+		 AlterTabReq::SignalLength, JBB);
+      return;
 
-    SegmentedSectionPtr tabInfoPtr;
-    signal->getSection(tabInfoPtr, AlterTabReq::DICT_TAB_INFO);
-    alterTabPtr.p->m_tabInfoPtrI = tabInfoPtr.i;
-    signal->header.m_noOfSections = 0;
+    }
+    case(AlterTabReq::AlterTableRevert): {
+      jam();
 
-    /* Send alter table commit to TUP. */
-    AlterTabReq *req= (AlterTabReq *)signal->getDataPtrSend();
-    req->senderRef= reference();
-    req->changeMask= changeMask;
-    req->senderData= senderData;
-    req->clientData= alterTabPtr.p->m_tupAlterTabPtr;
-    req->tableId = tableId;
-    req->tableVersion = tableVersion;
-    req->gci = gci;
-    req->requestType = requestType;
-    sendSignal(DBTUP_REF, GSN_ALTER_TAB_REQ, signal,
-               AlterTabReq::SignalLength, JBB);
-    return;
+      releaseSections(handle);
 
-  }
-  case(AlterTabReq::AlterTableRevert): {
-    jam();
-    /* Send alter table abort to TUP. */
-    AlterTabReq *req= (AlterTabReq *)signal->getDataPtrSend();
-    req->senderRef= reference();
-    req->changeMask= changeMask;
-    req->senderData= senderData;
-    req->clientData= alterTabPtr.p->m_tupAlterTabPtr;
-    req->tableId = tableId;
-    req->tableVersion = tableVersion;
-    req->gci = gci;
-    req->requestType = requestType;
-    sendSignal(DBTUP_REF, GSN_ALTER_TAB_REQ, signal,
-               AlterTabReq::SignalLength, JBB);
-    return;
-  }
-  default: ndbrequire(false);
-  }
-}
+      /* Send alter table abort to TUP. */
+      AlterTabReq *req= (AlterTabReq *)signal->getDataPtrSend();
+      req->senderRef= reference();
+      req->changeMask= changeMask;
+      req->senderData= senderData;
+      req->clientData= alterTabPtr.p->m_tupAlterTabPtr;
+      req->tableId = tableId;
+      req->tableVersion = tableVersion;
+      req->gci = gci;
+      req->requestType = requestType;
+      sendSignal(DBTUP_REF, GSN_ALTER_TAB_REQ, signal,
+		 AlterTabReq::SignalLength, JBB);
+      return;
+    }
+    default: ndbrequire(false);
+    }
+  } while(0);
 
-void Dbdict::alterTabRef(Signal * signal, 
-			 AlterTabReq * req, 
-			 AlterTableRef::ErrorCode errCode,
-			 ParseDictTabInfoRecord* parseRecord)
-{
-  jam();
-  releaseSections(signal);
+  releaseSections(handle);
   AlterTabRef * ref = (AlterTabRef*)signal->getDataPtrSend();
-  Uint32 senderRef = req->senderRef;
-  ref->senderData = req->senderData;
+  ref->senderData = senderData;
   ref->senderRef = reference();
-  if (parseRecord) {
-    jam();
-    ref->errorCode = parseRecord->errorCode;
-    ref->errorLine = parseRecord->errorLine;
-    ref->errorKey = parseRecord->errorKey;
-    ref->errorStatus = parseRecord->status;
-  }
-  else {
-    jam();
-    ref->errorCode = errCode;
-    ref->errorLine = 0;
-    ref->errorKey = 0;
-    ref->errorStatus = 0;
-  }
-  sendSignal(senderRef, GSN_ALTER_TAB_REF, signal, 
+  ref->errorCode = parseRecord.errorCode;
+  ref->errorLine = parseRecord.errorLine;
+  ref->errorKey = parseRecord.errorKey;
+  ref->errorStatus = parseRecord.status;
+
+  sendSignal(senderRef, GSN_ALTER_TAB_REF, signal,
 	     AlterTabRef::SignalLength, JBB);
-  
+
   c_blockState = BS_IDLE;
 }
 
+
 void Dbdict::execALTER_TAB_REF(Signal * signal){
   jamEntry();
 
@@ -4597,8 +4602,8 @@ void Dbdict::execALTER_TAB_REF(Signal * 
       packTableIntoPages(w, tablePtr);
       SegmentedSectionPtr spDataPtr;
       w.getPtr(spDataPtr);
-      signal->setSection(spDataPtr, AlterTabReq::DICT_TAB_INFO);
-      
+      SectionHandle handle(this, spDataPtr.i);
+
       NodeReceiverGroup rg(DBDICT, c_aliveNodes);
       alterTabPtr.p->m_coordinatorData.m_gsn = GSN_ALTER_TAB_REQ;
       safeCounter.init<AlterTabRef>(rg, alterTabPtr.p->key);
@@ -4615,7 +4620,7 @@ void Dbdict::execALTER_TAB_REF(Signal * 
       lreq->requestType = AlterTabReq::AlterTableRevert;
       
       sendSignal(rg, GSN_ALTER_TAB_REQ, signal, 
-		 AlterTabReq::SignalLength, JBB);
+		 AlterTabReq::SignalLength, JBB, &handle);
     }
     else {
       jam();
@@ -4751,8 +4756,8 @@ Dbdict::execALTER_TAB_CONF(Signal * sign
 	packTableIntoPages(w, tablePtr);
 	SegmentedSectionPtr spDataPtr;
 	w.getPtr(spDataPtr);
-	signal->setSection(spDataPtr, AlterTabReq::DICT_TAB_INFO);
-	
+	SectionHandle handle(this, spDataPtr.i);
+
 	NodeReceiverGroup rg(DBDICT, c_aliveNodes);
 	alterTabPtr.p->m_coordinatorData.m_gsn = GSN_ALTER_TAB_REQ;
 	safeCounter.init<AlterTabRef>(rg, alterTabPtr.p->key);
@@ -4769,7 +4774,7 @@ Dbdict::execALTER_TAB_CONF(Signal * sign
 	lreq->requestType = AlterTabReq::AlterTableRevert;
 	
 	sendSignal(rg, GSN_ALTER_TAB_REQ, signal, 
-		   AlterTabReq::SignalLength, JBB);
+		   AlterTabReq::SignalLength, JBB, &handle);
       }
       else {
 	jam();
@@ -4780,7 +4785,7 @@ Dbdict::execALTER_TAB_CONF(Signal * sign
 	packTableIntoPages(w, tablePtr);
 	SegmentedSectionPtr spDataPtr;
 	w.getPtr(spDataPtr);
-	signal->setSection(spDataPtr, AlterTabReq::DICT_TAB_INFO);
+	SectionHandle handle(this, spDataPtr.i);
 	
 	NodeReceiverGroup rg(DBDICT, c_aliveNodes);
 	alterTabPtr.p->m_coordinatorData.m_gsn = GSN_ALTER_TAB_REQ;
@@ -4798,7 +4803,7 @@ Dbdict::execALTER_TAB_CONF(Signal * sign
 	lreq->requestType = AlterTabReq::AlterTableCommit;
 	
 	sendFragmentedSignal(rg, GSN_ALTER_TAB_REQ, signal, 
-			     AlterTabReq::SignalLength, JBB);
+			     AlterTabReq::SignalLength, JBB, &handle);
       }
     }
     else {
@@ -4874,7 +4879,7 @@ Dbdict::execALTER_TAB_CONF(Signal * sign
     if (safeCounter.done()) {
       jam();
       // We have received all local confirmations
-      releaseSections(signal);
+
       if (alterTabPtr.p->m_alterTableFailed) {
 	jam();
 	AlterTableRef * apiRef = 
@@ -5149,14 +5154,15 @@ Dbdict::alterTab_writeTableConf(Signal* 
   req->gci = tabPtr.p->gciTableCreated;
   req->requestType = AlterTabReq::AlterTableCommit;
   req->changeMask = alterTabPtr.p->m_changeMask;
-  SegmentedSectionPtr tabInfoPtr;
-  getSection(tabInfoPtr, alterTabPtr.p->m_tabInfoPtrI);
-  signal->setSection(tabInfoPtr, AlterTabReq::DICT_TAB_INFO);
+
+  SectionHandle handle(this, alterTabPtr.p->m_tabInfoPtrI);
+  signal->theData[AlterTabReq::SignalLength] = alterTabPtr.p->m_tabInfoPtrI;
   EXECUTE_DIRECT(SUMA, GSN_ALTER_TAB_REQ, signal,
-                 AlterTabReq::SignalLength);
-  releaseSections(signal);
-  alterTabPtr.p->m_tabInfoPtrI = RNIL;
+                 AlterTabReq::SignalLength + 1);
   jamEntry();
+  releaseSections(handle);
+  alterTabPtr.p->m_tabInfoPtrI = RNIL;
+
   AlterTabConf * conf = (AlterTabConf*)signal->getDataPtrSend();
   conf->senderRef = reference();
   conf->senderData = callbackData;
@@ -5216,11 +5222,11 @@ Dbdict::execCREATE_FRAGMENTATION_CONF(Si
   CreateTableRecordPtr createTabPtr;
   ndbrequire(c_opCreateTable.find(createTabPtr, conf->senderData));
 
-  ndbrequire(signal->getNoOfSections() == 1);
-
+  SectionHandle handle(this, signal);
+  ndbrequire(handle.m_cnt == 1);
   SegmentedSectionPtr fragDataPtr;
-  signal->getSection(fragDataPtr, CreateFragmentationConf::FRAGMENTS);
-  signal->header.m_noOfSections = 0;
+  handle.getSection(fragDataPtr, CreateFragmentationConf::FRAGMENTS);
+  handle.clear();
 
   /**
    * Get table
@@ -5251,8 +5257,9 @@ Dbdict::execCREATE_FRAGMENTATION_CONF(Si
   SegmentedSectionPtr spDataPtr;
   w.getPtr(spDataPtr);
   
-  signal->setSection(spDataPtr, CreateTabReq::DICT_TAB_INFO);
-  signal->setSection(fragDataPtr, CreateTabReq::FRAGMENTATION);
+  handle.m_ptr[CreateTabReq::DICT_TAB_INFO] = spDataPtr;
+  handle.m_ptr[CreateTabReq::FRAGMENTATION] = fragDataPtr;
+  handle.m_cnt = 2;
  
   NodeReceiverGroup rg(DBDICT, c_aliveNodes);
   SafeCounter tmp(c_counterMgr, createTabPtr.p->m_coordinatorData.m_counter);
@@ -5272,7 +5279,8 @@ Dbdict::execCREATE_FRAGMENTATION_CONF(Si
   req->tableVersion = create_obj_inc_schema_version(tabEntry->m_tableVersion);
   
   sendFragmentedSignal(rg, GSN_CREATE_TAB_REQ, signal, 
-		       CreateTabReq::SignalLength, JBB);
+		       CreateTabReq::SignalLength, JBB,
+		       &handle);
 
   return;
 }
@@ -5487,8 +5495,9 @@ Dbdict::createTab_prepare(Signal* signal
   const Uint32 tableId = req->tableId;
   const Uint32 tableVersion = req->tableVersion;
 
+  SectionHandle handle(this, signal);
   SegmentedSectionPtr tabInfoPtr;
-  signal->getSection(tabInfoPtr, CreateTabReq::DICT_TAB_INFO);
+  handle.getSection(tabInfoPtr, CreateTabReq::DICT_TAB_INFO);
   
   CreateTableRecordPtr createTabPtr;  
   if(req->senderRef == reference()){
@@ -5526,13 +5535,12 @@ Dbdict::createTab_prepare(Signal* signal
   ndbrequire(!createTabPtr.isNull());
 
   SegmentedSectionPtr fragPtr;
-  signal->getSection(fragPtr, CreateTabReq::FRAGMENTATION);
+  handle.getSection(fragPtr, CreateTabReq::FRAGMENTATION);
+  handle.clear();
 
   createTabPtr.p->m_tabInfoPtrI = tabInfoPtr.i;
   createTabPtr.p->m_fragmentsPtrI = fragPtr.i;
   
-  signal->header.m_noOfSections = 0;
-  
   TableRecordPtr tabPtr;
   c_tableRecordPool.getPtr(tabPtr, tableId);
   tabPtr.p->packedSize = tabInfoPtr.sz;
@@ -5639,12 +5647,21 @@ Dbdict::createTab_dih(Signal* signal, 
 /*
   Need to fetch fragDataPtr from table object instead
 */
-  if(!fragDataPtr.isNull()){
-    signal->setSection(fragDataPtr, DiAddTabReq::FRAGMENTATION);
+  if(!fragDataPtr.isNull())
+  {
+    jam();
+    SectionHandle handle(this, fragDataPtr.i);
+    sendSignal(DBDIH_REF, GSN_DIADDTABREQ, signal,
+	       DiAddTabReq::SignalLength, JBB,
+	       &handle);
+  }
+  else
+  {
+    jam();
+    sendSignal(DBDIH_REF, GSN_DIADDTABREQ, signal,
+	       DiAddTabReq::SignalLength, JBB);
   }
 
-  sendSignal(DBDIH_REF, GSN_DIADDTABREQ, signal, 
-	     DiAddTabReq::SignalLength, JBB);
 
   /**
    * Create KeyDescriptor
@@ -7599,10 +7616,11 @@ void Dbdict::execGET_TABLEDID_REQ(Signal
   }
 
   char tableName[MAX_TAB_NAME_SIZE];
+  SectionHandle handle(this, signal);
   SegmentedSectionPtr ssPtr;
-  signal->getSection(ssPtr,GetTableIdReq::TABLE_NAME);
+  handle.getSection(ssPtr,GetTableIdReq::TABLE_NAME);
   copy((Uint32*)tableName, ssPtr);
-  releaseSections(signal);
+  releaseSections(handle);
     
   DictObject * obj_ptr_p = get_object(tableName, len);
   if(obj_ptr_p == 0 || !DictTabInfo::isTable(obj_ptr_p->m_type)){
@@ -7651,6 +7669,7 @@ void Dbdict::execGET_TABINFOREQ(Signal* 
   }  
 
   GetTabInfoReq * const req = (GetTabInfoReq *)&signal->theData[0];
+  SectionHandle handle(this, signal);
 
   /**
    * If I get a GET_TABINFO_REQ from myself
@@ -7662,23 +7681,26 @@ void Dbdict::execGET_TABINFOREQ(Signal* 
     jam();
     
     sendSignalWithDelay(reference(), GSN_GET_TABINFOREQ, signal, 30, 
-			signal->length());
+			signal->length(),
+			&handle);
     return;
   }//if
 
   const Uint32 MAX_WAITERS = 5;
   
-  if(c_retrieveRecord.busyState && fromTimeQueue == false){
+  if(c_retrieveRecord.busyState && fromTimeQueue == false)
+  {
     jam();
     if(c_retrieveRecord.noOfWaiters < MAX_WAITERS){
       jam();
       c_retrieveRecord.noOfWaiters++;
       
       sendSignalWithDelay(reference(), GSN_GET_TABINFOREQ, signal, 30, 
-			  signal->length());
+			  signal->length(),
+			  &handle);
       return;
     }
-    
+    releaseSections(handle);
     sendGET_TABINFOREF(signal, req, GetTabInfoRef::Busy);
     return;
   }
@@ -7694,36 +7716,29 @@ void Dbdict::execGET_TABINFOREQ(Signal* 
   Uint32 obj_id = RNIL;
   if(reqType == GetTabInfoReq::RequestByName){
     jam();
-    ndbrequire(signal->getNoOfSections() == 1);  
+    ndbrequire(handle.m_cnt == 1);
     const Uint32 len = req->tableNameLen;
     
     if(len > MAX_TAB_NAME_SIZE){
       jam();
-      releaseSections(signal);
+      releaseSections(handle);
       sendGET_TABINFOREF(signal, req, GetTabInfoRef::TableNameTooLong);
       return;
     }
 
-    char tableName[MAX_TAB_NAME_SIZE];
+    Uint32 tableName[(MAX_TAB_NAME_SIZE + 3) / 4];
     SegmentedSectionPtr ssPtr;
-    signal->getSection(ssPtr,GetTabInfoReq::TABLE_NAME);
-    SimplePropertiesSectionReader r0(ssPtr, getSectionSegmentPool());
-    r0.reset(); // undo implicit first()
-    if(!r0.getWords((Uint32*)tableName, (len+3)/4)){
-      jam();
-      releaseSections(signal);
-      sendGET_TABINFOREF(signal, req, GetTabInfoRef::TableNotDefined);
-      return;
-    }
-    releaseSections(signal);
+    handle.getSection(ssPtr,GetTabInfoReq::TABLE_NAME);
+    copy(tableName, ssPtr);
     
-    DictObject * old_ptr_p = old_ptr_p = get_object(tableName, len);
+    DictObject * old_ptr_p = get_object((char*)tableName, len);
     if(old_ptr_p)
       obj_id = old_ptr_p->m_id;
   } else {
     jam();
     obj_id = req->tableId;
   }
+  releaseSections(handle);
 
   SchemaFile::TableEntry *objEntry = 0;
   if(obj_id != RNIL){
@@ -8069,6 +8084,7 @@ Dbdict::execCREATE_INDX_REQ(Signal* sign
       jam();
       return;
     }
+    SectionHandle handle(this, signal);
     if (signal->getLength() == CreateIndxReq::SignalLength) {
       jam();
       CreateIndxRef::ErrorCode tmperr = CreateIndxRef::NoError;
@@ -8088,7 +8104,7 @@ Dbdict::execCREATE_INDX_REQ(Signal* sign
         tmperr = CreateIndxRef::SingleUser;
       }
       if (tmperr != CreateIndxRef::NoError) {
-	releaseSections(signal);
+	releaseSections(handle);
 	OpCreateIndex opBusy;
 	opPtr.p = &opBusy;
 	opPtr.p->save(req);
@@ -8105,7 +8121,8 @@ Dbdict::execCREATE_INDX_REQ(Signal* sign
       req->setOpKey(++c_opRecordSequence);
       NodeReceiverGroup rg(DBDICT, c_aliveNodes);
       sendSignal(rg, GSN_CREATE_INDX_REQ,
-          signal, CreateIndxReq::SignalLength + 1, JBB);
+		 signal, CreateIndxReq::SignalLength + 1, JBB,
+		 &handle);
       return;
     }
     // seize operation record
@@ -8123,14 +8140,14 @@ Dbdict::execCREATE_INDX_REQ(Signal* sign
       jam();
       opPtr.p->m_errorCode = CreateIndxRef::Busy;
       opPtr.p->m_errorLine = __LINE__;
-      releaseSections(signal);
+      releaseSections(handle);
       createIndex_sendReply(signal, opPtr, opPtr.p->m_isMaster);
       return;
     }
     c_opCreateIndex.add(opPtr);
     // save attribute list
     SegmentedSectionPtr ssPtr;
-    signal->getSection(ssPtr, CreateIndxReq::ATTRIBUTE_LIST_SECTION);
+    handle.getSection(ssPtr, CreateIndxReq::ATTRIBUTE_LIST_SECTION);
     SimplePropertiesSectionReader r0(ssPtr, getSectionSegmentPool());
     r0.reset(); // undo implicit first()
     if (! r0.getWord(&opPtr.p->m_attrList.sz) ||
@@ -8138,12 +8155,12 @@ Dbdict::execCREATE_INDX_REQ(Signal* sign
       jam();
       opPtr.p->m_errorCode = CreateIndxRef::InvalidName;
       opPtr.p->m_errorLine = __LINE__;
-      releaseSections(signal);
+      releaseSections(handle);
       createIndex_sendReply(signal, opPtr, opPtr.p->m_isMaster);
       return;
     }
     // save name and index table properties
-    signal->getSection(ssPtr, CreateIndxReq::INDEX_NAME_SECTION);
+    handle.getSection(ssPtr, CreateIndxReq::INDEX_NAME_SECTION);
     SimplePropertiesSectionReader r1(ssPtr, getSectionSegmentPool());
     c_tableDesc.init();
     SimpleProperties::UnpackStatus status = SimpleProperties::unpack(
@@ -8153,14 +8170,14 @@ Dbdict::execCREATE_INDX_REQ(Signal* sign
     if (status != SimpleProperties::Eof) {
       opPtr.p->m_errorCode = CreateIndxRef::InvalidName;
       opPtr.p->m_errorLine = __LINE__;
-      releaseSections(signal);
+      releaseSections(handle);
       createIndex_sendReply(signal, opPtr, opPtr.p->m_isMaster);
       return;
     }
     memcpy(opPtr.p->m_indexName, c_tableDesc.TableName, MAX_TAB_NAME_SIZE);
     opPtr.p->m_loggedIndex = c_tableDesc.TableLoggedFlag;
     opPtr.p->m_temporaryIndex = c_tableDesc.TableTemporaryFlag;
-    releaseSections(signal);
+    releaseSections(handle);
     // master expects to hear from all
     if (opPtr.p->m_isMaster)
       opPtr.p->m_signalCounter = c_aliveNodes;
@@ -8190,7 +8207,8 @@ Dbdict::execCREATE_INDX_REQ(Signal* sign
   }
   jam();
   // return to sender
-  releaseSections(signal);
+  SectionHandle handle(this, signal);
+  releaseSections(handle);
   OpCreateIndex opBad;
   opPtr.p = &opBad;
   opPtr.p->save(req);
@@ -8549,8 +8567,6 @@ Dbdict::createIndex_toCreateTable(Signal
   }
   // finish
   w.add(DictTabInfo::TableEnd, (Uint32)true);
-  // remember to...
-  releaseSections(signal);
   // send create index table request
   CreateTableReq * const cre = (CreateTableReq*)signal->getDataPtrSend();
   cre->senderRef = reference();
@@ -9406,12 +9422,13 @@ Dbdict::execCREATE_EVNT_REQ(Signal* sign
   CreateEvntReq *req = (CreateEvntReq*)signal->getDataPtr();
   const CreateEvntReq::RequestType requestType = req->getRequestType();
   const Uint32                     requestFlag = req->getRequestFlag();
+  SectionHandle handle(this, signal);
 
   if (refToBlock(signal->senderBlockRef()) != DBDICT &&
       getOwnNodeId() != c_masterNodeId)
   {
     jam();
-    releaseSections(signal);
+    releaseSections(handle);
     
     CreateEvntRef * ref = (CreateEvntRef *)signal->getDataPtrSend();
     ref->setUserRef(reference());
@@ -9429,7 +9446,7 @@ Dbdict::execCREATE_EVNT_REQ(Signal* sign
   if (!c_opCreateEvent.seize(evntRecPtr)) {
     // Failed to allocate event record
     jam();
-    releaseSections(signal);
+    releaseSections(handle);
 
     CreateEvntRef * ret = (CreateEvntRef *)signal->getDataPtrSend();
     ret->senderRef = reference();
@@ -9452,19 +9469,20 @@ Dbdict::execCREATE_EVNT_REQ(Signal* sign
   if (requestFlag & (Uint32)CreateEvntReq::RT_DICT_AFTER_GET) {
     jam();
     EVENT_TRACE;
+    releaseSections(handle);
     createEvent_RT_DICT_AFTER_GET(signal, evntRecPtr);
     return;
   }
   if (requestType == CreateEvntReq::RT_USER_GET) {
     jam();
     EVENT_TRACE;
-    createEvent_RT_USER_GET(signal, evntRecPtr);
+    createEvent_RT_USER_GET(signal, evntRecPtr, handle);
     return;
   }
   if (requestType == CreateEvntReq::RT_USER_CREATE) {
     jam();
     EVENT_TRACE;
-    createEvent_RT_USER_CREATE(signal, evntRecPtr);
+    createEvent_RT_USER_CREATE(signal, evntRecPtr, handle);
     return;
   }
 
@@ -9472,7 +9490,7 @@ Dbdict::execCREATE_EVNT_REQ(Signal* sign
   ndbout << "Dbdict.cpp: Dbdict::execCREATE_EVNT_REQ other" << endl;
 #endif
   jam();
-  releaseSections(signal);
+  releaseSections(handle);
     
   evntRecPtr.p->m_errorCode = 1;
   evntRecPtr.p->m_errorLine = __LINE__;
@@ -9488,7 +9506,9 @@ Dbdict::execCREATE_EVNT_REQ(Signal* sign
  *****************************************************************/
 
 void
-Dbdict::createEvent_RT_USER_CREATE(Signal* signal, OpCreateEventPtr evntRecPtr)
+Dbdict::createEvent_RT_USER_CREATE(Signal* signal,
+				   OpCreateEventPtr evntRecPtr,
+				   SectionHandle& handle)
 {
   jam();
   DBUG_ENTER("Dbdict::createEvent_RT_USER_CREATE");
@@ -9506,7 +9526,7 @@ Dbdict::createEvent_RT_USER_CREATE(Signa
 
   SegmentedSectionPtr ssPtr;
   // save name and event properties
-  signal->getSection(ssPtr, CreateEvntReq::EVENT_NAME_SECTION);
+  ndbrequire(handle.getSection(ssPtr, CreateEvntReq::EVENT_NAME_SECTION));
 
   SimplePropertiesSectionReader r0(ssPtr, getSectionSegmentPool());
 #ifdef EVENT_DEBUG
@@ -9517,7 +9537,7 @@ Dbdict::createEvent_RT_USER_CREATE(Signa
       (r0.getValueType() != SimpleProperties::StringValue) ||
       (r0.getValueLen() <= 0)) {
     jam();
-    releaseSections(signal);
+    releaseSections(handle);
 
     evntRecPtr.p->m_errorCode = 1;
     evntRecPtr.p->m_errorLine = __LINE__;
@@ -9543,7 +9563,7 @@ Dbdict::createEvent_RT_USER_CREATE(Signa
       (r0.getValueType() != SimpleProperties::StringValue) ||
       (r0.getValueLen() <= 0)) {
     jam();
-    releaseSections(signal);
+    releaseSections(handle);
     
     evntRecPtr.p->m_errorCode = 1;
     evntRecPtr.p->m_errorLine = __LINE__;
@@ -9558,7 +9578,7 @@ Dbdict::createEvent_RT_USER_CREATE(Signa
     memset(evntRecPtr.p->m_eventRec.TABLE_NAME+len, 0, MAX_TAB_NAME_SIZE-len);
   }
 
-  releaseSections(signal);
+  releaseSections(handle);
   
   // Send request to SUMA
 
@@ -9621,8 +9641,6 @@ void Dbdict::execCREATE_SUBID_CONF(Signa
   evntRec->m_request.setEventId(sumaIdConf->subscriptionId);
   evntRec->m_request.setEventKey(sumaIdConf->subscriptionKey);
 
-  releaseSections(signal);
-
   Callback c = { safe_cast(&Dbdict::createEventUTIL_PREPARE), 0 };
 
   prepareTransactionEventSysTable(&c, signal, evntRecId,
@@ -9886,12 +9904,14 @@ void Dbdict::executeTransaction(Callback
 
 void Dbdict::parseReadEventSys(Signal* signal, sysTab_NDBEVENTS_0& m_eventRec)
 {
-  SegmentedSectionPtr headerPtr, dataPtr;
   jam();
-  signal->getSection(headerPtr, UtilExecuteReq::HEADER_SECTION);
+  SectionHandle handle(this, signal);
+  SegmentedSectionPtr headerPtr, dataPtr;
+
+  handle.getSection(headerPtr, UtilExecuteReq::HEADER_SECTION);
   SectionReader headerReader(headerPtr, getSectionSegmentPool());
       
-  signal->getSection(dataPtr, UtilExecuteReq::DATA_SECTION);
+  handle.getSection(dataPtr, UtilExecuteReq::DATA_SECTION);
   SectionReader dataReader(dataPtr, getSectionSegmentPool());
   
   AttributeHeader header;
@@ -9906,7 +9926,7 @@ void Dbdict::parseReadEventSys(Signal* s
 
   ndbrequire( ((char*)dst-(char*)&m_eventRec) == sizeof(m_eventRec) );
 
-  releaseSections(signal);
+  releaseSections(handle);
 }
     
 void Dbdict::createEventUTIL_EXECUTE(Signal *signal, 
@@ -10020,7 +10040,9 @@ void Dbdict::createEventUTIL_EXECUTE(Sig
  */
 
 void
-Dbdict::createEvent_RT_USER_GET(Signal* signal, OpCreateEventPtr evntRecPtr){
+Dbdict::createEvent_RT_USER_GET(Signal* signal,
+				OpCreateEventPtr evntRecPtr,
+				SectionHandle& handle){
   jam();
   EVENT_TRACE;
 #ifdef EVENT_PH2_DEBUG
@@ -10029,7 +10051,7 @@ Dbdict::createEvent_RT_USER_GET(Signal* 
 
   SegmentedSectionPtr ssPtr;
 
-  signal->getSection(ssPtr, 0);
+  handle.getSection(ssPtr, 0);
 
   SimplePropertiesSectionReader r0(ssPtr, getSectionSegmentPool());
 #ifdef EVENT_DEBUG
@@ -10039,7 +10061,7 @@ Dbdict::createEvent_RT_USER_GET(Signal* 
       (r0.getValueType() != SimpleProperties::StringValue) ||
       (r0.getValueLen() <= 0)) {
     jam();
-    releaseSections(signal);
+    releaseSections(handle);
 
     evntRecPtr.p->m_errorCode = 1;
     evntRecPtr.p->m_errorLine = __LINE__;
@@ -10053,7 +10075,7 @@ Dbdict::createEvent_RT_USER_GET(Signal* 
   int len = strlen(evntRecPtr.p->m_eventRec.NAME);
   memset(evntRecPtr.p->m_eventRec.NAME+len, 0, MAX_TAB_NAME_SIZE-len);
   
-  releaseSections(signal);
+  releaseSections(handle);
   
   Callback c = { safe_cast(&Dbdict::createEventUTIL_PREPARE), 0 };
   
@@ -10858,12 +10880,13 @@ Dbdict::execDROP_EVNT_REQ(Signal* signal
   DropEvntReq *req = (DropEvntReq*)signal->getDataPtr();
   const Uint32 senderRef = signal->senderBlockRef();
   OpDropEventPtr evntRecPtr;
+  SectionHandle handle(this, signal);
 
   if (refToBlock(senderRef) != DBDICT &&
       getOwnNodeId() != c_masterNodeId)
   {
     jam();
-    releaseSections(signal);
+    releaseSections(handle);
 
     DropEvntRef * ref = (DropEvntRef *)signal->getDataPtrSend();
     ref->setUserRef(reference());
@@ -10880,7 +10903,7 @@ Dbdict::execDROP_EVNT_REQ(Signal* signal
   if (!c_opDropEvent.seize(evntRecPtr)) {
     // Failed to allocate event record
     jam();
-    releaseSections(signal);
+    releaseSections(handle);
  
     DropEvntRef * ret = (DropEvntRef *)signal->getDataPtrSend();
     ret->setErrorCode(747);
@@ -10900,7 +10923,7 @@ Dbdict::execDROP_EVNT_REQ(Signal* signal
 
   SegmentedSectionPtr ssPtr;
 
-  signal->getSection(ssPtr, 0);
+  handle.getSection(ssPtr, 0);
 
   SimplePropertiesSectionReader r0(ssPtr, getSectionSegmentPool());
 #ifdef EVENT_DEBUG
@@ -10911,7 +10934,7 @@ Dbdict::execDROP_EVNT_REQ(Signal* signal
       (r0.getValueType() != SimpleProperties::StringValue) ||
       (r0.getValueLen() <= 0)) {
     jam();
-    releaseSections(signal);
+    releaseSections(handle);
 
     evntRecPtr.p->m_errorCode = 1;
     evntRecPtr.p->m_errorLine = __LINE__;
@@ -10933,7 +10956,7 @@ Dbdict::execDROP_EVNT_REQ(Signal* signal
 #endif
   }
   
-  releaseSections(signal);
+  releaseSections(handle);
 
   Callback c = { safe_cast(&Dbdict::dropEventUTIL_PREPARE_READ), 0 };
 
@@ -11362,7 +11385,6 @@ Dbdict::execALTER_INDX_REQ(Signal* signa
       if (! isLocal && getOwnNodeId() != c_masterNodeId) {
         jam();
 
-	releaseSections(signal);
 	OpAlterIndex opBad;
 	opPtr.p = &opBad;
 	opPtr.p->save(req);
@@ -12057,7 +12079,6 @@ Dbdict::execBUILDINDXREQ(Signal* signal)
       if (!isLocal && getOwnNodeId() != c_masterNodeId) {
         jam();
 	
-	releaseSections(signal);
 	OpBuildIndex opBad;
 	opPtr.p = &opBad;
 	opPtr.p->save(req);
@@ -12527,6 +12548,7 @@ Dbdict::execCREATE_TRIG_REQ(Signal* sign
   OpCreateTriggerPtr opPtr;
   const Uint32 senderRef = signal->senderBlockRef();
   const CreateTrigReq::RequestType requestType = req->getRequestType();
+  SectionHandle handle(this, signal);
   if (requestType == CreateTrigReq::RT_USER ||
       requestType == CreateTrigReq::RT_ALTER_INDEX ||
       requestType == CreateTrigReq::RT_BUILD_INDEX) {
@@ -12546,7 +12568,7 @@ Dbdict::execCREATE_TRIG_REQ(Signal* sign
       if (! isLocal && getOwnNodeId() != c_masterNodeId) {
         jam();
 
-	releaseSections(signal);
+	releaseSections(handle);
 	OpCreateTrigger opBad;
 	opPtr.p = &opBad;
 	opPtr.p->save(req);
@@ -12560,7 +12582,8 @@ Dbdict::execCREATE_TRIG_REQ(Signal* sign
       req->setOpKey(++c_opRecordSequence);
       NodeReceiverGroup rg(DBDICT, receiverNodes);
       sendSignal(rg, GSN_CREATE_TRIG_REQ,
-          signal, CreateTrigReq::SignalLength + 1, JBB);
+		 signal, CreateTrigReq::SignalLength + 1, JBB,
+		 &handle);
       return;
     }
     // seize operation record
@@ -12578,7 +12601,7 @@ Dbdict::execCREATE_TRIG_REQ(Signal* sign
       jam();
       opPtr.p->m_errorCode = CreateTrigRef::Busy;
       opPtr.p->m_errorLine = __LINE__;
-      releaseSections(signal);
+      releaseSections(handle);
       createTrigger_sendReply(signal, opPtr, opPtr.p->m_isMaster);
       return;
     }
@@ -12586,19 +12609,19 @@ Dbdict::execCREATE_TRIG_REQ(Signal* sign
     {
       // save name
       SegmentedSectionPtr ssPtr;
-      signal->getSection(ssPtr, CreateTrigReq::TRIGGER_NAME_SECTION);
+      handle.getSection(ssPtr, CreateTrigReq::TRIGGER_NAME_SECTION);
       SimplePropertiesSectionReader ssReader(ssPtr, getSectionSegmentPool());
       if (ssReader.getKey() != CreateTrigReq::TriggerNameKey ||
 	  ! ssReader.getString(opPtr.p->m_triggerName)) {
 	jam();
 	opPtr.p->m_errorCode = CreateTrigRef::InvalidName;
 	opPtr.p->m_errorLine = __LINE__;
-	releaseSections(signal);
+	releaseSections(handle);
 	createTrigger_sendReply(signal, opPtr, opPtr.p->m_isMaster);
 	return;
       }
     }
-    releaseSections(signal);
+    releaseSections(handle);
     if(get_object(opPtr.p->m_triggerName) != 0){
       jam();
       opPtr.p->m_errorCode = CreateTrigRef::TriggerExists;
@@ -12615,6 +12638,7 @@ Dbdict::execCREATE_TRIG_REQ(Signal* sign
     createTrigger_sendReply(signal, opPtr, false);
     return;
   }
+  releaseSections(handle);
   c_opCreateTrigger.find(opPtr, req->getConnectionPtr());
   if (! opPtr.isNull()) {
     opPtr.p->m_requestType = requestType;
@@ -12642,7 +12666,6 @@ Dbdict::execCREATE_TRIG_REQ(Signal* sign
   }
   jam();
   // return to sender
-  releaseSections(signal);
   OpCreateTrigger opBad;
   opPtr.p = &opBad;
   opPtr.p->save(req);
@@ -13026,6 +13049,7 @@ Dbdict::execDROP_TRIG_REQ(Signal* signal
   const Uint32 senderRef = signal->senderBlockRef();
   const DropTrigReq::RequestType requestType = req->getRequestType();
 
+  SectionHandle handle(this, signal);
   if (signal->getNoOfSections() > 0) {
     ndbrequire(signal->getNoOfSections() == 1);
     jam();
@@ -13034,18 +13058,18 @@ Dbdict::execDROP_TRIG_REQ(Signal* signal
     opPtr.p=&opTmp;
 
     SegmentedSectionPtr ssPtr;
-    signal->getSection(ssPtr, DropTrigReq::TRIGGER_NAME_SECTION);
+    handle.getSection(ssPtr, DropTrigReq::TRIGGER_NAME_SECTION);
     SimplePropertiesSectionReader ssReader(ssPtr, getSectionSegmentPool());
     if (ssReader.getKey() != DropTrigReq::TriggerNameKey ||
 	! ssReader.getString(triggerName)) {
       jam();
       opPtr.p->m_errorCode = DropTrigRef::InvalidName;
       opPtr.p->m_errorLine = __LINE__;
-      releaseSections(signal);
+      releaseSections(handle);
       dropTrigger_sendReply(signal, opPtr, opPtr.p->m_isMaster);
       return;
     }
-    releaseSections(signal);
+    releaseSections(handle);
 
     //ndbout_c("++++++++++++++ Looking for trigger %s", keyRecord.triggerName);
     DictObject * obj_ptr_p = get_object(triggerName);
@@ -14385,6 +14409,8 @@ Dbdict::execCREATE_FILE_REQ(Signal* sign
     jam();
     return;
   }
+
+  SectionHandle handle(this, signal);
   
   CreateFileReq * req = (CreateFileReq*)signal->getDataPtr();
   CreateFileRef * ref = (CreateFileRef*)signal->getDataPtrSend();
@@ -14481,12 +14507,14 @@ Dbdict::execCREATE_FILE_REQ(Signal* sign
     SafeCounter tmp(c_counterMgr, trans_ptr.p->m_counter);
     tmp.init<CreateObjRef>(rg, GSN_CREATE_OBJ_REF, trans_key);
     sendSignal(rg, GSN_CREATE_OBJ_REQ, signal, 
-	       CreateObjReq::SignalLength, JBB);
+	       CreateObjReq::SignalLength, JBB,
+	       &handle);
 
     c_blockState = BS_CREATE_TAB;
     return;
   } while(0);
   
+  releaseSections(handle);
   ref->senderData = senderData;
   ref->masterNodeId = c_masterNodeId;
   sendSignal(senderRef, GSN_CREATE_FILE_REF,signal,
@@ -14503,6 +14531,8 @@ Dbdict::execCREATE_FILEGROUP_REQ(Signal*
     return;
   }
   
+  SectionHandle handle(this, signal);
+
   CreateFilegroupReq * req = (CreateFilegroupReq*)signal->getDataPtr();
   CreateFilegroupRef * ref = (CreateFilegroupRef*)signal->getDataPtrSend();
   Uint32 senderRef = req->senderRef;
@@ -14594,12 +14624,14 @@ Dbdict::execCREATE_FILEGROUP_REQ(Signal*
     SafeCounter tmp(c_counterMgr, trans_ptr.p->m_counter);
     tmp.init<CreateObjRef>(rg, GSN_CREATE_OBJ_REF, trans_key);
     sendSignal(rg, GSN_CREATE_OBJ_REQ, signal, 
-	       CreateObjReq::SignalLength, JBB);
+	       CreateObjReq::SignalLength, JBB,
+	       &handle);
 
     c_blockState = BS_CREATE_TAB;
     return;
   } while(0);
   
+  releaseSections(handle);
   ref->senderData = senderData;
   ref->masterNodeId = c_masterNodeId;
   sendSignal(senderRef, GSN_CREATE_FILEGROUP_REF,signal,
@@ -15201,7 +15233,9 @@ Dbdict::execCREATE_OBJ_REQ(Signal* signa
   const Uint32 requestInfo = req->requestInfo;
 
   SegmentedSectionPtr objInfoPtr;
-  signal->getSection(objInfoPtr, CreateObjReq::DICT_OBJ_INFO);
+  SectionHandle handle(this, signal);
+  ndbrequire(handle.getSection(objInfoPtr, CreateObjReq::DICT_OBJ_INFO));
+  handle.clear();
   
   CreateObjRecordPtr createObjPtr;  
   ndbrequire(c_opCreateObj.seize(createObjPtr));
@@ -15250,7 +15284,6 @@ Dbdict::execCREATE_OBJ_REQ(Signal* signa
     ndbrequire(false);
   }
   
-  signal->header.m_noOfSections = 0;
   (this->*f_dict_op[createObjPtr.p->m_vt_index].m_prepare_start)
     (signal, createObjPtr.p);
 }
@@ -15336,18 +15369,18 @@ Dbdict::createObj_prepare_start_done(Sig
 				     Uint32 callbackData, 
 				     Uint32 returnCode)
 {
+  jam();
   CreateObjRecordPtr createObjPtr;  
-  SegmentedSectionPtr objInfoPtr;
   
   ndbrequire(returnCode == 0);
   ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
-  jam();
-  getSection(objInfoPtr, createObjPtr.p->m_obj_info_ptr_i);
-  if(createObjPtr.p->m_errorCode != 0){
+  SectionHandle handle(this, createObjPtr.p->m_obj_info_ptr_i);
+
+  if(createObjPtr.p->m_errorCode != 0)
+  {
     jam();
     createObjPtr.p->m_obj_info_ptr_i= RNIL;
-    signal->setSection(objInfoPtr, 0);
-    releaseSections(signal);
+    releaseSections(handle);
     createObj_prepare_complete_done(signal, callbackData, 0);
     return;
   }
@@ -15358,13 +15391,14 @@ Dbdict::createObj_prepare_start_done(Sig
   tabEntry.m_tableType    = createObjPtr.p->m_obj_type;
   tabEntry.m_tableState   = SchemaFile::ADD_STARTED;
   tabEntry.m_gcp          = createObjPtr.p->m_gci;
-  tabEntry.m_info_words   = objInfoPtr.sz;
+  tabEntry.m_info_words   = handle.m_ptr[0].sz;
   
   Callback cb;
   cb.m_callbackData = createObjPtr.p->key;
   cb.m_callbackFunction = safe_cast(&Dbdict::createObj_writeSchemaConf1);
   
   updateSchemaState(signal, createObjPtr.p->m_obj_id, &tabEntry, &cb);
+  handle.clear();
 }
 
 void
@@ -15374,7 +15408,6 @@ Dbdict::createObj_writeSchemaConf1(Signa
 {
   CreateObjRecordPtr createObjPtr;  
   Callback callback;
-  SegmentedSectionPtr objInfoPtr;
 
   jam();
   ndbrequire(returnCode == 0);
@@ -15383,11 +15416,10 @@ Dbdict::createObj_writeSchemaConf1(Signa
   callback.m_callbackData = createObjPtr.p->key;
   callback.m_callbackFunction = safe_cast(&Dbdict::createObj_writeObjConf);
   
-  getSection(objInfoPtr, createObjPtr.p->m_obj_info_ptr_i);
-  writeTableFile(signal, createObjPtr.p->m_obj_id, objInfoPtr, &callback);
+  SectionHandle handle(this, createObjPtr.p->m_obj_info_ptr_i);
+  writeTableFile(signal, createObjPtr.p->m_obj_id, handle.m_ptr[0], &callback);
   
-  signal->setSection(objInfoPtr, 0);
-  releaseSections(signal);
+  releaseSections(handle);
   createObjPtr.p->m_obj_info_ptr_i = RNIL;
 }
 
@@ -15967,8 +15999,8 @@ Dbdict::create_fg_prepare_start(Signal* 
   /**
    * Put data into table record
    */
-  SegmentedSectionPtr objInfoPtr;
   jam();
+  SegmentedSectionPtr objInfoPtr;
   getSection(objInfoPtr, ((OpCreateObj*)op)->m_obj_info_ptr_i);
   SimplePropertiesSectionReader it(objInfoPtr, getSectionSegmentPool());
 
diff -Nrup a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp
--- a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp	2007-05-15 09:13:18 +02:00
+++ b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp	2007-09-24 17:09:26 +02:00
@@ -2391,10 +2391,12 @@ private:
   void dropEvent_sendReply(Signal* signal,
 			   OpDropEventPtr evntRecPtr);
 
-  void createEvent_RT_USER_CREATE(Signal* signal, OpCreateEventPtr evntRecPtr);
+  void createEvent_RT_USER_CREATE(Signal* signal,
+				  OpCreateEventPtr evntRecPtr,
+				  SectionHandle& handle);
   void createEventComplete_RT_USER_CREATE(Signal* signal,
 					  OpCreateEventPtr evntRecPtr);
-  void createEvent_RT_USER_GET(Signal* signal, OpCreateEventPtr evntRecPtr);
+  void createEvent_RT_USER_GET(Signal*, OpCreateEventPtr, SectionHandle&);
   void createEventComplete_RT_USER_GET(Signal* signal, OpCreateEventPtr evntRecPtr);
 
   void createEvent_RT_DICT_AFTER_GET(Signal* signal, OpCreateEventPtr evntRecPtr);
diff -Nrup a/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp b/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
--- a/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp	2007-09-18 15:18:38 +02:00
+++ b/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp	2007-09-24 17:09:26 +02:00
@@ -7163,12 +7163,11 @@ void Dbdih::execDIADDTABREQ(Signal* sign
     Uint16 fragments[2 + MAX_FRAG_PER_NODE*MAX_REPLICAS*MAX_NDB_NODES];
     Uint32 align;
   };
+  SectionHandle handle(this, signal);
   SegmentedSectionPtr fragDataPtr;
-  LINT_INIT(fragDataPtr.i);
-  LINT_INIT(fragDataPtr.sz);
-  signal->getSection(fragDataPtr, DiAddTabReq::FRAGMENTATION);
+  ndbrequire(handle.getSection(fragDataPtr, DiAddTabReq::FRAGMENTATION));
   copy((Uint32*)fragments, fragDataPtr);
-  releaseSections(signal);
+  releaseSections(handle);
   
   const Uint32 noReplicas = fragments[0];
   const Uint32 noFragments = fragments[1];
diff -Nrup a/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp b/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
--- a/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp	2007-09-12 13:35:57 +02:00
+++ b/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp	2007-09-24 17:09:26 +02:00
@@ -8888,10 +8888,11 @@ void Dbtc::execSCAN_TABREQ(Signal* signa
 
   jamEntry();
 
+  SectionHandle handle(this, signal);
   SegmentedSectionPtr api_op_ptr;
-  signal->getSection(api_op_ptr, 0);
+  handle.getSection(api_op_ptr, 0);
   copy(&cdata[0], api_op_ptr);
-  releaseSections(signal);
+  releaseSections(handle);
 
   apiConnectptr.i = scanTabReq->apiConnectPtr;
   tabptr.i = scanTabReq->tableId;
@@ -11610,8 +11611,6 @@ void Dbtc::execCREATE_TRIG_REQ(Signal* s
   DefinedTriggerPtr triggerPtr;
   BlockReference sender = signal->senderBlockRef();
 
-  releaseSections(signal);
-  
   triggerPtr.i = createTrigReq->getTriggerId();
   if (ERROR_INSERTED(8033) ||
       !c_theDefinedTriggers.seizeId(triggerPtr, 
@@ -11683,7 +11682,8 @@ void Dbtc::execCREATE_INDX_REQ(Signal* s
   TcIndexData* indexData;
   TcIndexDataPtr indexPtr;
   BlockReference sender = signal->senderBlockRef();
-  
+
+  SectionHandle handle(this, signal);
   if (ERROR_INSERTED(8034) ||
       !c_theIndexes.seizeId(indexPtr, createIndxReq->getIndexId())) {
     jam();
@@ -11694,7 +11694,7 @@ void Dbtc::execCREATE_INDX_REQ(Signal* s
 
      createIndxRef->setConnectionPtr(createIndxReq->getConnectionPtr());
      createIndxRef->setErrorCode(CreateIndxRef::TooManyIndexes);
-     releaseSections(signal);
+     releaseSections(handle);
      sendSignal(sender, GSN_CREATE_INDX_REF, 
                 signal, CreateIndxRef::SignalLength, JBB);
      return;
@@ -11708,7 +11708,7 @@ void Dbtc::execCREATE_INDX_REQ(Signal* s
 
   // So far need only attribute count
   SegmentedSectionPtr ssPtr;
-  signal->getSection(ssPtr, CreateIndxReq::ATTRIBUTE_LIST_SECTION);
+  handle.getSection(ssPtr, CreateIndxReq::ATTRIBUTE_LIST_SECTION);
   SimplePropertiesSectionReader r0(ssPtr, getSectionSegmentPool());
   r0.reset(); // undo implicit first()
   if (!r0.getWord(&indexData->attributeList.sz) ||
@@ -11717,7 +11717,7 @@ void Dbtc::execCREATE_INDX_REQ(Signal* s
   }
   indexData->primaryKeyPos = indexData->attributeList.sz;
 
-  releaseSections(signal);
+  releaseSections(handle);
   
   CreateIndxConf * const createIndxConf =  
     (CreateIndxConf *)&signal->theData[0];
@@ -12475,12 +12475,15 @@ void Dbtc::execTRANSID_AI_R(Signal* sign
 
   jamEntry();
 
+  SectionHandle handle(this, signal);
+
   /**
    * Forward signal to final destination
    * Truncate last word since that was used to hold the final dest.
    */
   sendSignal(recBlockref, GSN_TRANSID_AI,
-	     signal, sigLen - 1, JBB);
+	     signal, sigLen - 1, JBB,
+	     &handle);
 }
 
 void Dbtc::execKEYINFO20_R(Signal* signal){
@@ -12490,13 +12493,16 @@ void Dbtc::execKEYINFO20_R(Signal* signa
   Uint32 recBlockref = keyInfo->keyData[dataLen];
 
   jamEntry();
+
+  SectionHandle handle(this, signal);
   
   /**
    * Forward signal to final destination
    * Truncate last word since that was used to hold the final dest.
    */
   sendSignal(recBlockref, GSN_KEYINFO20,
-	     signal, sigLen - 1, JBB);
+	     signal, sigLen - 1, JBB,
+	     &handle);
 }
 
 
@@ -13897,6 +13903,8 @@ Dbtc::execROUTE_ORD(Signal* signal)
     return;
   }
 
+  SectionHandle handle(this, signal);
+
   RouteOrd* ord = (RouteOrd*)signal->getDataPtr();
   Uint32 dstRef = ord->dstRef;
   Uint32 srcRef = ord->srcRef;
@@ -13905,38 +13913,33 @@ Dbtc::execROUTE_ORD(Signal* signal)
   if (likely(getNodeInfo(refToNode(dstRef)).m_connected))
   {
     jam();
-    Uint32 secCount = signal->getNoOfSections();
-    SegmentedSectionPtr ptr[3];
+    Uint32 secCount = handle.m_cnt;
     ndbrequire(secCount >= 1 && secCount <= 3);
 
     jamLine(secCount);
-    for (Uint32 i = 0; i<secCount; i++)
-      signal->getSection(ptr[i], i);
 
     /**
      * Put section 0 in signal->theData
      */
-    ndbrequire(ptr[0].sz <= 25);
-    copy(signal->theData, ptr[0]);
-
-    signal->header.m_noOfSections = 0;
-    
-    /**
-     * Shift rest of sections
-     */
-    for(Uint32 i = 1; i<secCount; i++)
-    {
-      signal->setSection(ptr[i], i - 1);
-    }
-
-    sendSignal(dstRef, gsn, signal, ptr[0].sz, JBB);
-
-    signal->header.m_noOfSections = 0;
-    signal->setSection(ptr[0], 0);
-    releaseSections(signal);
+    Uint32 sigLen = handle.m_ptr[0].sz;
+    ndbrequire(sigLen <= 25);
+    copy(signal->theData, handle.m_ptr[0]);
+
+    SegmentedSectionPtr save = handle.m_ptr[0];
+    for (Uint32 i = 0; i < secCount - 1; i++)
+      handle.m_ptr[i] = handle.m_ptr[i+1];
+    handle.m_cnt--;
+
+    sendSignal(dstRef, gsn, signal, sigLen, JBB, &handle);
+
+    handle.m_cnt = 1;
+    handle.m_ptr[0] = save;
+    releaseSections(handle);
     return ;
   }
 
+  releaseSections(handle);
   warningEvent("Unable to route GSN: %d from %x to %x",
 	       gsn, srcRef, dstRef);
+
 }
diff -Nrup a/storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp	2007-08-07 09:49:20 +02:00
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp	2007-09-24 17:09:26 +02:00
@@ -608,10 +608,11 @@ Dbtup::execALTER_TAB_REQ(Signal *signal)
   if(!assembleFragments(signal))
     return;
   AlterTabReq *const req= (AlterTabReq *)signal->getDataPtr();
+  SectionHandle handle(this, signal);
   if (!AlterTableReq::getAddAttrFlag(req->changeMask))
   {
     /* Nothing to do in TUP. */
-    releaseSections(signal);
+    releaseSections(handle);
     sendAlterTabConf(signal, req);
     return;
   }
@@ -625,13 +626,19 @@ Dbtup::execALTER_TAB_REQ(Signal *signal)
 
   if(alterType==AlterTabReq::AlterTablePrepare)
   {
+    jam();
+    ndbrequire(handle.m_cnt == 1);
+    copy(signal->theData+25, handle.m_ptr[0]);
+    releaseSections(handle);
     handleAlterTabPrepare(signal, regTabPtr.p);
     return;
   }
+  releaseSections(handle);
 
   AlterTabOperationPtr regAlterTabOpPtr;
   if (req->clientData==RNIL)
   {
+    jam();
     /* This means that we failed in prepare, or never got there. */
     sendAlterTabConf(signal, req);
     return;
@@ -662,15 +669,7 @@ Dbtup::handleAlterTabPrepare(Signal *sig
   Uint32 newNoOfCharsets= req->newNoOfCharsets;
   Uint32 newNoOfKeyAttrs= req->newNoOfKeyAttrs;
 
-  ndbrequire(signal->getNoOfSections() == 1);
-  ndbrequire((25+noOfNewAttr*2)<<2 < sizeof(signal->theData));
-
-  /* Get the array of attribute descriptor words. */
-  SegmentedSectionPtr ssPtr;
   Uint32 *attrInfo= signal->theData+25;
-  signal->getSection(ssPtr, 0);
-  copy(attrInfo, ssPtr);
-  releaseSections(signal);
 
   Uint32 oldNoOfAttr= regTabPtr->m_no_of_attributes;
   Uint32 newNoOfAttr= oldNoOfAttr+noOfNewAttr;
diff -Nrup a/storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp	2007-08-13 17:07:42 +02:00
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp	2007-09-24 17:09:26 +02:00
@@ -2172,8 +2172,9 @@ Dbtup::read_pseudo(const Uint32 * inBuff
   Uint32* outBuffer = outBuf + ((outPos - 1) >> 2);
   
   Uint32 sz;
-  Uint32 tmp[sizeof(SignalHeader)+25];
-  Signal * signal = (Signal*)&tmp;
+  SignalT<4> signalT;
+  Signal * signal = (Signal*)&signalT;
+  bzero(signal, sizeof(signalT));
   switch(attrId){
   case AttributeHeader::READ_PACKED:
   case AttributeHeader::READ_ALL:
diff -Nrup a/storage/ndb/src/kernel/blocks/dbutil/DbUtil.cpp b/storage/ndb/src/kernel/blocks/dbutil/DbUtil.cpp
--- a/storage/ndb/src/kernel/blocks/dbutil/DbUtil.cpp	2006-12-23 20:20:17 +01:00
+++ b/storage/ndb/src/kernel/blocks/dbutil/DbUtil.cpp	2007-09-24 17:09:26 +02:00
@@ -791,7 +791,6 @@ DbUtil::execUTIL_PREPARE_REQ(Signal* sig
   if(signal->getNoOfSections() == 0) {
     // Missing prepare data
     jam();
-    releaseSections(signal);
     sendUtilPrepareRef(signal, UtilPrepareRef::MISSING_PROPERTIES_SECTION,
 		       senderRef, senderData);
     return;
@@ -799,21 +798,22 @@ DbUtil::execUTIL_PREPARE_REQ(Signal* sig
 
   PreparePtr prepPtr;
   SegmentedSectionPtr ptr;
+  SectionHandle handle(this, signal);
   
   jam();
   if(!c_runningPrepares.seize(prepPtr)) {
     jam();
-    releaseSections(signal);
+    releaseSections(handle);
     sendUtilPrepareRef(signal, UtilPrepareRef::PREPARE_SEIZE_ERROR,
 		       senderRef, senderData);
     return;
   };
-  signal->getSection(ptr, UtilPrepareReq::PROPERTIES_SECTION);
+  handle.getSection(ptr, UtilPrepareReq::PROPERTIES_SECTION);
   const Uint32 noPages  = (ptr.sz + sizeof(Page32)) / sizeof(Page32);
   ndbassert(noPages > 0);
   if (!prepPtr.p->preparePages.seize(noPages)) {
     jam();
-    releaseSections(signal);
+    releaseSections(handle);
     sendUtilPrepareRef(signal, UtilPrepareRef::PREPARE_PAGES_SEIZE_ERROR,
 		       senderRef, senderData);
     c_preparePool.release(prepPtr);
@@ -824,13 +824,12 @@ DbUtil::execUTIL_PREPARE_REQ(Signal* sig
   copy(target, ptr);
   prepPtr.p->prepDataLen = ptr.sz;
   // Release long signal sections
-  releaseSections(signal);
+  releaseSections(handle);
   // Check table properties with DICT
   SimplePropertiesSectionReader reader(ptr, getSectionSegmentPool());
   prepPtr.p->clientRef = senderRef;
   prepPtr.p->clientData = senderData;
   // Release long signal sections
-  releaseSections(signal);
   readPrepareProps(signal, &reader, prepPtr.i);
 }
 
@@ -917,13 +916,15 @@ DbUtil::execGET_TABINFO_CONF(Signal* sig
   const Uint32  prepI    = conf->senderData;
   const Uint32  totalLen = conf->totalLen;
   
+  SectionHandle handle(this, signal);
   SegmentedSectionPtr dictTabInfoPtr;
-  signal->getSection(dictTabInfoPtr, GetTabInfoConf::DICT_TAB_INFO);
+  handle.getSection(dictTabInfoPtr, GetTabInfoConf::DICT_TAB_INFO);
   ndbrequire(dictTabInfoPtr.sz == totalLen);
   
   PreparePtr prepPtr;
   c_runningPrepares.getPtr(prepPtr, prepI);
-  prepareOperation(signal, prepPtr);
+  prepareOperation(signal, prepPtr, dictTabInfoPtr);
+  releaseSections(handle);
 }
 
 void
@@ -980,7 +981,9 @@ DbUtil::execGET_TABINFOREF(Signal* signa
  *    - if (isPK) then assign offset
  ******************************************************************************/
 void
-DbUtil::prepareOperation(Signal* signal, PreparePtr prepPtr) 
+DbUtil::prepareOperation(Signal* signal,
+			 PreparePtr prepPtr,
+			 SegmentedSectionPtr ptr)
 {
   jam();
   
@@ -990,7 +993,6 @@ DbUtil::prepareOperation(Signal* signal,
   PreparedOperationPtr prepOpPtr;  
   if(!c_preparedOperationPool.seize(prepOpPtr)) {
     jam();
-    releaseSections(signal);
     sendUtilPrepareRef(signal, UtilPrepareRef::PREPARED_OPERATION_SEIZE_ERROR,
 		       prepPtr.p->clientRef, prepPtr.p->clientData);
     releasePrepare(prepPtr);
@@ -1090,10 +1092,7 @@ DbUtil::prepareOperation(Signal* signal,
      * Copy DictTabInfo into tableDesc struct
      *****************************************/
       
-    SegmentedSectionPtr ptr;
-    signal->getSection(ptr, GetTabInfoConf::DICT_TAB_INFO);
     SimplePropertiesSectionReader dictInfoReader(ptr, getSectionSegmentPool());
-
     SimpleProperties::UnpackStatus unpackStatus;
     unpackStatus = SimpleProperties::unpack(dictInfoReader, &tableDesc, 
 					    DictTabInfo::TableMapping, 
@@ -1155,7 +1154,6 @@ DbUtil::prepareOperation(Signal* signal,
      **********************/
     if (!attributeFound) {
       jam(); 
-      releaseSections(signal);
       sendUtilPrepareRef(signal, 
 			 UtilPrepareRef::DICT_TAB_INFO_ERROR,
 			 prepPtr.p->clientRef, prepPtr.p->clientData);
@@ -1188,7 +1186,6 @@ DbUtil::prepareOperation(Signal* signal,
        ***********************************************************/
       if (noOfPKAttribsStored != tableDesc.NoOfKeyAttr) {
 	jam(); 
-	releaseSections(signal);
 	sendUtilPrepareRef(signal, 
 			   UtilPrepareRef::DICT_TAB_INFO_ERROR,
 			   prepPtr.p->clientRef, prepPtr.p->clientData);
@@ -1248,7 +1245,6 @@ DbUtil::prepareOperation(Signal* signal,
    ***************************/
   if (noOfPKAttribsStored != tableDesc.NoOfKeyAttr) {
     jam(); 
-    releaseSections(signal);
     sendUtilPrepareRef(signal, 
 		       UtilPrepareRef::DICT_TAB_INFO_ERROR,
 		       prepPtr.p->clientRef, prepPtr.p->clientData);
@@ -1335,7 +1331,6 @@ DbUtil::prepareOperation(Signal* signal,
   conf->senderData = prepPtr.p->clientData;
   conf->prepareId = prepPtr.p->prepOpPtr.i;
 
-  releaseSections(signal);
   sendSignal(prepPtr.p->clientRef, GSN_UTIL_PREPARE_CONF, signal, 
 	     UtilPrepareConf::SignalLength, JBB);
 
@@ -1729,7 +1724,6 @@ DbUtil::execUTIL_EXECUTE_REQ(Signal* sig
   if(signal->getNoOfSections() == 0) {
     // Missing prepare data
     jam();
-    releaseSections(signal);
     sendUtilExecuteRef(signal, UtilExecuteRef::MissingDataSection, 
 		       0, clientRef, clientData);
     return;
@@ -1744,11 +1738,12 @@ DbUtil::execUTIL_EXECUTE_REQ(Signal* sig
 
   TransactionPtr  transPtr;
   OperationPtr    opPtr;
+  SectionHandle handle(this, signal);
   SegmentedSectionPtr headerPtr, dataPtr;
 
-  signal->getSection(headerPtr, UtilExecuteReq::HEADER_SECTION);
+  handle.getSection(headerPtr, UtilExecuteReq::HEADER_SECTION);
   SectionReader headerReader(headerPtr, getSectionSegmentPool());
-  signal->getSection(dataPtr, UtilExecuteReq::DATA_SECTION);
+  handle.getSection(dataPtr, UtilExecuteReq::DATA_SECTION);
   SectionReader dataReader(dataPtr, getSectionSegmentPool());
 
 #if 0 //def EVENT_DEBUG
@@ -1836,7 +1831,7 @@ DbUtil::execUTIL_EXECUTE_REQ(Signal* sig
     if (!res) {
       // Failed to allocate buffer data
       jam();
-      releaseSections(signal);
+      releaseSections(handle);
       sendUtilExecuteRef(signal, UtilExecuteRef::AllocationError, 
 			 0, clientRef, clientData);
       releaseTransaction(transPtr);    
@@ -1846,7 +1841,7 @@ DbUtil::execUTIL_EXECUTE_REQ(Signal* sig
   if (!dataComplete) {
     // Missing data in data section
     jam();
-    releaseSections(signal);
+    releaseSections(handle);
     sendUtilExecuteRef(signal, UtilExecuteRef::MissingData, 
 		       0, clientRef, clientData);
     releaseTransaction(transPtr);    
@@ -1872,7 +1867,7 @@ DbUtil::execUTIL_EXECUTE_REQ(Signal* sig
   }
 #endif
 
-  releaseSections(signal);
+  releaseSections(handle);
   transPtr.p->noOfRetries = 3;
   runTransaction(signal, transPtr);
 }
diff -Nrup a/storage/ndb/src/kernel/blocks/dbutil/DbUtil.hpp b/storage/ndb/src/kernel/blocks/dbutil/DbUtil.hpp
--- a/storage/ndb/src/kernel/blocks/dbutil/DbUtil.hpp	2006-12-23 20:20:17 +01:00
+++ b/storage/ndb/src/kernel/blocks/dbutil/DbUtil.hpp	2007-09-24 17:09:26 +02:00
@@ -413,7 +413,7 @@ public:
   void readPrepareProps(Signal* signal, 
 			SimpleProperties::Reader* reader, 
 			Uint32 senderData);
-  void prepareOperation(Signal*, PreparePtr);
+  void prepareOperation(Signal*, PreparePtr, SegmentedSectionPtr);
   void sendUtilPrepareRef(Signal*, UtilPrepareRef::ErrorCode, Uint32, Uint32);
   void sendUtilExecuteRef(Signal*, UtilExecuteRef::ErrorCode, 
 			  Uint32, Uint32, Uint32);
diff -Nrup a/storage/ndb/src/kernel/blocks/lgman.cpp b/storage/ndb/src/kernel/blocks/lgman.cpp
--- a/storage/ndb/src/kernel/blocks/lgman.cpp	2007-07-04 09:53:36 +02:00
+++ b/storage/ndb/src/kernel/blocks/lgman.cpp	2007-09-24 17:09:25 +02:00
@@ -488,6 +488,7 @@ Lgman::execCREATE_FILE_REQ(Signal* signa
   
   Ptr<Logfile_group> ptr;
   CreateFileImplRef::ErrorCode err = CreateFileImplRef::NoError;
+  SectionHandle handle(this, signal);
   do {
     if (!m_logfile_group_hash.find(ptr, req->filegroup_id))
     {
@@ -546,16 +547,22 @@ Lgman::execCREATE_FILE_REQ(Signal* signa
       err = CreateFileImplRef::OutOfFileRecords;
       break;
     }
+
+    if (!handle.m_cnt == 1)
+    {
+      ndbrequire(false);
+    }
     
     new (file_ptr.p) Undofile(req, ptr.i);
 
     Local_undofile_list tmp(m_file_pool, ptr.p->m_meta_files);
     tmp.add(file_ptr);
     
-    open_file(signal, file_ptr, req->requestInfo);
+    open_file(signal, file_ptr, req->requestInfo, &handle);
     return;
   } while(0);
   
+  releaseSections(handle);
   CreateFileImplRef* ref= (CreateFileImplRef*)signal->getDataPtr();
   ref->senderData = senderData;
   ref->senderRef = reference();
@@ -565,7 +572,9 @@ Lgman::execCREATE_FILE_REQ(Signal* signa
 }
 
 void
-Lgman::open_file(Signal* signal, Ptr<Undofile> ptr, Uint32 requestInfo)
+Lgman::open_file(Signal* signal, Ptr<Undofile> ptr,
+		 Uint32 requestInfo,
+		 SectionHandle * handle)
 {
   FsOpenReq* req = (FsOpenReq*)signal->getDataPtrSend();
   req->userReference = reference();
@@ -602,8 +611,8 @@ Lgman::open_file(Signal* signal, Ptr<Und
   req->file_size_hi = size >> 32;
   req->file_size_lo = size & 0xFFFFFFFF;
 
-  // Forward filename
-  sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, FsOpenReq::SignalLength, JBB);
+  sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, FsOpenReq::SignalLength, JBB,
+	     handle);
 }
 
 void
@@ -3129,10 +3138,11 @@ void Lgman::execGET_TABINFOREQ(Signal* s
   Uint32 senderData= req->senderData;
   Uint32 tableId= req->tableId;
 
-  if(reqType == GetTabInfoReq::RequestByName){
+  if(reqType == GetTabInfoReq::RequestByName)
+  {
     jam();
-    if(signal->getNoOfSections())
-      releaseSections(signal);
+    SectionHandle handle(this, signal);
+    releaseSections(handle);
 
     sendGET_TABINFOREF(signal, req, GetTabInfoRef::NoFetchByName);
     return;
@@ -3146,8 +3156,6 @@ void Lgman::execGET_TABINFOREQ(Signal* s
   if(ptr.p->m_logfile_group_id != tableId)
   {
     jam();
-    if(signal->getNoOfSections())
-      releaseSections(signal);
 
     sendGET_TABINFOREF(signal, req, GetTabInfoRef::InvalidTableId);
     return;
diff -Nrup a/storage/ndb/src/kernel/blocks/lgman.hpp b/storage/ndb/src/kernel/blocks/lgman.hpp
--- a/storage/ndb/src/kernel/blocks/lgman.hpp	2007-07-03 14:12:24 +02:00
+++ b/storage/ndb/src/kernel/blocks/lgman.hpp	2007-09-24 17:09:25 +02:00
@@ -272,7 +272,7 @@ private:
   
   void cut_log_tail(Signal*, Ptr<Logfile_group> ptr);
   void endlcp_callback(Signal*, Uint32, Uint32);
-  void open_file(Signal*, Ptr<Undofile>, Uint32 requestInfo);
+  void open_file(Signal*, Ptr<Undofile>, Uint32, SectionHandle*);
 
   void flush_log(Signal*, Ptr<Logfile_group>, Uint32 force);
   Uint32 write_log_pages(Signal*, Ptr<Logfile_group>, 
diff -Nrup a/storage/ndb/src/kernel/blocks/ndbfs/AsyncFile.cpp b/storage/ndb/src/kernel/blocks/ndbfs/AsyncFile.cpp
--- a/storage/ndb/src/kernel/blocks/ndbfs/AsyncFile.cpp	2007-08-27 20:57:18 +02:00
+++ b/storage/ndb/src/kernel/blocks/ndbfs/AsyncFile.cpp	2007-09-24 17:09:26 +02:00
@@ -524,8 +524,9 @@ no_odirect:
   {
     off_t off = 0;
     const off_t sz = request->par.open.file_size;
-    Uint32 tmp[sizeof(SignalHeader)+25];
-    Signal * signal = (Signal*)(&tmp[0]);
+    SignalT<25> tmp;
+    Signal * signal = (Signal*)&tmp;
+    bzero(signal, sizeof(tmp));
     FsReadWriteReq* req = (FsReadWriteReq*)signal->getDataPtrSend();
 
     Uint32 index = 0;
diff -Nrup a/storage/ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp b/storage/ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp
--- a/storage/ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp	2007-05-30 20:29:11 +02:00
+++ b/storage/ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp	2007-09-24 17:09:26 +02:00
@@ -211,10 +211,11 @@ Ndbfs::execFSOPENREQ(Signal* signal)
     file->theFileName.set(spec, userRef, fsOpenReq->fileNumber);
   } else {
     jam();
+    SectionHandle handle(this, signal);
     SegmentedSectionPtr ptr;
-    signal->getSection(ptr, FsOpenReq::FILENAME);
+    handle.getSection(ptr, FsOpenReq::FILENAME);
     file->theFileName.set(spec, ptr, g_sectionSegmentPool);
-    releaseSections(signal);
+    releaseSections(handle);
   }
   file->reportTo(&theFromThreads);
   if (getenv("NDB_TRACE_OPEN"))
diff -Nrup a/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp b/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp
--- a/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp	2007-09-12 13:30:24 +02:00
+++ b/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp	2007-09-24 17:09:26 +02:00
@@ -5145,6 +5145,7 @@ Qmgr::execAPI_BROADCAST_REP(Signal* sign
   jamEntry();
   ApiBroadcastRep api= *(const ApiBroadcastRep*)signal->getDataPtr();
 
+  SectionHandle handle(this, signal);
   Uint32 len = signal->getLength() - ApiBroadcastRep::SignalLength;
   memmove(signal->theData, signal->theData+ApiBroadcastRep::SignalLength, 
 	  4*len);
@@ -5163,7 +5164,8 @@ Qmgr::execAPI_BROADCAST_REP(Signal* sign
   }
   
   NodeReceiverGroup rg(API_CLUSTERMGR, mask);
-  sendSignal(rg, api.gsn, signal, len, JBB); // forward sections
+  sendSignal(rg, api.gsn, signal, len, JBB,
+	     &handle);
 }
 
 void
diff -Nrup a/storage/ndb/src/kernel/blocks/suma/Suma.cpp b/storage/ndb/src/kernel/blocks/suma/Suma.cpp
--- a/storage/ndb/src/kernel/blocks/suma/Suma.cpp	2007-09-13 13:59:45 +02:00
+++ b/storage/ndb/src/kernel/blocks/suma/Suma.cpp	2007-09-24 17:09:26 +02:00
@@ -1108,7 +1108,6 @@ Suma::sendSubIdRef(Signal* signal,
 	     CreateSubscriptionIdRef::SignalLength,
 	     JBB);
   
-  releaseSections(signal);
   DBUG_VOID_RETURN;
 }
 
@@ -1276,11 +1275,13 @@ Suma::execSUB_SYNC_REQ(Signal* signal)
   DBUG_PRINT("enter",("key.m_subscriptionId: %u, key.m_subscriptionKey: %u",
 		      key.m_subscriptionId, key.m_subscriptionKey));
 
+  SectionHandle handle(this, signal);
   if(!c_subscriptions.find(subPtr, key))
   {
     jam();
     DBUG_PRINT("info",("Not found"));
     sendSubSyncRef(signal, 1407);
+    releaseSections(handle);
     DBUG_VOID_RETURN;
   }
 
@@ -1292,6 +1293,7 @@ Suma::execSUB_SYNC_REQ(Signal* signal)
   {
     jam();
     sendSubSyncRef(signal, 1416);
+    releaseSections(handle);
     DBUG_VOID_RETURN;
   }
   DBUG_PRINT("info",("c_syncPool  size: %d free: %d",
@@ -1309,12 +1311,13 @@ Suma::execSUB_SYNC_REQ(Signal* signal)
   {
     jam();
     syncPtr.p->m_tableList.append(&subPtr.p->m_tableId, 1);
-    if(signal->getNoOfSections() > 0){
-      SegmentedSectionPtr ptr(0,0,0);
-      signal->getSection(ptr, SubSyncReq::ATTRIBUTE_LIST);
+    if(handle.m_cnt > 0)
+    {
+      SegmentedSectionPtr ptr;
+      handle.getSection(ptr, SubSyncReq::ATTRIBUTE_LIST);
       LocalDataBuffer<15> attrBuf(c_dataBufferPool,syncPtr.p->m_attributeList);
       append(attrBuf, ptr, getSectionSegmentPool());
-      releaseSections(signal);
+      releaseSections(handle);
     }
   }
 
@@ -1374,7 +1377,6 @@ Suma::sendSubSyncRef(Signal* signal, Uin
   jam();
   SubSyncRef * ref= (SubSyncRef *)signal->getDataPtrSend();
   ref->errorCode = errCode;
-  releaseSections(signal);
   sendSignal(signal->getSendersBlockRef(), 
 	     GSN_SUB_SYNC_REF, 
 	     signal, 
@@ -1752,14 +1754,16 @@ Suma::execGET_TABINFO_CONF(Signal* signa
     return;
   }
   
+  SectionHandle handle(this, signal);
   GetTabInfoConf* conf = (GetTabInfoConf*)signal->getDataPtr();
   Uint32 tableId = conf->tableId;
   TablePtr tabPtr;
   c_tablePool.getPtr(tabPtr, conf->senderData);
-  SegmentedSectionPtr ptr(0,0,0);
-  signal->getSection(ptr, GetTabInfoConf::DICT_TAB_INFO);
+  SegmentedSectionPtr ptr;
+  handle.getSection(ptr, GetTabInfoConf::DICT_TAB_INFO);
   ndbrequire(tabPtr.p->parseTable(ptr, *this));
-  releaseSections(signal);
+  releaseSections(handle);
+
   /**
    * We need to gather fragment info
    */
@@ -2446,7 +2450,6 @@ Suma::sendSubStartRef(Signal* signal, Ui
   SubStartRef * ref = (SubStartRef *)signal->getDataPtrSend();
   ref->senderRef = reference();
   ref->errorCode = errCode;
-  releaseSections(signal);
   sendSignal(signal->getSendersBlockRef(), GSN_SUB_START_REF, signal, 
 	     SubStartRef::SignalLength, JBB);
 }
@@ -3766,7 +3769,6 @@ Suma::execALTER_TAB_REQ(Signal *signal)
 {
   jamEntry();
   DBUG_ENTER("Suma::execALTER_TAB_REQ");
-  ndbassert(signal->getNoOfSections() == 1);
 
   AlterTabReq * const req = (AlterTabReq*)signal->getDataPtr();
   Uint32 senderRef= req->senderRef;
@@ -3793,11 +3795,14 @@ Suma::execALTER_TAB_REQ(Signal *signal)
   // dict coordinator sends info to API
 
   // Copy DICT_TAB_INFO to local buffer
+  SectionHandle handle(this, signal->theData[AlterTabReq::SignalLength]);
   SegmentedSectionPtr tabInfoPtr;
-  signal->getSection(tabInfoPtr, AlterTabReq::DICT_TAB_INFO);
+  handle.getSection(tabInfoPtr, 0);
+  handle.clear();
 #ifndef DBUG_OFF
   ndbout_c("DICT_TAB_INFO in SUMA,  tabInfoPtr.sz = %d", tabInfoPtr.sz);
-  SimplePropertiesSectionReader reader(tabInfoPtr, getSectionSegmentPool());
+  SimplePropertiesSectionReader reader(handle.m_ptr[0],
+				       getSectionSegmentPool());
   reader.printAll(ndbout);
 #endif
   copy(b_dti_buf, tabInfoPtr);
@@ -3805,8 +3810,6 @@ Suma::execALTER_TAB_REQ(Signal *signal)
   ptr[0].p = b_dti_buf;
   ptr[0].sz = tabInfoPtr.sz;
 
-  releaseSections(signal);
-
   const Uint64 gci = get_current_gci(signal);
   SubTableData * data = (SubTableData*)signal->getDataPtrSend();
   data->gci_hi         = Uint32(gci >> 32);
@@ -3838,9 +3841,8 @@ Suma::execALTER_TAB_REQ(Signal *signal)
       }
 
       data->senderData= subbPtr.p->m_senderData;
-      Callback c = { 0, 0 };
       sendFragmentedSignal(subbPtr.p->m_senderRef, GSN_SUB_TABLE_DATA, signal,
-                           SubTableData::SignalLength, JBB, ptr, 1, c);
+                           SubTableData::SignalLength, JBB, ptr, 1);
       DBUG_PRINT("info",("sent to subscriber %d", subbPtr.i));
     }
   }
@@ -4080,7 +4082,6 @@ Suma::sendSubRemoveRef(Signal* signal, c
   ref->subscriptionId = req.subscriptionId;
   ref->subscriptionKey = req.subscriptionKey;
   ref->errorCode = errCode;
-  releaseSections(signal);
   sendSignal(signal->getSendersBlockRef(), GSN_SUB_REMOVE_REF, 
 	     signal, SubRemoveRef::SignalLength, JBB);
   DBUG_VOID_RETURN;
diff -Nrup a/storage/ndb/src/kernel/blocks/trix/Trix.cpp b/storage/ndb/src/kernel/blocks/trix/Trix.cpp
--- a/storage/ndb/src/kernel/blocks/trix/Trix.cpp	2007-01-06 01:21:24 +01:00
+++ b/storage/ndb/src/kernel/blocks/trix/Trix.cpp	2007-09-24 17:09:26 +02:00
@@ -451,13 +451,14 @@ void Trix:: execBUILDINDXREQ(Signal* sig
   // Seize a subscription record
   SubscriptionRecPtr subRecPtr;
   SubscriptionRecord* subRec;
-  
+  SectionHandle handle(this, signal);
+
   if (!c_theSubscriptions.seizeId(subRecPtr, buildIndxReq->getBuildId())) {
     // Failed to allocate subscription record
     BuildIndxRef * buildIndxRef = (BuildIndxRef *)signal->getDataPtrSend();
 
     buildIndxRef->setErrorCode(BuildIndxRef::AllocationFailure);
-    releaseSections(signal);
+    releaseSections(handle);
     sendSignal(buildIndxReq->getUserRef(), 
 	       GSN_BUILDINDXREF, signal, BuildIndxRef::SignalLength, JBB);
     DBUG_VOID_RETURN;
@@ -478,16 +479,16 @@ void Trix:: execBUILDINDXREQ(Signal* sig
   subRec->prepareId = RNIL;
 
   // Get column order segments
-  Uint32 noOfSections = signal->getNoOfSections();
+  Uint32 noOfSections = handle.m_cnt;
   if(noOfSections > 0) {
     SegmentedSectionPtr ptr;
-    signal->getSection(ptr, BuildIndxReq::INDEX_COLUMNS);
+    handle.getSection(ptr, BuildIndxReq::INDEX_COLUMNS);
     append(subRec->attributeOrder, ptr, getSectionSegmentPool());
     subRec->noOfIndexColumns = ptr.sz;
   }
   if(noOfSections > 1) {
     SegmentedSectionPtr ptr;
-    signal->getSection(ptr, BuildIndxReq::KEY_COLUMNS);
+    handle.getSection(ptr, BuildIndxReq::KEY_COLUMNS);
     append(subRec->attributeOrder, ptr, getSectionSegmentPool());
     subRec->noOfKeyColumns = ptr.sz;
   }
@@ -496,7 +497,7 @@ void Trix:: execBUILDINDXREQ(Signal* sig
   printf("Trix:: execBUILDINDXREQ: Attribute order:\n");
   subRec->attributeOrder.print(stdout);
 #endif
-  releaseSections(signal);
+  releaseSections(handle);
   prepareInsertTransactions(signal, subRecPtr);
   DBUG_VOID_RETURN;
 }
@@ -699,14 +700,14 @@ void Trix::execSUB_TABLE_DATA(Signal* si
     DBUG_VOID_RETURN;
   }
   subRecPtr.p = subRec;
+  SectionHandle handle(this, signal);
   SegmentedSectionPtr headerPtr, dataPtr;
-  if (!signal->getSection(headerPtr, 0)) {
-    printf("Trix::execSUB_TABLE_DATA: Failed to get header section\n");
-  }
-  if (!signal->getSection(dataPtr, 1)) {
-    printf("Trix::execSUB_TABLE_DATA: Failed to get data section\n");
-  }
+
+  handle.getSection(headerPtr, 0);
+  handle.getSection(dataPtr, 1);
   executeInsertTransaction(signal, subRecPtr, headerPtr, dataPtr);
+
+  releaseSections(handle);
   DBUG_VOID_RETURN;
 }
 
diff -Nrup a/storage/ndb/src/kernel/blocks/tsman.cpp b/storage/ndb/src/kernel/blocks/tsman.cpp
--- a/storage/ndb/src/kernel/blocks/tsman.cpp	2007-09-14 08:04:47 +02:00
+++ b/storage/ndb/src/kernel/blocks/tsman.cpp	2007-09-24 17:09:25 +02:00
@@ -452,6 +452,7 @@ Tsman::execCREATE_FILE_REQ(Signal* signa
   
   Ptr<Tablespace> ptr;
   CreateFileImplRef::ErrorCode err = CreateFileImplRef::NoError;
+  SectionHandle handle(this, signal);
   do {
     if (!m_tablespace_hash.find(ptr, req->filegroup_id))
     {
@@ -473,7 +474,7 @@ Tsman::execCREATE_FILE_REQ(Signal* signa
       err = CreateFileImplRef::FilegroupNotOnline;
       break;
     }
-    
+
     Ptr<Datafile> file_ptr;
     switch(req->requestInfo){
     case CreateFileImplReq::Commit:
@@ -514,6 +515,11 @@ Tsman::execCREATE_FILE_REQ(Signal* signa
       // Prepare
       break;
     }
+
+    if (!handle.m_cnt == 1)
+    {
+      ndbrequire(false);
+    }
     
     if (!m_file_pool.seize(file_ptr))
     {
@@ -530,12 +536,14 @@ Tsman::execCREATE_FILE_REQ(Signal* signa
     file_ptr.p->m_tablespace_ptr_i = ptr.i;
     file_ptr.p->m_extent_size = ptr.p->m_extent_size;
 
-    err = (CreateFileImplRef::ErrorCode)open_file(signal, ptr, file_ptr, req);
+    err = (CreateFileImplRef::ErrorCode)open_file(signal, ptr, file_ptr, req,
+						  &handle);
     if(err)
       break;
     return;
   } while(0);
-  
+
+  releaseSections(handle);
   CreateFileImplRef* ref= (CreateFileImplRef*)signal->getDataPtr();
   ref->senderData = senderData;
   ref->senderRef = reference();
@@ -658,7 +666,9 @@ Tsman::execFSCLOSECONF(Signal* signal)
 int
 Tsman::open_file(Signal* signal, 
 		 Ptr<Tablespace> ts_ptr, 
-		 Ptr<Datafile> ptr, CreateFileImplReq* org)
+		 Ptr<Datafile> ptr,
+		 CreateFileImplReq* org,
+		 SectionHandle* handle)
 {
   Uint32 requestInfo = org->requestInfo;
   Uint32 hi = org->file_size_hi;
@@ -718,7 +728,6 @@ Tsman::open_file(Signal* signal, 
   
   ptr.p->m_create.m_extent_pages = extent_pages;
   ptr.p->m_create.m_data_pages = data_pages;
-  // Forward filename
 
   /**
    * Update file size
@@ -730,7 +739,8 @@ Tsman::open_file(Signal* signal, 
   req->file_size_hi = hi;
   req->file_size_lo = lo;
 
-  sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, FsOpenReq::SignalLength, JBB);
+  sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, FsOpenReq::SignalLength, JBB,
+	     handle);
 
   return 0;
 }
@@ -2145,9 +2155,11 @@ void Tsman::execGET_TABINFOREQ(Signal* s
   BlockReference retRef= req->senderRef;
   Uint32 senderData= req->senderData;
 
-  if(reqType == GetTabInfoReq::RequestByName){
+  if(reqType == GetTabInfoReq::RequestByName)
+  {
     jam();
-    releaseSections(signal);
+    SectionHandle handle(this, signal);
+    releaseSections(handle);
 
     sendGET_TABINFOREF(signal, req, GetTabInfoRef::NoFetchByName);
     return;
diff -Nrup a/storage/ndb/src/kernel/blocks/tsman.hpp b/storage/ndb/src/kernel/blocks/tsman.hpp
--- a/storage/ndb/src/kernel/blocks/tsman.hpp	2006-12-31 01:04:56 +01:00
+++ b/storage/ndb/src/kernel/blocks/tsman.hpp	2007-09-24 17:09:25 +02:00
@@ -204,7 +204,8 @@ private:
   Page_cache_client m_page_cache_client;
   Lgman * const m_lgman;
   
-  int open_file(Signal*, Ptr<Tablespace>, Ptr<Datafile>, CreateFileImplReq*);
+  int open_file(Signal*, Ptr<Tablespace>, Ptr<Datafile>, CreateFileImplReq*,
+		SectionHandle* handle);
   void load_extent_pages(Signal* signal, Ptr<Datafile> ptr);
   void load_extent_page_callback(Signal*, Uint32, Uint32);
   void create_file_ref(Signal*, Ptr<Tablespace>, Ptr<Datafile>, 
diff -Nrup a/storage/ndb/src/kernel/vm/FastScheduler.cpp b/storage/ndb/src/kernel/vm/FastScheduler.cpp
--- a/storage/ndb/src/kernel/vm/FastScheduler.cpp	2006-12-23 20:20:19 +01:00
+++ b/storage/ndb/src/kernel/vm/FastScheduler.cpp	2007-09-24 17:09:26 +02:00
@@ -117,7 +117,6 @@ FastScheduler::doJob()
 	b->m_currentGsn = reg_gsn;
 #endif
 	
-	getSections(signal->header.m_noOfSections, signal->m_sectionPtr);
 #ifdef VM_TRACE
         {
           if (globalData.testOn) {
@@ -127,15 +126,11 @@ FastScheduler::doJob()
             globalSignalLoggers.executeSignal(signal->header,
 					      tHighPrio,
 					      &signal->theData[0], 
-					      globalData.ownId,
-                                              signal->m_sectionPtr,
-                                              signal->header.m_noOfSections);
+					      globalData.ownId);
           }//if
         }
 #endif
         b->executeFunction(reg_gsn, signal);
-	releaseSections(signal->header.m_noOfSections, signal->m_sectionPtr);
-	signal->header.m_noOfSections = 0;
 #ifdef VM_TRACE_TIME
 	NdbTick_CurrentMicrosecond(&ms2, &us2);
 	Uint64 diff = ms2;
@@ -241,20 +236,16 @@ APZJobBuffer::retrieve(Signal* signal)
         tSigDataPtr[3] = tData3;
         tSigDataPtr += 4;
       }//while
-
-      /**
-       * Copy sections references (copy all without if-statements)
-       */
-      tDataRegPtr = &buf.theDataRegister[tLength];
-      SegmentedSectionPtr * tSecPtr = &signal->m_sectionPtr[0];
-      Uint32 tData0 = tDataRegPtr[0];
-      Uint32 tData1 = tDataRegPtr[1];
-      Uint32 tData2 = tDataRegPtr[2];
-      
-      tSecPtr[0].i = tData0;
-      tSecPtr[1].i = tData1;
-      tSecPtr[2].i = tData2;
       
+      tSigDataPtr = signal->m_sectionPtrI;
+      tDataRegPtr = buf.theDataRegister + buf.header.theLength;
+      Uint32 ptr0 = * tDataRegPtr ++;
+      Uint32 ptr1 = * tDataRegPtr ++;
+      Uint32 ptr2 = * tDataRegPtr ++;
+      * tSigDataPtr ++ = ptr0;
+      * tSigDataPtr ++ = ptr1;
+      * tSigDataPtr ++ = ptr2;
+
       //---------------------------------------------------------
       // Prefetch of buffer[rPtr] is done here. We prefetch for
       // read both the first cache line and the next 64 byte
@@ -282,7 +273,7 @@ APZJobBuffer::signal2buffer(Signal* sign
 {
   Uint32 tSignalId = globalData.theSignalId;
   Uint32 tFirstData = signal->theData[0];
-  Uint32 tLength = signal->header.theLength;
+  Uint32 tLength = signal->header.theLength + signal->header.m_noOfSections;
   Uint32 tSigId  = buf.header.theSignalId;
   
   buf.header = signal->header;
@@ -310,18 +301,6 @@ APZJobBuffer::signal2buffer(Signal* sign
     tDataRegPtr[3] = tData3;
     tDataRegPtr += 4;
   }//while
-
-  /**
-   * Copy sections references (copy all without if-statements)
-   */
-  tDataRegPtr = &buf.theDataRegister[tLength];
-  SegmentedSectionPtr * tSecPtr = &signal->m_sectionPtr[0];
-  Uint32 tData0 = tSecPtr[0].i;
-  Uint32 tData1 = tSecPtr[1].i;
-  Uint32 tData2 = tSecPtr[2].i;
-  tDataRegPtr[0] = tData0;
-  tDataRegPtr[1] = tData1;
-  tDataRegPtr[2] = tData2;
 }//APZJobBuffer::signal2buffer()
 
 void
diff -Nrup a/storage/ndb/src/kernel/vm/FastScheduler.hpp b/storage/ndb/src/kernel/vm/FastScheduler.hpp
--- a/storage/ndb/src/kernel/vm/FastScheduler.hpp	2006-12-23 20:20:19 +01:00
+++ b/storage/ndb/src/kernel/vm/FastScheduler.hpp	2007-09-24 17:09:26 +02:00
@@ -276,14 +276,10 @@ APZJobBuffer::retrieve(Signal* signal, U
   
   Uint32 *from = (Uint32*) &buf.theDataRegister[0];
   Uint32 *to   = (Uint32*) &signal->theData[0];
-  Uint32 noOfWords = buf.header.theLength;
+  Uint32 noOfWords = buf.header.theLength + buf.header.m_noOfSections;
   for(; noOfWords; noOfWords--)
     *to++ = *from++;
   // Copy sections references (copy all without if-statements)
-  SegmentedSectionPtr * tSecPtr = &signal->m_sectionPtr[0];
-  tSecPtr[0].i = from[0];
-  tSecPtr[1].i = from[1];
-  tSecPtr[2].i = from[2];
   return;
 }
 
diff -Nrup a/storage/ndb/src/kernel/vm/SimulatedBlock.cpp b/storage/ndb/src/kernel/vm/SimulatedBlock.cpp
--- a/storage/ndb/src/kernel/vm/SimulatedBlock.cpp	2007-09-24 17:07:27 +02:00
+++ b/storage/ndb/src/kernel/vm/SimulatedBlock.cpp	2007-09-24 17:09:26 +02:00
@@ -190,6 +190,48 @@ SimulatedBlock::signal_error(Uint32 gsn,
 
 extern class SectionSegmentPool g_sectionSegmentPool;
 
+#define check_sections(signal, cnt) if (unlikely(cnt)) handle_invalid_sections_in_send_signal(signal)
+
+void
+SimulatedBlock::handle_invalid_sections_in_send_signal(Signal* signal) const
+{
+  //Uint32 cnt = signal->header.m_noOfSections;
+#if defined VM_TRACE || defined ERROR_INSERT
+  ErrorReporter::handleError(NDBD_EXIT_BLOCK_BNR_ZERO,
+			     "Unhandled sections in sendSignal",
+			     "");
+#else
+  infoEvent("Unhandled sections in sendSignal!!");
+#endif
+}
+
+void
+SimulatedBlock::handle_lingering_sections_after_execute(Signal* signal) const
+{
+  //Uint32 cnt = signal->header.m_noOfSections;
+#if defined VM_TRACE || defined ERROR_INSERT
+  ErrorReporter::handleError(NDBD_EXIT_BLOCK_BNR_ZERO,
+			     "Unhandled sections after execute",
+			     "");
+#else
+  infoEvent("Unhandled sections after execute");
+#endif
+}
+
+void
+SimulatedBlock::handle_lingering_sections_after_execute(SectionHandle* handle) const
+{
+  //Uint32 cnt = signal->header.m_noOfSections;
+#if defined VM_TRACE || defined ERROR_INSERT
+  ErrorReporter::handleError(NDBD_EXIT_BLOCK_BNR_ZERO,
+			     "Unhandled sections(handle) after execute",
+			     "");
+#else
+  infoEvent("Unhandled sections(handle) after execute");
+#endif
+}
+
+
 void 
 SimulatedBlock::sendSignal(BlockReference ref, 
 			   GlobalSignalNumber gsn, 
@@ -208,10 +250,13 @@ SimulatedBlock::sendSignal(BlockReferenc
   signal->header.theLength = length;
   signal->header.theVerId_signalNumber = gsn;
   signal->header.theReceiversBlockNumber = recBlock;
+  signal->header.m_noOfSections = 0;
+
+  check_sections(signal, noOfSections);
   
   Uint32 tSignalId = signal->header.theSignalId;
   
-  if ((length == 0) || (length + noOfSections > 25) || (recBlock == 0)) {
+  if ((length == 0) || length > 25 || (recBlock == 0)) {
     signal_error(gsn, length, recBlock, __FILE__, __LINE__);
     return;
   }//if
@@ -223,9 +268,7 @@ SimulatedBlock::sendSignal(BlockReferenc
     globalSignalLoggers.sendSignal(signal->header, 
 				   jobBuffer, 
 				   &signal->theData[0],
-				   proc,
-                                   signal->m_sectionPtr,
-                                   signal->header.m_noOfSections);
+				   proc);
   }
 #endif
   
@@ -234,8 +277,6 @@ SimulatedBlock::sendSignal(BlockReferenc
     signal->header.theSendersBlockRef = sendBRef;
     globalScheduler.execute(signal, jobBuffer, recBlock,
 			    gsn);
-    signal->header.m_noOfSections = 0;
-    signal->header.m_fragmentInfo = 0;
     return;
   } else { 
     // send distributed Signal
@@ -249,7 +290,7 @@ SimulatedBlock::sendSignal(BlockReferenc
     sh.theLength               = length;
     sh.theTrace                = tTrace;
     sh.theSignalId             = tSignalId;
-    sh.m_noOfSections          = noOfSections;
+    sh.m_noOfSections          = 0;
     sh.m_fragmentInfo          = 0;
     
 #ifdef TRACE_DISTRIBUTED
@@ -260,12 +301,9 @@ SimulatedBlock::sendSignal(BlockReferenc
     SendStatus ss = globalTransporterRegistry.prepareSend(&sh, jobBuffer, 
 							  &signal->theData[0],
 							  recNode, 
-							  g_sectionSegmentPool,
-							  signal->m_sectionPtr);
+							  (LinearSectionPtr*)0);
     
     ndbrequire(ss == SEND_OK || ss == SEND_BLOCKED || ss == SEND_DISCONNECTED);
-    ::releaseSections(noOfSections, signal->m_sectionPtr);
-    signal->header.m_noOfSections = 0;   
   }
   return;
 }
@@ -280,7 +318,6 @@ SimulatedBlock::sendSignal(NodeReceiverG
   Uint32 noOfSections = signal->header.m_noOfSections;
   Uint32 tSignalId = signal->header.theSignalId;
   Uint32 tTrace = signal->getTrace();
-  Uint32 tFragInf = signal->header.m_fragmentInfo;
   
   Uint32 ourProcessor = globalData.ownId;
   Uint32 recBlock = rg.m_block;
@@ -290,8 +327,11 @@ SimulatedBlock::sendSignal(NodeReceiverG
   signal->header.theReceiversBlockNumber = recBlock;
   signal->header.theSendersSignalId = tSignalId;
   signal->header.theSendersBlockRef = reference();
-  
-  if ((length == 0) || (length + noOfSections > 25) || (recBlock == 0)) {
+  signal->header.m_noOfSections = 0;
+
+  check_sections(signal, noOfSections);
+
+  if ((length == 0) || (length > 25) || (recBlock == 0)) {
     signal_error(gsn, length, recBlock, __FILE__, __LINE__);
     return;
   }//if
@@ -304,29 +344,25 @@ SimulatedBlock::sendSignal(NodeReceiverG
   sh.theLength               = length;
   sh.theTrace                = tTrace;
   sh.theSignalId             = tSignalId;
-  sh.m_noOfSections          = noOfSections;
-  sh.m_fragmentInfo          = tFragInf;
+  sh.m_noOfSections          = 0;
+  sh.m_fragmentInfo          = 0;
 
   /**
    * Check own node
    */
-  bool release = true;
   if(rg.m_nodes.get(0) || rg.m_nodes.get(ourProcessor)){
 #ifdef VM_TRACE
     if(globalData.testOn){
       globalSignalLoggers.sendSignal(signal->header, 
 				     jobBuffer, 
 				     &signal->theData[0],
-				     ourProcessor,
-                                     signal->m_sectionPtr,
-                                     signal->header.m_noOfSections);
+				     ourProcessor);
     }
 #endif
     globalScheduler.execute(signal, jobBuffer, recBlock, gsn);
     
     rg.m_nodes.clear((Uint32)0);
     rg.m_nodes.clear(ourProcessor);
-    release = false;
   }
 
   /**
@@ -341,9 +377,7 @@ SimulatedBlock::sendSignal(NodeReceiverG
       globalSignalLoggers.sendSignal(signal->header, 
 				     jobBuffer, 
 				     &signal->theData[0],
-				     recNode,
-                                     signal->m_sectionPtr,
-                                     signal->header.m_noOfSections);
+				     recNode);
     }
 #endif
 
@@ -356,18 +390,10 @@ SimulatedBlock::sendSignal(NodeReceiverG
     SendStatus ss = globalTransporterRegistry.prepareSend(&sh, jobBuffer, 
 							  &signal->theData[0],
 							  recNode,
-							  g_sectionSegmentPool,
-							  signal->m_sectionPtr);
+							  (LinearSectionPtr*)0);
     ndbrequire(ss == SEND_OK || ss == SEND_BLOCKED || ss == SEND_DISCONNECTED);
   }
-  
-  if(release){
-    ::releaseSections(noOfSections, signal->m_sectionPtr);
-  }
-  
-  signal->header.m_noOfSections = 0;
-  signal->header.m_fragmentInfo = 0;
-  
+
   return;
 }
 
@@ -389,7 +415,7 @@ SimulatedBlock::sendSignal(BlockReferenc
   Uint32 recNode   = refToNode(ref);
   Uint32 ourProcessor         = globalData.ownId;
   
-  ::releaseSections(signal->header.m_noOfSections, signal->m_sectionPtr);
+  check_sections(signal, signal->header.m_noOfSections);
   
   signal->header.theLength = length;
   signal->header.theVerId_signalNumber = gsn;
@@ -426,7 +452,7 @@ SimulatedBlock::sendSignal(BlockReferenc
     Ptr<SectionSegment> segptr[3];
     for(Uint32 i = 0; i<noOfSections; i++){
       ndbrequire(import(segptr[i], ptr[i].p, ptr[i].sz));
-      signal->m_sectionPtr[i].i = segptr[i].i;
+      signal->theData[length+i] = segptr[i].i;
     }
     
     globalScheduler.execute(signal, jobBuffer, recBlock,
@@ -483,7 +509,7 @@ SimulatedBlock::sendSignal(NodeReceiverG
   Uint32 ourProcessor = globalData.ownId;
   Uint32 recBlock = rg.m_block;
   
-  ::releaseSections(signal->header.m_noOfSections, signal->m_sectionPtr);
+  check_sections(signal, signal->header.m_noOfSections);
   
   signal->header.theLength = length;
   signal->header.theVerId_signalNumber = gsn;
@@ -526,7 +552,7 @@ SimulatedBlock::sendSignal(NodeReceiverG
     Ptr<SectionSegment> segptr[3];
     for(Uint32 i = 0; i<noOfSections; i++){
       ndbrequire(import(segptr[i], ptr[i].p, ptr[i].sz));
-      signal->m_sectionPtr[i].i = segptr[i].i;
+      signal->theData[length+i] = segptr[i].i;
     }
     globalScheduler.execute(signal, jobBuffer, recBlock, gsn);
     
@@ -572,6 +598,211 @@ SimulatedBlock::sendSignal(NodeReceiverG
 }
 
 void
+SimulatedBlock::sendSignal(BlockReference ref,
+			   GlobalSignalNumber gsn,
+			   Signal* signal,
+			   Uint32 length,
+			   JobBufferLevel jobBuffer,
+			   SectionHandle* sections) const {
+
+  Uint32 noOfSections = sections->m_cnt;
+  BlockNumber sendBnr = number();
+  BlockReference sendBRef = reference();
+
+  Uint32 recBlock = refToBlock(ref);
+  Uint32 recNode   = refToNode(ref);
+  Uint32 ourProcessor         = globalData.ownId;
+
+  check_sections(signal, signal->header.m_noOfSections);
+
+  signal->header.theLength = length;
+  signal->header.theVerId_signalNumber = gsn;
+  signal->header.theReceiversBlockNumber = recBlock;
+  signal->header.m_noOfSections = noOfSections;
+
+  Uint32 tSignalId = signal->header.theSignalId;
+  Uint32 tFragInfo = signal->header.m_fragmentInfo;
+
+  if ((length == 0) || (length + noOfSections > 25) || (recBlock == 0)) {
+    signal_error(gsn, length, recBlock, __FILE__, __LINE__);
+    return;
+  }//if
+#ifdef VM_TRACE
+  if(globalData.testOn){
+    Uint16 proc =
+      (recNode == 0 ? globalData.ownId : recNode);
+    signal->header.theSendersBlockRef = sendBRef;
+    globalSignalLoggers.sendSignal(signal->header,
+				   jobBuffer,
+				   &signal->theData[0],
+				   proc,
+                                   sections->m_ptr, noOfSections);
+  }
+#endif
+
+  if(recNode == ourProcessor || recNode == 0) {
+    signal->header.theSendersSignalId = tSignalId;
+    signal->header.theSendersBlockRef = sendBRef;
+
+    /**
+     * We have to copy the data
+     */
+    Uint32 * dst = signal->theData + length;
+    * dst ++ = sections->m_ptr[0].i;
+    * dst ++ = sections->m_ptr[1].i;
+    * dst ++ = sections->m_ptr[2].i;
+
+    globalScheduler.execute(signal, jobBuffer, recBlock, gsn);
+  } else {
+    // send distributed Signal
+    SignalHeader sh;
+
+    Uint32 tTrace = signal->getTrace();
+
+    sh.theVerId_signalNumber   = gsn;
+    sh.theReceiversBlockNumber = recBlock;
+    sh.theSendersBlockRef      = sendBnr;
+    sh.theLength               = length;
+    sh.theTrace                = tTrace;
+    sh.theSignalId             = tSignalId;
+    sh.m_noOfSections          = noOfSections;
+    sh.m_fragmentInfo          = tFragInfo;
+
+#ifdef TRACE_DISTRIBUTED
+    ndbout_c("send: %s(%d) to (%s, %d)",
+	     getSignalName(gsn), gsn, getBlockName(recBlock),
+	     recNode);
+#endif
+
+    SendStatus ss = globalTransporterRegistry.prepareSend(&sh, jobBuffer,
+							  &signal->theData[0],
+							  recNode,
+							  g_sectionSegmentPool,
+							  sections->m_ptr);
+    ndbrequire(ss == SEND_OK || ss == SEND_BLOCKED || ss == SEND_DISCONNECTED);
+    ::releaseSections(noOfSections, sections->m_ptr);
+  }
+
+  signal->header.m_noOfSections = 0;
+  signal->header.m_fragmentInfo = 0;
+  sections->m_cnt = 0;
+  return;
+}
+
+void
+SimulatedBlock::sendSignal(NodeReceiverGroup rg,
+			   GlobalSignalNumber gsn,
+			   Signal* signal,
+			   Uint32 length,
+			   JobBufferLevel jobBuffer,
+			   SectionHandle * sections) const {
+
+  Uint32 noOfSections = sections->m_cnt;
+  Uint32 tSignalId = signal->header.theSignalId;
+  Uint32 tTrace    = signal->getTrace();
+  Uint32 tFragInfo = signal->header.m_fragmentInfo;
+
+  Uint32 ourProcessor = globalData.ownId;
+  Uint32 recBlock = rg.m_block;
+
+  check_sections(signal, signal->header.m_noOfSections);
+
+  signal->header.theLength = length;
+  signal->header.theVerId_signalNumber = gsn;
+  signal->header.theReceiversBlockNumber = recBlock;
+  signal->header.theSendersSignalId = tSignalId;
+  signal->header.theSendersBlockRef = reference();
+  signal->header.m_noOfSections = noOfSections;
+
+  if ((length == 0) || (length + noOfSections > 25) || (recBlock == 0)) {
+    signal_error(gsn, length, recBlock, __FILE__, __LINE__);
+    return;
+  }//if
+
+  SignalHeader sh;
+  sh.theVerId_signalNumber   = gsn;
+  sh.theReceiversBlockNumber = recBlock;
+  sh.theSendersBlockRef      = number();
+  sh.theLength               = length;
+  sh.theTrace                = tTrace;
+  sh.theSignalId             = tSignalId;
+  sh.m_noOfSections          = noOfSections;
+  sh.m_fragmentInfo          = tFragInfo;
+
+  /**
+   * Check own node
+   */
+  bool release = true;
+  if(rg.m_nodes.get(0) || rg.m_nodes.get(ourProcessor))
+  {
+    release = false;
+#ifdef VM_TRACE
+    if(globalData.testOn){
+      globalSignalLoggers.sendSignal(signal->header,
+				     jobBuffer,
+				     &signal->theData[0],
+				     ourProcessor,
+                                     sections->m_ptr, noOfSections);
+    }
+#endif
+    /**
+     * We have to copy the data
+     */
+    Uint32 * dst = signal->theData + length;
+    * dst ++ = sections->m_ptr[0].i;
+    * dst ++ = sections->m_ptr[1].i;
+    * dst ++ = sections->m_ptr[2].i;
+    globalScheduler.execute(signal, jobBuffer, recBlock, gsn);
+
+    rg.m_nodes.clear((Uint32)0);
+    rg.m_nodes.clear(ourProcessor);
+  }
+
+  /**
+   * Do the big loop
+   */
+  Uint32 recNode = 0;
+  while(!rg.m_nodes.isclear()){
+    recNode = rg.m_nodes.find(recNode + 1);
+    rg.m_nodes.clear(recNode);
+
+#ifdef VM_TRACE
+    if(globalData.testOn){
+      globalSignalLoggers.sendSignal(signal->header,
+				     jobBuffer,
+				     &signal->theData[0],
+				     recNode,
+                                     sections->m_ptr, noOfSections);
+    }
+#endif
+
+#ifdef TRACE_DISTRIBUTED
+    ndbout_c("send: %s(%d) to (%s, %d)",
+	     getSignalName(gsn), gsn, getBlockName(recBlock),
+	     recNode);
+#endif
+
+    SendStatus ss = globalTransporterRegistry.prepareSend(&sh, jobBuffer,
+							  &signal->theData[0],
+							  recNode,
+							  g_sectionSegmentPool,
+							  sections->m_ptr);
+    ndbrequire(ss == SEND_OK || ss == SEND_BLOCKED || ss == SEND_DISCONNECTED);
+  }
+
+  if (release)
+  {
+    ::releaseSections(noOfSections, sections->m_ptr);
+  }
+
+  sections->m_cnt = 0;
+  signal->header.m_noOfSections = 0;
+  signal->header.m_fragmentInfo = 0;
+
+  return;
+}
+
+void
 SimulatedBlock::sendSignalWithDelay(BlockReference ref, 
 				    GlobalSignalNumber gsn,
 				    Signal* signal,
@@ -579,6 +810,8 @@ SimulatedBlock::sendSignalWithDelay(Bloc
 				    Uint32 length) const {
   
   BlockNumber bnr = refToBlock(ref);
+
+  check_sections(signal, signal->header.m_noOfSections);
   
   signal->header.theLength = length;
   signal->header.theSendersSignalId = signal->header.theSignalId;
@@ -593,25 +826,71 @@ SimulatedBlock::sendSignalWithDelay(Bloc
 					      signal->header,
 					      0,
 					      &signal->theData[0], 
-					      globalData.ownId,
-                                              signal->m_sectionPtr,
-                                              signal->header.m_noOfSections);
+					      globalData.ownId);
     }
   }
 #endif
   globalTimeQueue.insert(signal, bnr, gsn, delayInMilliSeconds);
 
-  signal->header.m_noOfSections = 0;
-  signal->header.m_fragmentInfo = 0;
-  
   // befor 2nd parameter to globalTimeQueue.insert
   // (Priority)theSendSig[sigIndex].jobBuffer
 }
 
 void
-SimulatedBlock::releaseSections(Signal* signal){
-  ::releaseSections(signal->header.m_noOfSections, signal->m_sectionPtr);
+SimulatedBlock::sendSignalWithDelay(BlockReference ref,
+				    GlobalSignalNumber gsn,
+				    Signal* signal,
+				    Uint32 delayInMilliSeconds,
+				    Uint32 length,
+				    SectionHandle * sections) const {
+
+  Uint32 noOfSections = sections->m_cnt;
+  BlockNumber bnr = refToBlock(ref);
+
+  //BlockNumber sendBnr = number();
+  BlockReference sendBRef = reference();
+
+  if (bnr == 0) {
+    bnr_error();
+  }//if
+
+  check_sections(signal, signal->header.m_noOfSections);
+
+  signal->header.theLength = length;
+  signal->header.theSendersSignalId = signal->header.theSignalId;
+  signal->header.theSendersBlockRef = sendBRef;
+  signal->header.theVerId_signalNumber = gsn;
+  signal->header.theReceiversBlockNumber = bnr;
+  signal->header.m_noOfSections = noOfSections;
+
+  Uint32 * dst = signal->theData + length;
+  * dst ++ = sections->m_ptr[0].i;
+  * dst ++ = sections->m_ptr[1].i;
+  * dst ++ = sections->m_ptr[2].i;
+
+#ifdef VM_TRACE
+  {
+    if(globalData.testOn){
+      globalSignalLoggers.sendSignalWithDelay(delayInMilliSeconds,
+					      signal->header,
+					      0,
+					      &signal->theData[0],
+					      globalData.ownId);
+    }
+  }
+#endif
+  globalTimeQueue.insert(signal, bnr, gsn, delayInMilliSeconds);
+
   signal->header.m_noOfSections = 0;
+  signal->header.m_fragmentInfo = 0;
+  sections->m_cnt = 0;
+}
+
+void
+SimulatedBlock::releaseSections(SectionHandle& handle)
+{
+  ::releaseSections(handle.m_cnt, handle.m_ptr);
+  handle.m_cnt = 0;
 }
 
 class SectionSegmentPool& 
@@ -773,9 +1052,9 @@ SimulatedBlock::infoEvent(const char * m
   if(msg == 0)
     return;
   
-  Uint32 theData[25];
-  theData[0] = NDB_LE_InfoEvent;
-  char * buf = (char *)&(theData[1]);
+  SignalT<25> signalT;
+  signalT.theData[0] = NDB_LE_InfoEvent;
+  char * buf = (char *)(signalT.theData+1);
   
   va_list ap;
   va_start(ap, msg);
@@ -791,32 +1070,31 @@ SimulatedBlock::infoEvent(const char * m
   /**
    * Init and put it into the job buffer
    */
-  SignalHeader sh;
-  memset(&sh, 0, sizeof(SignalHeader));
+  memset(&signalT.header, 0, sizeof(SignalHeader));
   
   const Signal * signal = globalScheduler.getVMSignals();
   Uint32 tTrace = signal->header.theTrace;
   Uint32 tSignalId = signal->header.theSignalId;
   
-  sh.theVerId_signalNumber   = GSN_EVENT_REP;
-  sh.theReceiversBlockNumber = CMVMI;
-  sh.theSendersBlockRef      = reference();
-  sh.theTrace                = tTrace;
-  sh.theSignalId             = tSignalId;
-  sh.theLength               = ((len+3)/4)+1;
+  signalT.header.theVerId_signalNumber   = GSN_EVENT_REP;
+  signalT.header.theReceiversBlockNumber = CMVMI;
+  signalT.header.theSendersBlockRef      = reference();
+  signalT.header.theTrace                = tTrace;
+  signalT.header.theSignalId             = tSignalId;
+  signalT.header.theLength               = ((len+3)/4)+1;
   
-  Uint32 secPtrI[3]; // Dummy
-  globalScheduler.execute(&sh, JBB, theData, secPtrI);
+  globalScheduler.execute(&signalT.header, JBB, signalT.theData,
+                          signalT.m_sectionPtrI);
 }
 
 void 
 SimulatedBlock::warningEvent(const char * msg, ...) const {
   if(msg == 0)
     return;
-  
-  Uint32 theData[25];
-  theData[0] = NDB_LE_WarningEvent;
-  char * buf = (char *)&(theData[1]);
+
+  SignalT<25> signalT;
+  signalT.theData[0] = NDB_LE_WarningEvent;
+  char * buf = (char *)(signalT.theData+1);
   
   va_list ap;
   va_start(ap, msg);
@@ -832,22 +1110,21 @@ SimulatedBlock::warningEvent(const char 
   /**
    * Init and put it into the job buffer
    */
-  SignalHeader sh;
-  memset(&sh, 0, sizeof(SignalHeader));
+  memset(&signalT.header, 0, sizeof(SignalHeader));
   
   const Signal * signal = globalScheduler.getVMSignals();
   Uint32 tTrace = signal->header.theTrace;
   Uint32 tSignalId = signal->header.theSignalId;
   
-  sh.theVerId_signalNumber   = GSN_EVENT_REP;
-  sh.theReceiversBlockNumber = CMVMI;
-  sh.theSendersBlockRef      = reference();
-  sh.theTrace                = tTrace;
-  sh.theSignalId             = tSignalId;
-  sh.theLength               = ((len+3)/4)+1;
+  signalT.header.theVerId_signalNumber   = GSN_EVENT_REP;
+  signalT.header.theReceiversBlockNumber = CMVMI;
+  signalT.header.theSendersBlockRef      = reference();
+  signalT.header.theTrace                = tTrace;
+  signalT.header.theSignalId             = tSignalId;
+  signalT.header.theLength               = ((len+3)/4)+1;
 
-  Uint32 secPtrI[3]; // Dummy
-  globalScheduler.execute(&sh, JBB, theData, secPtrI);
+  globalScheduler.execute(&signalT.header, JBB, signalT.theData,
+                          signalT.m_sectionPtrI);
 }
 
 void
@@ -1019,6 +1296,8 @@ SimulatedBlock::assembleFragments(Signal
   Uint32 fragId = signal->theData[sigLen];
   Uint32 fragInfo = signal->header.m_fragmentInfo;
   Uint32 senderRef = signal->getSendersBlockRef();
+
+  Uint32 *sectionPtr = signal->m_sectionPtrI;
   
   if(fragInfo == 0){
     return true;
@@ -1043,7 +1322,7 @@ SimulatedBlock::assembleFragments(Signal
     for(Uint32 i = 0; i<secs; i++){
       Uint32 sectionNo = secNos[i];
       ndbassert(sectionNo < 3);
-      fragPtr.p->m_sectionPtrI[sectionNo] = signal->m_sectionPtr[i].i;
+      fragPtr.p->m_sectionPtrI[sectionNo] = sectionPtr[i];
     }
     
     /**
@@ -1064,7 +1343,7 @@ SimulatedBlock::assembleFragments(Signal
     for(i = 0; i<secs; i++){
       Uint32 sectionNo = secNos[i];
       ndbassert(sectionNo < 3);
-      Uint32 sectionPtrI = signal->m_sectionPtr[i].i;
+      Uint32 sectionPtrI = sectionPtr[i];
       if(fragPtr.p->m_sectionPtrI[sectionNo] != RNIL){
 	linkSegments(fragPtr.p->m_sectionPtrI[sectionNo], sectionPtrI);
       } else {
@@ -1086,16 +1365,16 @@ SimulatedBlock::assembleFragments(Signal
     for(i = 0; i<3; i++){
       Uint32 ptrI = fragPtr.p->m_sectionPtrI[i];
       if(ptrI != RNIL){
-	signal->m_sectionPtr[i].i = ptrI;
+	signal->m_sectionPtrI[i] = ptrI;
       } else {
 	break;
       }
     }
-    signal->setLength(sigLen - i);
+
+    signal->setLength(sigLen - secs);
     signal->header.m_noOfSections = i;
     signal->header.m_fragmentInfo = 0;
-    getSections(i, signal->m_sectionPtr);
-    
+
     c_fragmentInfoHash.release(fragPtr);
     return true;
   }
@@ -1114,37 +1393,37 @@ SimulatedBlock::sendFirstFragment(Fragme
 				  Signal* signal, 
 				  Uint32 length, 
 				  JobBufferLevel jbuf,
+				  SectionHandle* sections,
 				  Uint32 messageSize){
   
+  Uint32 noSections = sections->m_cnt;
+  SegmentedSectionPtr * ptr = sections->m_ptr;
+
   info.m_sectionPtr[0].m_segmented.i = RNIL;
   info.m_sectionPtr[1].m_segmented.i = RNIL;
   info.m_sectionPtr[2].m_segmented.i = RNIL;
   
   Uint32 totalSize = 0;
-  SectionSegment * p;
-  switch(signal->header.m_noOfSections){
+  switch(noSections){
   case 3:
-    p = signal->m_sectionPtr[2].p;  
-    info.m_sectionPtr[2].m_segmented.p = p;
-    info.m_sectionPtr[2].m_segmented.i = signal->m_sectionPtr[2].i;
-    totalSize += p->m_sz;
+    info.m_sectionPtr[2].m_segmented.i = ptr[2].i;
+    info.m_sectionPtr[2].m_segmented.p = ptr[2].p;
+    totalSize += ptr[2].sz;
   case 2:
-    p = signal->m_sectionPtr[1].p;  
-    info.m_sectionPtr[1].m_segmented.p = p;
-    info.m_sectionPtr[1].m_segmented.i = signal->m_sectionPtr[1].i;
-    totalSize += p->m_sz;
+    info.m_sectionPtr[1].m_segmented.i = ptr[1].i;
+    info.m_sectionPtr[1].m_segmented.p = ptr[1].p;
+    totalSize += ptr[1].sz;
   case 1:
-    p = signal->m_sectionPtr[0].p;  
-    info.m_sectionPtr[0].m_segmented.p = p;
-    info.m_sectionPtr[0].m_segmented.i = signal->m_sectionPtr[0].i;
-    totalSize += p->m_sz;
+    info.m_sectionPtr[0].m_segmented.i = ptr[0].i;
+    info.m_sectionPtr[0].m_segmented.p = ptr[0].p;
+    totalSize += ptr[0].sz;
   }
 
   if(totalSize <= messageSize + SectionSegment::DataLength){
     /**
      * Send signal directly
      */
-    sendSignal(rg, gsn, signal, length, jbuf);
+    sendSignal(rg, gsn, signal, length, jbuf, sections);
     info.m_status = FragmentSendInfo::SendComplete;
     return true;
   }
@@ -1152,7 +1431,7 @@ SimulatedBlock::sendFirstFragment(Fragme
   /**
    * Consume sections
    */
-  signal->header.m_noOfSections = 0;
+  sections->m_cnt = 0;
     
   /**
    * Setup info object
@@ -1210,6 +1489,9 @@ SimulatedBlock::sendNextSegmentedFragmen
   Uint32 secCount = 0;
   Uint32 * secNos = &signal->theData[sigLen];
   
+  SectionHandle sections(this);
+  SegmentedSectionPtr *ptr = sections.m_ptr;
+
   enum { Unknown = 0, Full = 1 } loop = Unknown;
   for(; secNo >= 0 && secCount < 3; secNo--){
     Uint32 ptrI = info.m_sectionPtr[secNo].m_segmented.i;
@@ -1221,9 +1503,9 @@ SimulatedBlock::sendNextSegmentedFragmen
     SectionSegment * ptrP = info.m_sectionPtr[secNo].m_segmented.p;
     const Uint32 size = ptrP->m_sz;
     
-    signal->m_sectionPtr[secCount].i = ptrI;
-    signal->m_sectionPtr[secCount].p = ptrP;
-    signal->m_sectionPtr[secCount].sz = size;
+    ptr[secCount].i = ptrI;
+    ptr[secCount].p = ptrP;
+    ptr[secCount].sz = size;
     secNos[secCount] = secNo;
     secCount++;
     
@@ -1285,10 +1567,10 @@ SimulatedBlock::sendNextSegmentedFragmen
      * Rewrite header w.r.t size and last
      */
     Uint32 prev = secCount - 1;
-    const Uint32 last = signal->m_sectionPtr[prev].p->m_lastSegment;
-    signal->m_sectionPtr[prev].p->m_lastSegment = prevPtrI;
-    signal->m_sectionPtr[prev].p->m_sz = sum;
-    signal->m_sectionPtr[prev].sz = sum;
+    const Uint32 last = ptr[prev].p->m_lastSegment;
+    ptr[prev].p->m_lastSegment = prevPtrI;
+    ptr[prev].p->m_sz = sum;
+    ptr[prev].sz = sum;
       
     /**
      * Write "new" list header
@@ -1337,13 +1619,15 @@ SimulatedBlock::sendNextSegmentedFragmen
   }
   
   signal->header.m_fragmentInfo = fragInfo;
-  signal->header.m_noOfSections = secCount;
+  signal->header.m_noOfSections = 0;
+  sections.m_cnt = secCount;
   
   sendSignal(info.m_nodeReceiverGroup,
 	     info.m_gsn,
 	     signal, 
 	     sigLen + secCount + 1,
-	     (JobBufferLevel)info.m_prio);
+	     (JobBufferLevel)info.m_prio,
+	     &sections);
   
   if(fragInfo == 3){
     /**
@@ -1364,8 +1648,7 @@ SimulatedBlock::sendFirstFragment(Fragme
 				  Uint32 noOfSections,
 				  Uint32 messageSize){
   
-  ::releaseSections(signal->header.m_noOfSections, signal->m_sectionPtr);
-  signal->header.m_noOfSections = 0;
+  check_sections(signal, signal->header.m_noOfSections);
   
   info.m_sectionPtr[0].m_linear.p = NULL;
   info.m_sectionPtr[1].m_linear.p = NULL;
@@ -1580,29 +1863,31 @@ SimulatedBlock::sendFragmentedSignal(Blo
 				     Signal* signal, 
 				     Uint32 length, 
 				     JobBufferLevel jbuf,
+				     SectionHandle* sections,
 				     Callback & c,
 				     Uint32 messageSize){
   bool res = true;
-  Ptr<FragmentSendInfo> ptr;
-  res = c_segmentedFragmentSendList.seize(ptr);
+  Ptr<FragmentSendInfo> tmp;
+  res = c_segmentedFragmentSendList.seize(tmp);
   ndbrequire(res);
   
-  res = sendFirstFragment(* ptr.p, 
+  res = sendFirstFragment(* tmp.p,
 			  NodeReceiverGroup(ref),
 			  gsn,
 			  signal,
 			  length,
 			  jbuf,
+			  sections,
 			  messageSize);
   ndbrequire(res);
   
-  if(ptr.p->m_status == FragmentSendInfo::SendComplete){
-    c_segmentedFragmentSendList.release(ptr);
+  if(tmp.p->m_status == FragmentSendInfo::SendComplete){
+    c_segmentedFragmentSendList.release(tmp);
     if(c.m_callbackFunction != 0)
       execute(signal, c, 0);
     return;
   }
-  ptr.p->m_callback = c;
+  tmp.p->m_callback = c;
 
   if(!c_fragSenderRunning){
     c_fragSenderRunning = true;
@@ -1618,29 +1903,31 @@ SimulatedBlock::sendFragmentedSignal(Nod
 				     Signal* signal, 
 				     Uint32 length, 
 				     JobBufferLevel jbuf,
+				     SectionHandle * sections,
 				     Callback & c,
 				     Uint32 messageSize){
   bool res = true;
-  Ptr<FragmentSendInfo> ptr;
-  res = c_segmentedFragmentSendList.seize(ptr);
+  Ptr<FragmentSendInfo> tmp;
+  res = c_segmentedFragmentSendList.seize(tmp);
   ndbrequire(res);
   
-  res = sendFirstFragment(* ptr.p, 
+  res = sendFirstFragment(* tmp.p,
 			  rg,
 			  gsn,
 			  signal,
 			  length,
 			  jbuf,
+			  sections,
 			  messageSize);
   ndbrequire(res);
   
-  if(ptr.p->m_status == FragmentSendInfo::SendComplete){
-    c_segmentedFragmentSendList.release(ptr);
+  if(tmp.p->m_status == FragmentSendInfo::SendComplete){
+    c_segmentedFragmentSendList.release(tmp);
     if(c.m_callbackFunction != 0)
       execute(signal, c, 0);
     return;
   }
-  ptr.p->m_callback = c;
+  tmp.p->m_callback = c;
 
   if(!c_fragSenderRunning){
     c_fragSenderRunning = true;
diff -Nrup a/storage/ndb/src/kernel/vm/SimulatedBlock.hpp b/storage/ndb/src/kernel/vm/SimulatedBlock.hpp
--- a/storage/ndb/src/kernel/vm/SimulatedBlock.hpp	2007-07-11 14:38:00 +02:00
+++ b/storage/ndb/src/kernel/vm/SimulatedBlock.hpp	2007-09-24 17:09:26 +02:00
@@ -96,6 +96,7 @@ class SimulatedBlock {
   friend class Lgman;
   friend class Logfile_client;
   friend struct Pool_context;
+  friend struct SectionHandle;
 public:
   friend class BlockComponent;
   virtual ~SimulatedBlock();
@@ -157,6 +158,20 @@ protected:
                   Signal* signal, 
 		  Uint32 length, 
 		  JobBufferLevel jbuf,
+		  SectionHandle* sections) const;
+
+  void sendSignal(NodeReceiverGroup rg,
+		  GlobalSignalNumber gsn,
+                  Signal* signal,
+		  Uint32 length,
+		  JobBufferLevel jbuf,
+		  SectionHandle* sections) const;
+
+  void sendSignal(BlockReference ref,
+		  GlobalSignalNumber gsn,
+                  Signal* signal,
+		  Uint32 length,
+		  JobBufferLevel jbuf,
 		  LinearSectionPtr ptr[3],
 		  Uint32 noOfSections) const ;
   
@@ -177,13 +192,24 @@ protected:
                            Uint32 delayInMilliSeconds, 
 			   Uint32 length) const ;
 
+  void sendSignalWithDelay(BlockReference ref,
+			   GlobalSignalNumber gsn,
+                           Signal* signal,
+                           Uint32 delayInMilliSeconds,
+			   Uint32 length,
+			   SectionHandle* sections) const;
+
   void EXECUTE_DIRECT(Uint32 block, 
 		      Uint32 gsn, 
 		      Signal* signal, 
 		      Uint32 len);
   
   class SectionSegmentPool& getSectionSegmentPool();
-  void releaseSections(Signal* signal);
+  void releaseSections(struct SectionHandle&);
+
+  void handle_invalid_sections_in_send_signal(Signal*) const;
+  void handle_lingering_sections_after_execute(Signal*) const;
+  void handle_lingering_sections_after_execute(SectionHandle*) const;
 
   /**********************************************************
    * Fragmented signals
@@ -202,6 +228,7 @@ protected:
 			    Signal* signal, 
 			    Uint32 length, 
 			    JobBufferLevel jbuf,
+			    SectionHandle * sections,
 			    Callback & = TheEmptyCallback,
 			    Uint32 messageSize = 240);
 
@@ -210,6 +237,7 @@ protected:
 			    Signal* signal, 
 			    Uint32 length, 
 			    JobBufferLevel jbuf,
+			    SectionHandle * sections,
 			    Callback & = TheEmptyCallback,
 			    Uint32 messageSize = 240);
 
@@ -220,7 +248,7 @@ protected:
 			    JobBufferLevel jbuf,
 			    LinearSectionPtr ptr[3],
 			    Uint32 noOfSections,
-			    Callback &,
+			    Callback & = TheEmptyCallback,
 			    Uint32 messageSize = 240);
 
   void sendFragmentedSignal(NodeReceiverGroup rg, 
@@ -230,7 +258,7 @@ protected:
 			    JobBufferLevel jbuf,
 			    LinearSectionPtr ptr[3],
 			    Uint32 noOfSections,
-			    Callback &,
+			    Callback & = TheEmptyCallback,
 			    Uint32 messageSize = 240);
 
   /**********************************************************
@@ -273,7 +301,7 @@ protected:
     };
     Uint8  m_status;
     Uint8  m_prio;
-    Uint16  m_fragInfo;
+    Uint16 m_fragInfo;
     Uint16 m_gsn;
     Uint16 m_messageSize; // Size of each fragment
     Uint32 m_fragmentId;
@@ -302,8 +330,7 @@ protected:
 			 Signal* signal, 
 			 Uint32 length, 
 			 JobBufferLevel jbuf,
-			 LinearSectionPtr ptr[3],
-			 Uint32 noOfSections,
+			 SectionHandle * sections,
 			 Uint32 messageSize = 240);
   
   bool sendFirstFragment(FragmentSendInfo & info,
@@ -312,6 +339,8 @@ protected:
 			 Signal* signal, 
 			 Uint32 length, 
 			 JobBufferLevel jbuf,
+			 LinearSectionPtr ptr[3],
+			 Uint32 noOfSections,
 			 Uint32 messageSize = 240);
   
   /**
@@ -579,6 +608,11 @@ SimulatedBlock::executeFunction(GlobalSi
     clear_global_variables();
 #endif
     (this->*f)(signal);
+
+    if (unlikely(signal->header.m_noOfSections))
+    {
+      handle_lingering_sections_after_execute(signal);
+    }
     return;
   }
 
@@ -818,6 +852,15 @@ BLOCK::addRecSignal(GlobalSignalNumber g
 }
 
 #include "Mutex.hpp"
+
+inline
+SectionHandle::~SectionHandle()
+{
+  if (unlikely(m_cnt))
+  {
+    m_block->handle_lingering_sections_after_execute(this);
+  }
+}
 
 #endif
 
diff -Nrup a/storage/ndb/src/kernel/vm/VMSignal.hpp b/storage/ndb/src/kernel/vm/VMSignal.hpp
--- a/storage/ndb/src/kernel/vm/VMSignal.hpp	2007-01-06 01:21:24 +01:00
+++ b/storage/ndb/src/kernel/vm/VMSignal.hpp	2007-09-24 17:09:26 +02:00
@@ -26,6 +26,24 @@
 #include <RefConvert.hpp>
 #include <TransporterDefinitions.hpp>
 
+extern void getSections(Uint32 secCount, SegmentedSectionPtr ptr[3]);
+
+struct SectionHandle
+{
+  SectionHandle (class SimulatedBlock*);
+  SectionHandle (class SimulatedBlock*, Uint32 ptrI);
+  SectionHandle (class SimulatedBlock*, class Signal*);
+  ~SectionHandle ();
+
+  Uint32 m_cnt;
+  SegmentedSectionPtr m_ptr[3];
+
+  bool getSection(SegmentedSectionPtr & ptr, Uint32 sectionNo);
+  void clear() { m_cnt = 0;}
+
+  SimulatedBlock* m_block;
+};
+
 /**
  * Struct used when sending to multiple blocks
  */
@@ -44,8 +62,8 @@ struct NodeReceiverGroup {
 
 template <unsigned T> struct SignalT
 {
+  Uint32 m_sectionPtrI[3];
   SignalHeader header;
-  SegmentedSectionPtr m_sectionPtr[3]; 
   union {
     Uint32 theData[T];
     Uint64 dummyAlign;
@@ -72,8 +90,6 @@ public:
   void setTrace(Uint32);
 
   Uint32 getNoOfSections() const;
-  bool getSection(SegmentedSectionPtr & ptr, Uint32 sectionNo);
-  void setSection(SegmentedSectionPtr ptr, Uint32 sectionNo);
 
   /**
    * Old depricated methods...
@@ -92,8 +108,8 @@ public:
 #error "VMSignal buffer is too small"
 #endif
   
+  Uint32 m_sectionPtrI[3];
   SignalHeader header; // 28 bytes
-  SegmentedSectionPtr m_sectionPtr[3]; 
   union {
     Uint32 theData[8192];  // 8192 32-bit words -> 32K Bytes
     Uint64 dummyAlign;
@@ -150,27 +166,6 @@ Signal::getNoOfSections() const {
 }
 
 inline
-bool 
-Signal::getSection(SegmentedSectionPtr & ptr, Uint32 section){
-  if(section < header.m_noOfSections){
-    ptr = m_sectionPtr[section];
-    return true;
-  }
-  ptr.p = 0;
-  return false;
-}
-
-inline
-void
-Signal::setSection(SegmentedSectionPtr ptr, Uint32 sectionNo){
-  if(sectionNo != header.m_noOfSections || sectionNo > 2){
-    abort();
-  }
-  m_sectionPtr[sectionNo] = ptr;
-  header.m_noOfSections++;
-}
-
-inline
 NodeReceiverGroup::NodeReceiverGroup() : m_block(0){
   m_nodes.clear();
 }
@@ -214,6 +209,53 @@ NodeReceiverGroup::operator=(BlockRefere
   m_block = refToBlock(blockRef);
   m_nodes.set(refToNode(blockRef));
   return * this;
+}
+
+inline
+SectionHandle::SectionHandle(SimulatedBlock* b)
+  : m_block(b)
+{
+}
+
+inline
+SectionHandle::SectionHandle(SimulatedBlock* b, Signal* s)
+  : m_cnt(s->header.m_noOfSections),
+    m_block(b)
+{
+  Uint32 * ptr = s->m_sectionPtrI;
+  Uint32 ptr0 = * ptr++;
+  Uint32 ptr1 = * ptr++;
+  Uint32 ptr2 = * ptr++;
+
+  m_ptr[0].i = ptr0;
+  m_ptr[1].i = ptr1;
+  m_ptr[2].i = ptr2;
+
+  getSections(m_cnt, m_ptr);
+
+  s->header.m_noOfSections = 0;
+}
+
+inline
+SectionHandle::SectionHandle(SimulatedBlock* b, Uint32 ptr)
+  : m_cnt(1),
+    m_block(b)
+{
+  m_ptr[0].i = ptr;
+  getSections(1, m_ptr);
+}
+
+inline
+bool
+SectionHandle::getSection(SegmentedSectionPtr& ptr, Uint32 no)
+{
+  if (likely(no < m_cnt))
+  {
+    ptr = m_ptr[no];
+    return true;
+  }
+
+  return false;
 }
 
 #endif
Thread
bk commit into 5.1 tree (knielsen:1.2609)knielsen24 Sep