List:Commits« Previous MessageNext Message »
From:Maitrayi Sabaratnam Date:October 1 2010 10:28am
Subject:bzr commit into mysql-5.1-telco-7.0-mai branch (msabaratnam:3254)
View as plain text  
#At file:///export/home2/tmp/maitrayi/mysql-src2/mysql-5.1-telco-7.0-mai/ based on revid:msabaratnam@stripped

 3254 Maitrayi Sabaratnam	2010-10-01 [merge]
      Merge with 7.0 - revno 3815

    added:
      storage/ndb/src/ndbapi/trp_client.hpp
    modified:
      storage/ndb/include/kernel/signaldata/WaitGCP.hpp
      storage/ndb/include/ndbapi/Ndb.hpp
      storage/ndb/include/ndbapi/NdbDictionary.hpp
      storage/ndb/include/ndbapi/NdbTransaction.hpp
      storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
      storage/ndb/src/mgmsrv/MgmtSrvr.cpp
      storage/ndb/src/mgmsrv/MgmtSrvr.hpp
      storage/ndb/src/ndbapi/Ndb.cpp
      storage/ndb/src/ndbapi/NdbDictionary.cpp
      storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp
      storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp
      storage/ndb/src/ndbapi/NdbImpl.hpp
      storage/ndb/src/ndbapi/NdbTransaction.cpp
      storage/ndb/src/ndbapi/Ndbif.cpp
      storage/ndb/src/ndbapi/SignalSender.cpp
      storage/ndb/src/ndbapi/SignalSender.hpp
      storage/ndb/src/ndbapi/TransporterFacade.cpp
      storage/ndb/src/ndbapi/TransporterFacade.hpp
      storage/ndb/test/ndbapi/testDict.cpp
      storage/ndb/test/ndbapi/testRestartGci.cpp
=== modified file 'storage/ndb/include/kernel/signaldata/WaitGCP.hpp'
--- a/storage/ndb/include/kernel/signaldata/WaitGCP.hpp	2009-05-27 15:21:45 +0000
+++ b/storage/ndb/include/kernel/signaldata/WaitGCP.hpp	2010-09-30 14:27:18 +0000
@@ -51,7 +51,8 @@ public:
     CurrentGCI        = 8,  ///< Immediately return current GCI
     BlockStartGcp     = 9,
     UnblockStartGcp   = 10,
-    WaitEpoch         = 11  // If GCP is blocked, wait for epoch to not start
+    WaitEpoch         = 11, // If GCP is blocked, wait for epoch to not start
+    RestartGCI        = 12  // Return restart GCI
   };
 
   Uint32 senderRef;
@@ -98,6 +99,7 @@ class WaitGCPRef {
   friend class Dbdict;
   friend class Backup;
   friend class Trix;
+  friend class NdbDictInterface;
 
 public:
   STATIC_CONST( SignalLength = 2 );

=== modified file 'storage/ndb/include/ndbapi/Ndb.hpp'
--- a/storage/ndb/include/ndbapi/Ndb.hpp	2010-09-29 13:25:19 +0000
+++ b/storage/ndb/include/ndbapi/Ndb.hpp	2010-09-30 14:27:18 +0000
@@ -1664,23 +1664,6 @@ public:
   };
 
   /**
-   * For testing purposes it is possible to tamper with the NDB Cluster
-   * (i.e. send a special signal to DBDIH, the NDB distribution handler).
-   * <b>This feature should only used for debugging purposes.</b>
-   * In a release versions of NDB Cluster,
-   * this call always return -1 and does nothing.
-   * 
-   * @param aAction Action to be taken according to TamperType above
-   *
-   * @param aNode  Which node the action will be taken
-   *              -1:   Master DIH.
-   *            0-16:   Nodnumber.
-   * @return -1 indicates error, other values have meaning dependent 
-   *          on type of tampering.
-   */
-  int NdbTamper(TamperType aAction, int aNode);  
-
-  /**
    * Return a unique tuple id for a table.  The id sequence is
    * ascending but may contain gaps.  Methods which have no
    * TupleIdRange argument use NDB API dict cache.  They may
@@ -1846,9 +1829,6 @@ private:
                                       Uint32 nodeSequence,
                                       Uint32 *ret_conn_seq= 0);
   
-  // Sets Restart GCI in Ndb object
-  void			RestartGCI(int aRestartGCI);
-
   // Get block number of this NDBAPI object
   int			getBlockNumber();
   

=== modified file 'storage/ndb/include/ndbapi/NdbDictionary.hpp'
--- a/storage/ndb/include/ndbapi/NdbDictionary.hpp	2010-09-30 13:15:22 +0000
+++ b/storage/ndb/include/ndbapi/NdbDictionary.hpp	2010-10-01 10:27:55 +0000
@@ -2325,6 +2325,11 @@ public:
      */
     int forceGCPWait();
     int forceGCPWait(int type);
+
+    /**
+     * Get restart gci
+     */
+    int getRestartGCI(Uint32 * gci);
 #endif
 
     /** @} *******************************************************************/

=== modified file 'storage/ndb/include/ndbapi/NdbTransaction.hpp'
--- a/storage/ndb/include/ndbapi/NdbTransaction.hpp	2010-09-29 13:25:19 +0000
+++ b/storage/ndb/include/ndbapi/NdbTransaction.hpp	2010-09-30 14:27:18 +0000
@@ -942,7 +942,6 @@ private:
   Uint32        get_send_size();                  // Get size to send
   void          set_send_size(Uint32);            // Set size to send;
   
-  int  receiveDIHNDBTAMPER(const NdbApiSignal* anApiSignal);
   int  receiveTCSEIZECONF(const NdbApiSignal* anApiSignal);
   int  receiveTCSEIZEREF(const NdbApiSignal* anApiSignal);
   int  receiveTCRELEASECONF(const NdbApiSignal* anApiSignal);

=== modified file 'storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp'
--- a/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp	2010-09-13 14:31:30 +0000
+++ b/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp	2010-09-30 14:27:18 +0000
@@ -17993,6 +17993,18 @@ void Dbdih::execWAIT_GCP_REQ(Signal* sig
     return;
   }//if
 
+  if(requestType == WaitGCPReq::RestartGCI)
+  {
+    jam();
+    conf->senderData = senderData;
+    conf->gci_hi = Uint32(crestartGci);
+    conf->gci_lo = 0;
+    conf->blockStatus = cgcpOrderBlocked;
+    sendSignal(senderRef, GSN_WAIT_GCP_CONF, signal,
+	       WaitGCPConf::SignalLength, JBB);
+    return;
+  }//if
+
   if (requestType == WaitGCPReq::BlockStartGcp)
   {
     jam();

=== modified file 'storage/ndb/src/mgmsrv/MgmtSrvr.cpp'
--- a/storage/ndb/src/mgmsrv/MgmtSrvr.cpp	2010-09-29 13:25:19 +0000
+++ b/storage/ndb/src/mgmsrv/MgmtSrvr.cpp	2010-10-01 07:38:17 +0000
@@ -408,9 +408,7 @@ MgmtSrvr::start_transporter(const Config
     Register ourself at TransporterFacade to be able to receive signals
     and to be notified when a database process has died.
   */
-  if ((_blockNumber= theFacade->open(this,
-                                     signalReceivedNotification,
-                                     nodeStatusNotification)) == -1)
+  if ((_blockNumber= theFacade->open(this)) == -1)
   {
     g_eventLogger->error("Failed to open block in TransporterFacade");
     theFacade->stop_instance();
@@ -2457,7 +2455,8 @@ const char* MgmtSrvr::getErrorText(int e
 
 
 void
-MgmtSrvr::handleReceivedSignal(const NdbApiSignal* signal)
+MgmtSrvr::trp_deliver_signal(const NdbApiSignal* signal,
+                             const LinearSectionPtr ptr[3])
 {
   int gsn = signal->readSignalNumber();
 
@@ -2492,16 +2491,7 @@ MgmtSrvr::handleReceivedSignal(const Ndb
 
 
 void
-MgmtSrvr::signalReceivedNotification(void* mgmtSrvr,
-                                     const NdbApiSignal* signal,
-				     const LinearSectionPtr ptr[3])
-{
-  ((MgmtSrvr*)mgmtSrvr)->handleReceivedSignal(signal);
-}
-
-
-void
-MgmtSrvr::handleStatus(NodeId nodeId, bool alive, bool nfComplete)
+MgmtSrvr::trp_node_status(Uint32 nodeId, bool alive, bool nfComplete)
 {
   DBUG_ENTER("MgmtSrvr::handleStatus");
   DBUG_PRINT("enter",("nodeid: %d, alive: %d, nfComplete: %d",
@@ -2532,15 +2522,6 @@ MgmtSrvr::handleStatus(NodeId nodeId, bo
   DBUG_VOID_RETURN;
 }
 
-
-void
-MgmtSrvr::nodeStatusNotification(void* mgmSrv, Uint32 nodeId,
-				 bool alive, bool nfComplete)
-{
-  ((MgmtSrvr*)mgmSrv)->handleStatus(nodeId, alive, nfComplete);
-}
-
-
 enum ndb_mgm_node_type 
 MgmtSrvr::getNodeType(NodeId nodeId) const 
 {

=== modified file 'storage/ndb/src/mgmsrv/MgmtSrvr.hpp'
--- a/storage/ndb/src/mgmsrv/MgmtSrvr.hpp	2010-09-29 13:25:19 +0000
+++ b/storage/ndb/src/mgmsrv/MgmtSrvr.hpp	2010-10-01 07:38:17 +0000
@@ -73,7 +73,7 @@ public:
   @class MgmtSrvr
   @brief Main class for the management server.
  */
-class MgmtSrvr : private ConfigSubscriber {
+class MgmtSrvr : private ConfigSubscriber, public trp_client {
 
 public:
   // some compilers need all of this
@@ -469,30 +469,12 @@ private:
   NodeBitmask m_reserved_nodes;
   struct in_addr m_connect_address[MAX_NODES];
 
-  void handleReceivedSignal(const NdbApiSignal* signal);
-  void handleStatus(NodeId nodeId, bool alive, bool nfComplete);
-
   /**
-     Callback function installed into TransporterFacade, will be called
-     once for each new signal received to the MgmtSrvr.
-     @param  mgmtSrvr: The MgmtSrvr object which shall recieve the signal.
-     @param  signal: The received signal.
-     @param  ptr: The long part(s) of the signal
-   */
-  static void signalReceivedNotification(void* mgmtSrvr, 
-					 const NdbApiSignal* signal,
-					 const struct LinearSectionPtr ptr[3]);
-
-  /**
-     Callback function installed into TransporterFacade, will be called
-     when status of a node changes.
-     @param  mgmtSrvr: The MgmtSrvr object which shall receive
-     the notification.
-     @param  processId: Id of the node whose status changed.
-     @param alive: true if the other node is alive
+   * trp_client interface
    */
-  static void nodeStatusNotification(void* mgmSrv, Uint32 nodeId, 
-				     bool alive, bool nfCompleted);
+  virtual void trp_deliver_signal(const NdbApiSignal* signal,
+                                  const struct LinearSectionPtr ptr[3]);
+  virtual void trp_node_status(Uint32 nodeId, bool alive, bool nfCompleted);
   
   /**
    * An event from <i>nodeId</i> has arrived

=== modified file 'storage/ndb/src/ndbapi/Ndb.cpp'
--- a/storage/ndb/src/ndbapi/Ndb.cpp	2010-09-30 09:32:28 +0000
+++ b/storage/ndb/src/ndbapi/Ndb.cpp	2010-09-30 14:27:18 +0000
@@ -990,171 +990,6 @@ Ndb::closeTransaction(NdbTransaction* aC
   DBUG_VOID_RETURN;
 }//Ndb::closeTransaction()
 
-/*****************************************************************************
-int* NdbTamper(int aAction, int aNode);
-
-Parameters: aAction     Specifies what action to be taken
-            1: Lock global checkpointing    Can only be sent to master DIH, Parameter aNode ignored.
-            2: UnLock global checkpointing    Can only be sent to master DIH, Parameter aNode ignored.
-	    3: Crash node
-
-           aNode        Specifies which node the action will be taken
-     	  -1: Master DIH 
-       	0-16: Nodnumber
-
-Return Value: -1 Error  .
-                
-Remark:         Sends a signal to DIH.
-*****************************************************************************/ 
-int 
-Ndb::NdbTamper(TamperType aAction, int aNode)
-{
-  NdbTransaction*	tNdbConn;
-  NdbApiSignal		tSignal(theMyRef);
-  int			tNode;
-  int                   tAction;
-  int			ret_code;
-
-#ifdef CUSTOMER_RELEASE
-  return -1;
-#else
-  DBUG_ENTER("Ndb::NdbTamper");
-  CHECK_STATUS_MACRO;
-  checkFailedNode();
-
-  theRestartGCI = 0;
-  switch (aAction) {
-// Translate enum to integer. This is done because the SCI layer
-// expects integers. 
-     case LockGlbChp:
-        tAction = 1;
-        break;
-     case UnlockGlbChp:
-        tAction = 2;
-	break;
-     case CrashNode:
-        tAction = 3;
-        break;
-     case ReadRestartGCI:
-	tAction = 4;
-	break;
-     default:
-        theError.code = 4102;
-        DBUG_RETURN(-1);
-  }
-
-  tNdbConn = getNdbCon();	// Get free connection object
-  if (tNdbConn == NULL) {
-    theError.code = 4000;
-    DBUG_RETURN(-1);
-  }
-  tSignal.setSignal(GSN_DIHNDBTAMPER);
-  tSignal.setData (tAction, 1);
-  tSignal.setData(tNdbConn->ptr2int(),2);
-  tSignal.setData(theMyRef,3);		// Set return block reference
-  tNdbConn->Status(NdbTransaction::Connecting); // Set status to connecting
-  TransporterFacade *tp = theImpl->m_transporter_facade;
-  if (tAction == 3) {
-    tp->lock_mutex();
-    tp->sendSignal(&tSignal, aNode);
-    tp->unlock_mutex();
-    releaseNdbCon(tNdbConn);
-  } else if ( (tAction == 2) || (tAction == 1) ) {
-    tp->lock_mutex();
-    tNode = tp->get_an_alive_node();
-    if (tNode == 0) {
-      theError.code = 4002;
-      releaseNdbCon(tNdbConn);
-      DBUG_RETURN(-1);
-    }//if
-    ret_code = tp->sendSignal(&tSignal,aNode);
-    tp->unlock_mutex();
-    releaseNdbCon(tNdbConn);
-    DBUG_RETURN(ret_code);
-  } else {
-    do {
-      tp->lock_mutex();
-      // Start protected area
-      tNode = tp->get_an_alive_node();
-      tp->unlock_mutex();
-      // End protected area
-      if (tNode == 0) {
-        theError.code = 4009;
-        releaseNdbCon(tNdbConn);
-        DBUG_RETURN(-1);
-      }//if
-      ret_code = sendRecSignal(tNode, WAIT_NDB_TAMPER, &tSignal, 0);
-      if (ret_code == 0) {  
-        if (tNdbConn->Status() != NdbTransaction::Connected) {
-          theRestartGCI = 0;
-        }//if
-        releaseNdbCon(tNdbConn);
-        DBUG_RETURN(theRestartGCI);
-      } else if ((ret_code == -5) || (ret_code == -2)) {
-        TRACE_DEBUG("Continue DIHNDBTAMPER when node failed/stopping");
-      } else {
-        DBUG_RETURN(-1);
-      }//if
-    } while (1);
-  }
-  DBUG_RETURN(0);
-#endif
-}
-#if 0
-/****************************************************************************
-NdbSchemaCon* startSchemaTransaction();
-
-Return Value:   Returns a pointer to a schema connection object.
-                Return NULL otherwise.
-Remark:         Start schema transaction. Synchronous.
-****************************************************************************/ 
-NdbSchemaCon* 
-Ndb::startSchemaTransaction()
-{
-  NdbSchemaCon* tSchemaCon;
-  if (theSchemaConToNdbList != NULL) {
-    theError.code = 4321;
-    return NULL;
-  }//if
-  tSchemaCon = new NdbSchemaCon(this);
-  if (tSchemaCon == NULL) {
-    theError.code = 4000;
-    return NULL;
-  }//if 
-  theSchemaConToNdbList = tSchemaCon;
-  return tSchemaCon;  
-}
-/*****************************************************************************
-void closeSchemaTransaction(NdbSchemaCon* aSchemaCon);
-
-Parameters:     aSchemaCon: the schemacon used in the transaction.
-Remark:         Close transaction by releasing the schemacon and all schemaop.
-*****************************************************************************/
-void
-Ndb::closeSchemaTransaction(NdbSchemaCon* aSchemaCon)
-{
-  if (theSchemaConToNdbList != aSchemaCon) {
-    abort();
-    return;
-  }//if
-  aSchemaCon->release();
-  delete aSchemaCon;
-  theSchemaConToNdbList = NULL;
-  return;
-}//Ndb::closeSchemaTransaction()
-#endif
-
-/*****************************************************************************
-void RestartGCI(int aRestartGCI);
-
-Remark:		Set theRestartGCI on the NDB object
-*****************************************************************************/
-void
-Ndb::RestartGCI(int aRestartGCI)
-{
-  theRestartGCI = aRestartGCI;
-}
-
 /****************************************************************************
 int getBlockNumber(void);
 

=== modified file 'storage/ndb/src/ndbapi/NdbDictionary.cpp'
--- a/storage/ndb/src/ndbapi/NdbDictionary.cpp	2010-09-30 13:15:22 +0000
+++ b/storage/ndb/src/ndbapi/NdbDictionary.cpp	2010-10-01 10:27:55 +0000
@@ -2568,6 +2568,12 @@ NdbDictionary::Dictionary::forceGCPWait(
   return m_impl.forceGCPWait(type);
 }
 
+int
+NdbDictionary::Dictionary::getRestartGCI(Uint32 * gci)
+{
+  return m_impl.getRestartGCI(gci);
+}
+
 void
 NdbDictionary::Dictionary::removeCachedIndex(const Index *index){
   DBUG_ENTER("NdbDictionary::Dictionary::removeCachedIndex");

=== modified file 'storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp'
--- a/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp	2010-10-01 08:53:44 +0000
+++ b/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp	2010-10-01 10:27:55 +0000
@@ -4609,7 +4609,7 @@ NdbDictInterface::executeSubscribeEvent(
                        errCodes, -1);
   if (ret == 0)
   {
-    buckets =m_sub_start_conf.m_buckets;
+    buckets = m_data.m_sub_start_conf.m_buckets;
   }
 
   DBUG_RETURN(ret);
@@ -4924,7 +4924,7 @@ NdbDictInterface::execSUB_START_CONF(con
 
   if (signal->getLength() == SubStartConf::SignalLength)
   {
-    m_sub_start_conf.m_buckets = subStartConf->bucketCount;
+    m_data.m_sub_start_conf.m_buckets = subStartConf->bucketCount;
   }
   else
   {
@@ -4932,7 +4932,7 @@ NdbDictInterface::execSUB_START_CONF(con
      * 6.3 doesn't send required bucketCount.  
      * ~0 indicates no bucketCount received
      */
-    m_sub_start_conf.m_buckets = ~0;
+    m_data.m_sub_start_conf.m_buckets = ~0;
   }
   DBUG_PRINT("info",("subscriptionId=%d,subscriptionKey=%d,subscriberData=%d",
 		     subscriptionId,subscriptionKey,subscriberData));
@@ -5781,12 +5781,15 @@ int
 NdbDictInterface::forceGCPWait(int type)
 {
   NdbApiSignal tSignal(m_reference);
-  if (type == 0)
+  if (type == 0 || type == 2)
   {
     WaitGCPReq* const req = CAST_PTR(WaitGCPReq, tSignal.getDataPtrSend());
     req->senderRef = m_reference;
     req->senderData = 0;
-    req->requestType = WaitGCPReq::CompleteForceStart;
+    req->requestType = 
+      type == 0 ? 
+      WaitGCPReq::CompleteForceStart : WaitGCPReq::RestartGCI;
+      
     tSignal.theReceiversBlockNumber = DBDIH;
     tSignal.theVerId_signalNumber = GSN_WAIT_GCP_REQ;
     tSignal.theLength = WaitGCPReq::SignalLength;
@@ -5811,7 +5814,7 @@ NdbDictInterface::forceGCPWait(int type)
       m_waiter.m_state = WAIT_LIST_TABLES_CONF;
       m_waiter.wait(DICT_WAITFOR_TIMEOUT);
       m_transporter->unlock_mutex();
-      return 0;
+      return m_error.code == 0 ? 0 : -1;
     }
     return -1;
   }
@@ -5840,15 +5843,34 @@ NdbDictInterface::forceGCPWait(int type)
       m_transporter->forceSend(refToBlock(m_reference));
       m_transporter->unlock_mutex();
     }
-    return 0;
+    return m_error.code == 0 ? 0 : -1;
+  }
+  else
+  {
+    m_error.code = 4003;
   }
   return -1;
 }
 
+int
+NdbDictionaryImpl::getRestartGCI(Uint32 * gci)
+{
+  int res = m_receiver.forceGCPWait(2);
+  if (res == 0 && gci != 0)
+  {
+    * gci = m_receiver.m_data.m_wait_gcp_conf.gci_hi;
+  }
+  return res;
+}
+
 void
 NdbDictInterface::execWAIT_GCP_CONF(const NdbApiSignal* signal,
 				    const LinearSectionPtr ptr[3])
 {
+  const WaitGCPConf* conf = CAST_CONSTPTR(WaitGCPConf, signal->getDataPtr());
+
+  m_data.m_wait_gcp_conf.gci_lo = conf->gci_lo;
+  m_data.m_wait_gcp_conf.gci_hi = conf->gci_hi;
   m_waiter.signal(NO_WAIT);
 }
 
@@ -5856,6 +5878,9 @@ void
 NdbDictInterface::execWAIT_GCP_REF(const NdbApiSignal* signal,
                                    const LinearSectionPtr ptr[3])
 {
+  const WaitGCPRef* ref = CAST_CONSTPTR(WaitGCPRef, signal->getDataPtr());
+  m_error.code = ref->errorCode;
+
   m_waiter.signal(NO_WAIT);
 }
 

=== modified file 'storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp'
--- a/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp	2010-10-01 08:53:44 +0000
+++ b/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp	2010-10-01 10:27:55 +0000
@@ -662,6 +662,7 @@ public:
 			  Uint32 noOfSections, bool fullyQualifiedNames);
 
   int forceGCPWait(int type);
+  int getRestartGCI(Uint32 *);
 
   static int parseTableInfo(NdbTableImpl ** dst, 
 			    const Uint32 * data, Uint32 len,
@@ -713,6 +714,7 @@ private:
   class TransporterFacade * m_transporter;
   
   friend class Ndb;
+  friend class NdbImpl;
   friend class NdbDictionaryImpl;
   static void execSignal(void* dictImpl, 
 			 const class NdbApiSignal* signal,
@@ -788,9 +790,15 @@ private:
   UtilBuffer m_tableData;
   UtilBuffer m_tableNames;
 
-  struct {
-    Uint32 m_buckets;
-  } m_sub_start_conf;
+  union {
+    struct SubStartConfData {
+      Uint32 m_buckets;
+    } m_sub_start_conf;
+    struct WaitGcpData {
+      Uint32 gci_hi;
+      Uint32 gci_lo;
+    } m_wait_gcp_conf;
+  } m_data;
 };
 
 class NdbDictionaryImpl;
@@ -847,6 +855,7 @@ public:
   int stopSubscribeEvent(NdbEventOperationImpl &);
 
   int forceGCPWait(int type);
+  int getRestartGCI(Uint32*);
 
   int listObjects(List& list, NdbDictionary::Object::Type type, 
                   bool fullyQualified);

=== modified file 'storage/ndb/src/ndbapi/NdbImpl.hpp'
--- a/storage/ndb/src/ndbapi/NdbImpl.hpp	2010-09-30 10:36:47 +0000
+++ b/storage/ndb/src/ndbapi/NdbImpl.hpp	2010-10-01 07:38:17 +0000
@@ -29,6 +29,7 @@
 #include "ndb_cluster_connection_impl.hpp"
 #include "NdbDictionaryImpl.hpp"
 #include "ObjectMap.hpp"
+#include "trp_client.hpp"
 
 template <class T>
 struct Ndb_free_list_t 
@@ -49,7 +50,8 @@ struct Ndb_free_list_t
 /**
  * Private parts of the Ndb object (corresponding to Ndb.hpp in public API)
  */
-class NdbImpl {
+class NdbImpl : public trp_client
+{
 public:
   NdbImpl(Ndb_cluster_connection *, Ndb&);
   ~NdbImpl();
@@ -142,6 +144,13 @@ public:
   Ndb_free_list_t<NdbOperation>  theOpIdleList;  
   Ndb_free_list_t<NdbIndexOperation> theIndexOpIdleList;
   Ndb_free_list_t<NdbTransaction> theConIdleList; 
+
+  /**
+   * trp_client interface
+   */
+  virtual void trp_deliver_signal(const NdbApiSignal*,
+                                  const LinearSectionPtr p[3]);
+  virtual void trp_node_status(Uint32, bool nodeAlive, bool nfComplete);
 };
 
 #ifdef VM_TRACE

=== modified file 'storage/ndb/src/ndbapi/NdbTransaction.cpp'
--- a/storage/ndb/src/ndbapi/NdbTransaction.cpp	2010-09-30 10:36:47 +0000
+++ b/storage/ndb/src/ndbapi/NdbTransaction.cpp	2010-09-30 14:27:18 +0000
@@ -1626,26 +1626,6 @@ NdbTransaction::getNdbIndexOperation(con
 
 
 /*******************************************************************************
-int  receiveDIHNDBTAMPER(NdbApiSignal* aSignal)
-
-Return Value:  Return 0 : receiveDIHNDBTAMPER was successful.
-               Return -1: In all other case.
-Parameters:    aSignal: The signal object pointer.
-Remark:        Sets theRestartGCI in the NDB object. 
-*******************************************************************************/
-int			
-NdbTransaction::receiveDIHNDBTAMPER(const NdbApiSignal* aSignal)
-{
-  if (theStatus != Connecting) {
-    return -1;
-  } else {
-    theNdb->RestartGCI((Uint32)aSignal->readData(2));
-    theStatus = Connected;
-  }//if
-  return 0;  
-}//NdbTransaction::receiveDIHNDBTAMPER()
-
-/*******************************************************************************
 int  receiveTCSEIZECONF(NdbApiSignal* aSignal);
 
 Return Value:  Return 0 : receiveTCSEIZECONF was successful.

=== modified file 'storage/ndb/src/ndbapi/Ndbif.cpp'
--- a/storage/ndb/src/ndbapi/Ndbif.cpp	2010-09-30 11:52:49 +0000
+++ b/storage/ndb/src/ndbapi/Ndbif.cpp	2010-10-01 07:38:17 +0000
@@ -73,9 +73,8 @@ Ndb::init(int aMaxNoOfTransactions)
   TransporterFacade * theFacade =  theImpl->m_transporter_facade;
   theFacade->lock_mutex();
   
-  const int tBlockNo = theFacade->open(this,
-                                       executeMessage, 
-                                       statusMessage);  
+  const int tBlockNo = theFacade->open(theImpl);
+
   if ( tBlockNo == -1 ) {
     theError.code = 4105;
     theFacade->unlock_mutex();
@@ -162,12 +161,10 @@ Ndb::releaseTransactionArrays()
 }//Ndb::releaseTransactionArrays()
 
 void
-Ndb::executeMessage(void* NdbObject,
-                    const NdbApiSignal * aSignal,
-                    const LinearSectionPtr ptr[3])
+NdbImpl::trp_deliver_signal(const NdbApiSignal * aSignal,
+                            const LinearSectionPtr ptr[3])
 {
-  Ndb* tNdb = (Ndb*)NdbObject;
-  tNdb->handleReceivedSignal(aSignal, ptr);
+  m_ndb.handleReceivedSignal(aSignal, ptr);
 }
 
 void Ndb::connected(Uint32 ref)
@@ -215,12 +212,12 @@ void Ndb::report_node_connected(Uint32 n
 }
 
 void
-Ndb::statusMessage(void* NdbObject, Uint32 a_node, bool alive, bool nfComplete)
+NdbImpl::trp_node_status(Uint32 a_node, bool alive, bool nfComplete)
 {
   DBUG_ENTER("Ndb::statusMessage");
   DBUG_PRINT("info", ("a_node: %u  alive: %u  nfComplete: %u",
                       a_node, alive, nfComplete));
-  Ndb* tNdb = (Ndb*)NdbObject;
+  Ndb* tNdb = (Ndb*)&m_ndb;
   if (alive) {
     if (nfComplete) {
       // cluster connect, a_node == own reference
@@ -773,21 +770,6 @@ Ndb::handleReceivedSignal(const NdbApiSi
     theEventBuffer->insertDataL(op, sdata, tLen, copy);
     return;
   }
-  case GSN_DIHNDBTAMPER:
-    {
-      tFirstDataPtr = int2void(tFirstData);
-      if (tFirstDataPtr == 0) goto InvalidSignal;
-      
-      if (tWaitState != WAIT_NDB_TAMPER)
-	return;
-      tCon = void2con(tFirstDataPtr);
-      if (tCon->checkMagicNumber() != 0)
-	return;
-      tReturnCode = tCon->receiveDIHNDBTAMPER(aSignal);
-      if (tReturnCode != -1)
-	theImpl->theWaiter.m_state = NO_WAIT;
-      break;
-    }
   case GSN_SCAN_TABCONF:
     {
       tFirstDataPtr = int2void(tFirstData);

=== modified file 'storage/ndb/src/ndbapi/SignalSender.cpp'
--- a/storage/ndb/src/ndbapi/SignalSender.cpp	2010-09-30 11:52:49 +0000
+++ b/storage/ndb/src/ndbapi/SignalSender.cpp	2010-10-01 07:38:17 +0000
@@ -81,7 +81,7 @@ SignalSender::SignalSender(TransporterFa
   m_cond = NdbCondition_Create();
   theFacade = facade;
   lock();
-  m_blockNo = theFacade->open(this, execSignal, execNodeStatus, blockNo);
+  m_blockNo = theFacade->open(this, blockNo);
   unlock();
   assert(m_blockNo > 0);
 }
@@ -91,7 +91,7 @@ SignalSender::SignalSender(Ndb_cluster_c
   m_cond = NdbCondition_Create();
   theFacade = connection->m_impl.m_transporter_facade;
   lock();
-  m_blockNo = theFacade->open(this, execSignal, execNodeStatus, -1);
+  m_blockNo = theFacade->open(this, -1);
   unlock();
   assert(m_blockNo > 0);
 }
@@ -257,9 +257,9 @@ SignalSender::waitFor(Uint32 timeOutMill
 #include <NdbApiSignal.hpp>
 
 void
-SignalSender::execSignal(void* signalSender, 
-			 const NdbApiSignal* signal,
-			 const struct LinearSectionPtr ptr[3]){
+SignalSender::trp_deliver_signal(const NdbApiSignal* signal,
+                                 const struct LinearSectionPtr ptr[3])
+{
   SimpleSignal * s = new SimpleSignal(true);
   s->header = * signal;
   memcpy(&s->theData[0], signal->getDataPtr(), 4 * s->header.theLength);
@@ -268,23 +268,20 @@ SignalSender::execSignal(void* signalSen
     s->ptr[i].sz = ptr[i].sz;
     memcpy(s->ptr[i].p, ptr[i].p, 4 * ptr[i].sz);
   }
-  SignalSender * ss = (SignalSender*)signalSender;
-  ss->m_jobBuffer.push_back(s);
-  NdbCondition_Signal(ss->m_cond);
+  m_jobBuffer.push_back(s);
+  NdbCondition_Signal(m_cond);
 }
   
 void 
-SignalSender::execNodeStatus(void* signalSender, 
-			     Uint32 nodeId, 
-			     bool alive, 
-			     bool nfCompleted){
+SignalSender::trp_node_status(Uint32 nodeId,
+                              bool alive,
+                              bool nfCompleted){
   if (alive) {
     // node connected
     return;
   }
 
   SimpleSignal * s = new SimpleSignal(true);
-  SignalSender * ss = (SignalSender*)signalSender;
 
   // node disconnected
   if(nfCompleted)
@@ -309,13 +306,13 @@ SignalSender::execNodeStatus(void* signa
     NdbNodeBitmask::clear(rep->theNodes);
 
     // Mark ndb nodes as failed in bitmask
-    const ClusterMgr::Node node= ss->getNodeInfo(nodeId);
+    const ClusterMgr::Node node= getNodeInfo(nodeId);
     if (node.m_info.getType() ==  NodeInfo::DB)
       NdbNodeBitmask::set(rep->theNodes, nodeId);
   }
 
-  ss->m_jobBuffer.push_back(s);
-  NdbCondition_Signal(ss->m_cond);
+  m_jobBuffer.push_back(s);
+  NdbCondition_Signal(m_cond);
 }
 
 

=== modified file 'storage/ndb/src/ndbapi/SignalSender.hpp'
--- a/storage/ndb/src/ndbapi/SignalSender.hpp	2010-09-29 13:25:19 +0000
+++ b/storage/ndb/src/ndbapi/SignalSender.hpp	2010-10-01 07:38:17 +0000
@@ -21,6 +21,7 @@
 
 #include <ndb_global.h>
 #include "TransporterFacade.hpp"
+#include "trp_client.hpp"
 #include <Vector.hpp>
 
 #include <signaldata/TestOrd.hpp>
@@ -84,7 +85,7 @@ private:
   bool deallocSections;
 };
 
-class SignalSender {
+class SignalSender  : public trp_client {
 public:
   SignalSender(TransporterFacade *facade, int blockNo = -1);
   SignalSender(Ndb_cluster_connection* connection);
@@ -119,13 +120,16 @@ private:
   int m_blockNo;
   TransporterFacade * theFacade;
   
-  static void execSignal(void* signalSender, 
-			 const NdbApiSignal* signal,
-			 const struct LinearSectionPtr ptr[3]);
+public:
+  /**
+   * trp_client interface
+   */
+  virtual void trp_deliver_signal(const NdbApiSignal* signal,
+                                  const struct LinearSectionPtr ptr[3]);
   
-  static void execNodeStatus(void* signalSender, Uint32 nodeId, 
-			     bool alive, bool nfCompleted);
+  virtual void trp_node_status(Uint32 nodeId, bool alive, bool nfCompleted);
   
+private:
   int m_lock;
   struct NdbCondition * m_cond;
   Vector<SimpleSignal *> m_jobBuffer;

=== modified file 'storage/ndb/src/ndbapi/TransporterFacade.cpp'
--- a/storage/ndb/src/ndbapi/TransporterFacade.cpp	2010-09-30 11:52:49 +0000
+++ b/storage/ndb/src/ndbapi/TransporterFacade.cpp	2010-10-01 07:38:17 +0000
@@ -17,8 +17,8 @@
 */
 
 #include <ndb_global.h>
-#include <my_pthread.h>
 #include <ndb_limits.h>
+#include "trp_client.hpp"
 #include "TransporterFacade.hpp"
 #include "ClusterMgr.hpp"
 #include <IPCConfig.hpp>
@@ -211,24 +211,24 @@ TransporterFacade::deliver_signal(Signal
                                   Uint8 prio, Uint32 * const theData,
                                   LinearSectionPtr ptr[3])
 {
-
-  TransporterFacade::ThreadData::Object_Execute oe; 
   Uint32 tRecBlockNo = header->theReceiversBlockNumber;
   
 #ifdef API_TRACE
   if(setSignalLog() && TRACE_GSN(header->theVerId_signalNumber)){
     signalLogger.executeSignal(* header, 
-			       prio,
+                               prio,
                                theData,
-			       ownId(),
+                               ownId(),
                                ptr, header->m_noOfSections);
     signalLogger.flushSignalLog();
   }
 #endif  
 
-  if (tRecBlockNo >= MIN_API_BLOCK_NO) {
-    oe = m_threads.get(tRecBlockNo);
-    if (oe.m_object != 0 && oe.m_executeFunction != 0) {
+  if (tRecBlockNo >= MIN_API_BLOCK_NO)
+  {
+    trp_client * clnt = m_threads.get(tRecBlockNo);
+    if (clnt != 0)
+    {
       /**
        * Handle received signal immediately to avoid any unnecessary
        * copying of data, allocation of memory and other things. Copying
@@ -243,9 +243,11 @@ TransporterFacade::deliver_signal(Signal
       NdbApiSignal tmpSignal(*header);
       NdbApiSignal * tSignal = &tmpSignal;
       tSignal->setDataPtr(theData);
-      (* oe.m_executeFunction) (oe.m_object, tSignal, ptr);
+      clnt->trp_deliver_signal(tSignal, ptr);
     }//if
-  } else if (tRecBlockNo == API_PACKED) {
+  }
+  else if (tRecBlockNo == API_PACKED)
+  {
     /**
      * Block number == 2047 is used to signal a signal that consists of
      * multiple instances of the same signal. This is an effort to
@@ -263,150 +265,162 @@ TransporterFacade::deliver_signal(Signal
       Tsent++;
       Uint32 TpacketLen = (Theader & 0x1F) + 3;
       tRecBlockNo = Theader >> 16;
-      if (TpacketLen <= 25) {
-	if ((TpacketLen + Tsent) <= Tlength) {
-	  /**
-	   * Set the data length of the signal and the receivers block
-	   * reference and then call the API.
-	   */
-	  header->theLength = TpacketLen;
-	  header->theReceiversBlockNumber = tRecBlockNo;
-	  Uint32* tDataPtr = &theData[Tsent];
-	  Tsent += TpacketLen;
-	  if (tRecBlockNo >= MIN_API_BLOCK_NO) {
-	    oe = m_threads.get(tRecBlockNo);
-	    if(oe.m_object != 0 && oe.m_executeFunction != 0){
-	      NdbApiSignal tmpSignal(*header);
-	      NdbApiSignal * tSignal = &tmpSignal;
-	      tSignal->setDataPtr(tDataPtr);
-	      (*oe.m_executeFunction)(oe.m_object, tSignal, 0);
-	    }
-	  }
-	}
+      if (TpacketLen <= 25)
+      {
+        if ((TpacketLen + Tsent) <= Tlength)
+        {
+          /**
+           * Set the data length of the signal and the receivers block
+           * reference and then call the API.
+           */
+          header->theLength = TpacketLen;
+          header->theReceiversBlockNumber = tRecBlockNo;
+          Uint32* tDataPtr = &theData[Tsent];
+          Tsent += TpacketLen;
+          if (tRecBlockNo >= MIN_API_BLOCK_NO)
+          {
+            trp_client * clnt = m_threads.get(tRecBlockNo);
+            if(clnt != 0)
+            {
+              NdbApiSignal tmpSignal(*header);
+              NdbApiSignal * tSignal = &tmpSignal;
+              tSignal->setDataPtr(tDataPtr);
+              clnt->trp_deliver_signal(tSignal, 0);
+            }
+          }
+        }
+      }
+    }
+    return;
+  }
+  else if (tRecBlockNo == API_CLUSTERMGR)
+  {
+    /**
+     * The signal was aimed for the Cluster Manager. 
+     * We handle it immediately here.
+     */     
+    ClusterMgr * clusterMgr = theClusterMgr;
+    const Uint32 gsn = header->theVerId_signalNumber;
+    
+    switch (gsn){
+    case GSN_API_REGREQ:
+      clusterMgr->execAPI_REGREQ(theData);
+      break;
+      
+    case GSN_API_REGCONF:
+    {
+      clusterMgr->execAPI_REGCONF(theData);
+      
+      // Distribute signal to all threads/blocks
+      NdbApiSignal tSignal(* header);
+      tSignal.setDataPtr(theData);
+      for_each(&tSignal, ptr);
+      break;
+    }
+    
+    case GSN_API_REGREF:
+      clusterMgr->execAPI_REGREF(theData);
+      break;
+      
+    case GSN_NODE_FAILREP:
+      clusterMgr->execNODE_FAILREP(theData);
+      break;
+      
+    case GSN_NF_COMPLETEREP:
+      clusterMgr->execNF_COMPLETEREP(theData);
+      break;
+      
+    case GSN_ARBIT_STARTREQ:
+      if (theArbitMgr != NULL)
+        theArbitMgr->doStart(theData);
+      break;
+      
+    case GSN_ARBIT_CHOOSEREQ:
+      if (theArbitMgr != NULL)
+        theArbitMgr->doChoose(theData);
+      break;
+      
+    case GSN_ARBIT_STOPORD:
+      if(theArbitMgr != NULL)
+        theArbitMgr->doStop(theData);
+      break;
+      
+    case GSN_ALTER_TABLE_REP:
+    {
+      if (m_globalDictCache == NULL)
+        break;
+      const AlterTableRep* rep = (const AlterTableRep*)theData;
+      m_globalDictCache->lock();
+      m_globalDictCache->
+        alter_table_rep((const char*)ptr[0].p, 
+                        rep->tableId,
+                        rep->tableVersion,
+                        rep->changeType == AlterTableRep::CT_ALTERED);
+      m_globalDictCache->unlock();
+      break;
+    }
+    case GSN_SUB_GCP_COMPLETE_REP:
+    {
+      /**
+       * Report
+       */
+      NdbApiSignal tSignal(* header);
+      tSignal.setDataPtr(theData);
+      for_each(&tSignal, ptr);
+      
+      /**
+       * Reply
+       */
+      {
+        Uint32* send= tSignal.getDataPtrSend();
+        memcpy(send, theData, tSignal.getLength() << 2);
+        CAST_PTR(SubGcpCompleteAck, send)->rep.senderRef = 
+          numberToRef(API_CLUSTERMGR, theOwnId);
+        Uint32 ref= header->theSendersBlockRef;
+        Uint32 aNodeId= refToNode(ref);
+        tSignal.theReceiversBlockNumber= refToBlock(ref);
+        tSignal.theVerId_signalNumber= GSN_SUB_GCP_COMPLETE_ACK;
+        sendSignalUnCond(&tSignal, aNodeId);
       }
+      break;
+    }
+    case GSN_TAKE_OVERTCCONF:
+    {
+      /**
+       * Report
+       */
+      NdbApiSignal tSignal(* header);
+      tSignal.setDataPtr(theData);
+      for_each(&tSignal, ptr);
+      return;
+    }
+    default:
+      break;
+      
     }
     return;
-  } else if (tRecBlockNo == API_CLUSTERMGR) {
-     /**
-      * The signal was aimed for the Cluster Manager. 
-      * We handle it immediately here.
-      */     
-     ClusterMgr * clusterMgr = theClusterMgr;
-     const Uint32 gsn = header->theVerId_signalNumber;
-
-     switch (gsn){
-     case GSN_API_REGREQ:
-       clusterMgr->execAPI_REGREQ(theData);
-       break;
-
-     case GSN_API_REGCONF:
-     {
-       clusterMgr->execAPI_REGCONF(theData);
-
-       // Distribute signal to all threads/blocks
-       NdbApiSignal tSignal(* header);
-       tSignal.setDataPtr(theData);
-       for_each(&tSignal, ptr);
-       break;
-     }
-
-     case GSN_API_REGREF:
-       clusterMgr->execAPI_REGREF(theData);
-       break;
-
-     case GSN_NODE_FAILREP:
-       clusterMgr->execNODE_FAILREP(theData);
-       break;
-       
-     case GSN_NF_COMPLETEREP:
-       clusterMgr->execNF_COMPLETEREP(theData);
-       break;
-
-     case GSN_ARBIT_STARTREQ:
-       if (theArbitMgr != NULL)
-	 theArbitMgr->doStart(theData);
-       break;
-       
-     case GSN_ARBIT_CHOOSEREQ:
-       if (theArbitMgr != NULL)
-	 theArbitMgr->doChoose(theData);
-       break;
-       
-     case GSN_ARBIT_STOPORD:
-       if(theArbitMgr != NULL)
-	 theArbitMgr->doStop(theData);
-       break;
-
-     case GSN_ALTER_TABLE_REP:
-     {
-       if (m_globalDictCache == NULL)
-         break;
-       const AlterTableRep* rep = (const AlterTableRep*)theData;
-       m_globalDictCache->lock();
-       m_globalDictCache->
-	 alter_table_rep((const char*)ptr[0].p, 
-			 rep->tableId,
-			 rep->tableVersion,
-			 rep->changeType == AlterTableRep::CT_ALTERED);
-       m_globalDictCache->unlock();
-       break;
-     }
-     case GSN_SUB_GCP_COMPLETE_REP:
-     {
-       /**
-	* Report
-	*/
-       NdbApiSignal tSignal(* header);
-       tSignal.setDataPtr(theData);
-       for_each(&tSignal, ptr);
-
-       /**
-	* Reply
-	*/
-       {
-	 Uint32* send= tSignal.getDataPtrSend();
-	 memcpy(send, theData, tSignal.getLength() << 2);
-	 CAST_PTR(SubGcpCompleteAck, send)->rep.senderRef = 
-	   numberToRef(API_CLUSTERMGR, theOwnId);
-	 Uint32 ref= header->theSendersBlockRef;
-	 Uint32 aNodeId= refToNode(ref);
-	 tSignal.theReceiversBlockNumber= refToBlock(ref);
-	 tSignal.theVerId_signalNumber= GSN_SUB_GCP_COMPLETE_ACK;
-	 sendSignalUnCond(&tSignal, aNodeId);
-       }
-       break;
-     }
-     case GSN_TAKE_OVERTCCONF:
-     {
-       /**
-	* Report
-	*/
-       NdbApiSignal tSignal(* header);
-       tSignal.setDataPtr(theData);
-       for_each(&tSignal, ptr);
-       return;
-     }
-     default:
-       break;
-       
-     }
-     return;
-  } else if (tRecBlockNo >= MIN_API_FIXED_BLOCK_NO &&
-             tRecBlockNo <= MAX_API_FIXED_BLOCK_NO) {
+  }
+  else if (tRecBlockNo >= MIN_API_FIXED_BLOCK_NO &&
+           tRecBlockNo <= MAX_API_FIXED_BLOCK_NO) 
+  {
     Uint32 dynamic= m_fixed2dynamic[tRecBlockNo - MIN_API_FIXED_BLOCK_NO];
-    oe = m_threads.get(dynamic);
-    if (oe.m_object != 0 && oe.m_executeFunction != 0) {
+    trp_client * clnt = m_threads.get(dynamic);
+    if (clnt != 0)
+    {
       NdbApiSignal tmpSignal(*header);
       NdbApiSignal * tSignal = &tmpSignal;
       tSignal->setDataPtr(theData);
-      (* oe.m_executeFunction) (oe.m_object, tSignal, ptr);
+      clnt->trp_deliver_signal(tSignal, ptr);
     }//if   
-  } else {
-    ; // Ignore all other block numbers.
-    if(header->theVerId_signalNumber != GSN_API_REGREQ) {
+  }
+  else
+  {
+    // Ignore all other block numbers.
+    if(header->theVerId_signalNumber != GSN_API_REGREQ)
+    {
       TRP_DEBUG( "TransporterFacade received signal to unknown block no." );
       ndbout << "BLOCK NO: "  << tRecBlockNo << " sig " 
-	     << header->theVerId_signalNumber  << endl;
+             << header->theVerId_signalNumber  << endl;
       abort();
     }
   }
@@ -877,13 +891,12 @@ void
 TransporterFacade::for_each(NdbApiSignal* aSignal, LinearSectionPtr ptr[3])
 {
   Uint32 sz = m_threads.m_statusNext.size();
-  TransporterFacade::ThreadData::Object_Execute oe; 
   for (Uint32 i = 0; i < sz ; i ++) 
   {
-    oe = m_threads.m_objectExecute[i];
-    if (m_threads.getInUse(i))
+    trp_client * clnt = m_threads.m_objectExecute[i];
+    if (clnt != 0)
     {
-      (* oe.m_executeFunction) (oe.m_object, aSignal, ptr);
+      clnt->trp_deliver_signal(aSignal, ptr);
     }
   }
 }
@@ -893,11 +906,12 @@ TransporterFacade::connected()
 {
   DBUG_ENTER("TransporterFacade::connected");
   Uint32 sz = m_threads.m_statusNext.size();
-  for (Uint32 i = 0; i < sz ; i ++) {
-    if (m_threads.getInUse(i)){
-      void * obj = m_threads.m_objectExecute[i].m_object;
-      NodeStatusFunction RegPC = m_threads.m_statusFunction[i];
-      (*RegPC) (obj, numberToRef(indexToNumber(i), theOwnId), true, true);
+  for (Uint32 i = 0; i < sz ; i ++)
+  {
+    trp_client * clnt = m_threads.m_objectExecute[i];
+    if (clnt != 0)
+    {
+      clnt->trp_node_status(numberToRef(indexToNumber(i), theOwnId), true, true);
     }
   }
   DBUG_VOID_RETURN;
@@ -917,11 +931,12 @@ TransporterFacade::ReportNodeDead(NodeId
    * might not have noticed the failure.
    */
   Uint32 sz = m_threads.m_statusNext.size();
-  for (Uint32 i = 0; i < sz ; i ++) {
-    if (m_threads.getInUse(i)){
-      void * obj = m_threads.m_objectExecute[i].m_object;
-      NodeStatusFunction RegPC = m_threads.m_statusFunction[i];
-      (*RegPC) (obj, tNodeId, false, false);
+  for (Uint32 i = 0; i < sz ; i ++)
+  {
+    trp_client * clnt = m_threads.m_objectExecute[i];
+    if (clnt != 0)
+    {
+      clnt->trp_node_status(tNodeId, false, false);
     }
   }
   DBUG_VOID_RETURN;
@@ -942,11 +957,12 @@ TransporterFacade::ReportNodeFailureComp
   DBUG_ENTER("TransporterFacade::ReportNodeFailureComplete");
   DBUG_PRINT("enter",("nodeid= %d", tNodeId));
   Uint32 sz = m_threads.m_statusNext.size();
-  for (Uint32 i = 0; i < sz ; i ++) {
-    if (m_threads.getInUse(i)){
-      void * obj = m_threads.m_objectExecute[i].m_object;
-      NodeStatusFunction RegPC = m_threads.m_statusFunction[i];
-      (*RegPC) (obj, tNodeId, false, true);
+  for (Uint32 i = 0; i < sz ; i ++)
+  {
+    trp_client * clnt = m_threads.m_objectExecute[i];
+    if (clnt != 0)
+    {
+      clnt->trp_node_status(tNodeId, false, true);
     }
   }
   DBUG_VOID_RETURN;
@@ -965,11 +981,12 @@ TransporterFacade::ReportNodeAlive(NodeI
    * might not have noticed the failure.
    */
   Uint32 sz = m_threads.m_statusNext.size();
-  for (Uint32 i = 0; i < sz ; i ++) {
-    if (m_threads.getInUse(i)){
-      void * obj = m_threads.m_objectExecute[i].m_object;
-      NodeStatusFunction RegPC = m_threads.m_statusFunction[i];
-      (*RegPC) (obj, tNodeId, true, false);
+  for (Uint32 i = 0; i < sz ; i ++)
+  {
+    trp_client * clnt = m_threads.m_objectExecute[i];
+    if (clnt != 0)
+    {
+      clnt->trp_node_status(tNodeId, true, false);
     }
   }
 }
@@ -990,29 +1007,30 @@ TransporterFacade::close_local(BlockNumb
 }
 
 int
-TransporterFacade::open(void* objRef, 
-                        ExecuteFunction fun, 
-                        NodeStatusFunction statusFun,
-                        int blockNo)
+TransporterFacade::open(trp_client * clnt, int blockNo)
 {
   DBUG_ENTER("TransporterFacade::open");
-  int r= m_threads.open(objRef, fun, statusFun);
+  int r= m_threads.open(clnt);
   if (r < 0)
+  {
     DBUG_RETURN(r);
+  }
 
-  if (unlikely(blockNo != -1)){
+  if (unlikely(blockNo != -1))
+  {
     // Using fixed block number, add fixed->dymamic mapping
-    Uint32 fixed_index= blockNo - MIN_API_FIXED_BLOCK_NO;
-
+    Uint32 fixed_index = blockNo - MIN_API_FIXED_BLOCK_NO;
+    
     assert(blockNo >= MIN_API_FIXED_BLOCK_NO &&
            fixed_index <= NO_API_FIXED_BLOCKS);
-
+    
     m_fixed2dynamic[fixed_index]= r;
   }
 
 #if 1
-  if (theOwnId > 0) {
-    (*statusFun)(objRef, numberToRef(r, theOwnId), true, true);
+  if (theOwnId > 0)
+  {
+    clnt->trp_node_status(numberToRef(r, theOwnId), true, true);
   }
 #endif
   DBUG_RETURN(r);
@@ -1746,12 +1764,10 @@ TransporterFacade::ThreadData::ThreadDat
 
 void
 TransporterFacade::ThreadData::expand(Uint32 size){
-  Object_Execute oe = { 0 ,0 };
-  NodeStatusFunction fun = 0;
+  trp_client * oe = 0;
 
   const Uint32 sz = m_statusNext.size();
   m_objectExecute.fill(sz + size, oe);
-  m_statusFunction.fill(sz + size, fun);
   for(Uint32 i = 0; i<size; i++){
     m_statusNext.push_back(sz + i + 1);
   }
@@ -1762,9 +1778,7 @@ TransporterFacade::ThreadData::expand(Ui
 
 
 int
-TransporterFacade::ThreadData::open(void* objRef, 
-				    ExecuteFunction fun, 
-				    NodeStatusFunction fun2)
+TransporterFacade::ThreadData::open(trp_client * clnt)
 {
   Uint32 nextFree = m_firstFree;
 
@@ -1780,11 +1794,8 @@ TransporterFacade::ThreadData::open(void
   m_use_cnt++;
   m_firstFree = m_statusNext[nextFree];
 
-  Object_Execute oe = { objRef , fun };
-
   m_statusNext[nextFree] = INACTIVE;
-  m_objectExecute[nextFree] = oe;
-  m_statusFunction[nextFree] = fun2;
+  m_objectExecute[nextFree] = clnt;
 
   return indexToNumber(nextFree);
 }
@@ -1792,14 +1803,12 @@ TransporterFacade::ThreadData::open(void
 int
 TransporterFacade::ThreadData::close(int number){
   number= numberToIndex(number);
-  assert(getInUse(number));
+  assert(m_objectExecute[number] != 0);
   m_statusNext[number] = m_firstFree;
   assert(m_use_cnt);
   m_use_cnt--;
   m_firstFree = number;
-  Object_Execute oe = { 0, 0 };
-  m_objectExecute[number] = oe;
-  m_statusFunction[number] = 0;
+  m_objectExecute[number] = 0;
   return 0;
 }
 
@@ -1982,8 +1991,7 @@ void PollGuard::unlock_and_signal()
   m_locked=false;
 }
 
-template class Vector<NodeStatusFunction>;
-template class Vector<TransporterFacade::ThreadData::Object_Execute>;
+template class Vector<trp_client*>;
 
 #include "SignalSender.hpp"
 

=== modified file 'storage/ndb/src/ndbapi/TransporterFacade.hpp'
--- a/storage/ndb/src/ndbapi/TransporterFacade.hpp	2010-09-30 11:52:49 +0000
+++ b/storage/ndb/src/ndbapi/TransporterFacade.hpp	2010-10-01 07:38:17 +0000
@@ -35,9 +35,7 @@ struct ndb_mgm_configuration;
 class Ndb;
 class NdbApiSignal;
 class NdbWaiter;
-
-typedef void (* ExecuteFunction)(void *, const NdbApiSignal *, const LinearSectionPtr ptr[3]);
-typedef void (* NodeStatusFunction)(void *, Uint32, bool nodeAlive, bool nfComplete);
+class trp_client;
 
 extern "C" {
   void* runSendRequest_C(void*);
@@ -69,8 +67,7 @@ public:
    * @blockNo block number to use, -1 => any blockNumber
    * @return BlockNumber or -1 for failure
    */
-  int open(void* objRef, ExecuteFunction, NodeStatusFunction,
-           int blockNo = -1);
+  int open(trp_client*, int blockNo = -1);
   
   // Close this block number
   int close(BlockNumber blockNumber);
@@ -262,43 +259,22 @@ private:
     
     ThreadData(Uint32 initialSize = 32);
     
-    /**
-     * Split "object" into 3 list
-     *   This to improve locality
-     *   when iterating over lists
-     */
-    struct Object_Execute {
-      void * m_object;
-      ExecuteFunction m_executeFunction;
-    };
-    struct NodeStatus_NextFree {
-      NodeStatusFunction m_statusFunction;
-    };
-
     Uint32 m_use_cnt;
     Uint32 m_firstFree;
     Vector<Uint32> m_statusNext;
-    Vector<Object_Execute> m_objectExecute;
-    Vector<NodeStatusFunction> m_statusFunction;
+    Vector<trp_client*> m_objectExecute;
     
-    int open(void* objRef, ExecuteFunction, NodeStatusFunction);
+    int open(trp_client*);
     int close(int number);
     void expand(Uint32 size);
 
-    inline Object_Execute get(Uint16 blockNo) const {
+    inline trp_client* get(Uint16 blockNo) const {
       blockNo -= MIN_API_BLOCK_NO;
-      if(likely (blockNo < m_objectExecute.size())){
-	return m_objectExecute[blockNo];
+      if(likely (blockNo < m_objectExecute.size()))
+      {
+        return m_objectExecute.getBase()[blockNo];
       }
-      Object_Execute oe = { 0, 0 };
-      return oe;
-    }
-
-    /**
-     * Is the block number used currently
-     */
-    inline bool getInUse(Uint16 index) const {
-      return (m_statusNext[index] & (1 << 16)) != 0;
+      return 0;
     }
   } m_threads;
 

=== added file 'storage/ndb/src/ndbapi/trp_client.hpp'
--- a/storage/ndb/src/ndbapi/trp_client.hpp	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/src/ndbapi/trp_client.hpp	2010-10-01 07:44:39 +0000
@@ -0,0 +1,37 @@
+/*
+   Copyright (C) 2003 MySQL AB
+    All rights reserved. Use is subject to license terms.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+*/
+
+#ifndef trp_client_hpp
+#define trp_client_hpp
+
+#include <ndb_global.h>
+
+class NdbApiSignal;
+struct LinearSectionPtr;
+
+class trp_client
+{
+public:
+  virtual ~trp_client() {}
+
+  virtual void trp_deliver_signal(const NdbApiSignal *,
+                                  const LinearSectionPtr ptr[3]) = 0;
+  virtual void trp_node_status(Uint32, bool nodeAlive, bool nfComplete) = 0;
+};
+
+#endif

=== modified file 'storage/ndb/test/ndbapi/testDict.cpp'
--- a/storage/ndb/test/ndbapi/testDict.cpp	2010-08-26 12:33:33 +0000
+++ b/storage/ndb/test/ndbapi/testDict.cpp	2010-09-30 14:27:18 +0000
@@ -7749,8 +7749,10 @@ runBug46585(NDBT_Context* ctx, NDBT_Step
     CHECK2(res.waitClusterStarted() == 0,
            "wait cluster started failed");
 
-    int restartGCI = pNdb->NdbTamper(Ndb::ReadRestartGCI, 0);
-    ndbout_c("restartGCI: %d", restartGCI);
+    Uint32 restartGCI = 0;
+    CHECK2(pDic->getRestartGCI(&restartGCI) == 0,
+           "getRestartGCI failed");
+    ndbout_c("restartGCI: %u", restartGCI);
 
     pDic->invalidateTable(tab.getName());
     {

=== modified file 'storage/ndb/test/ndbapi/testRestartGci.cpp'
--- a/storage/ndb/test/ndbapi/testRestartGci.cpp	2010-09-15 09:43:39 +0000
+++ b/storage/ndb/test/ndbapi/testRestartGci.cpp	2010-09-30 15:26:18 +0000
@@ -132,7 +132,14 @@ int runVerifyInserts(NDBT_Context* ctx,
   HugoOperations hugoOps(*ctx->getTab());
   NdbRestarter restarter;
 
-  int restartGCI = pNdb->NdbTamper(Ndb::ReadRestartGCI, 0);    
+  Uint32 restartGCI;
+  int res = pNdb->getDictionary()->getRestartGCI(&restartGCI);
+  if (res != 0)
+  {
+    ndbout << "Failed to retreive restart gci" << endl;
+    ndbout << pNdb->getDictionary()->getNdbError() << endl;
+    return NDBT_FAILED;
+  }
 
   ndbout << "restartGCI = " << restartGCI << endl;
   int count = 0;
@@ -145,7 +152,7 @@ int runVerifyInserts(NDBT_Context* ctx,
   int recordsWithLowerOrSameGci = 0;
   unsigned i; 
   for (i = 0; i < savedRecords.size(); i++){
-    if (savedRecords[i].m_gci <= restartGCI)
+    if (savedRecords[i].m_gci <= (int)restartGCI)
       recordsWithLowerOrSameGci++;
   }
   if (recordsWithLowerOrSameGci != count){
@@ -173,7 +180,7 @@ int runVerifyInserts(NDBT_Context* ctx,
       // Record was not found in db'
 
       // Check record gci
-      if (savedRecords[i].m_gci <= restartGCI){
+      if (savedRecords[i].m_gci <= (int)restartGCI){
 	ndbout << "ERR: Record "<<i<<" should have existed" << endl;
 	result = NDBT_FAILED;
       }
@@ -194,7 +201,7 @@ int runVerifyInserts(NDBT_Context* ctx,
 	result = NDBT_FAILED;
       }
       // Check record gci in range
-      if (savedRecords[i].m_gci > restartGCI){
+      if (savedRecords[i].m_gci > (int)restartGCI){
 	ndbout << "ERR: Record "<<i<<" should not have existed" << endl;
 	result = NDBT_FAILED;
       }


Attachment: [text/bzr-bundle] bzr/msabaratnam@mysql.com-20101001102755-bv0qo6tktp75bfsb.bundle
Thread
bzr commit into mysql-5.1-telco-7.0-mai branch (msabaratnam:3254) Maitrayi Sabaratnam1 Oct