List:Internals« Previous MessageNext Message »
From:mikael Date:March 22 2005 3:24pm
Subject:bk commit into 5.0 tree (mronstrom:1.1841)
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of mikron. When mikron 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://www.mysql.com/doc/I/n/Installing_source_tree.html

ChangeSet
  1.1841 05/03/22 15:24:44 mronstrom@stripped +10 -0
  WL2405 Optimisations for single threaded usage of NDB API
  Lots of fixes, preparation for pulling latest 5.0 into clone

  ndb/src/ndbapi/TransporterFacade.hpp
    1.26 05/03/22 15:24:35 mronstrom@stripped +4 -3
    forceSend moved to PollGuard class

  ndb/src/ndbapi/TransporterFacade.cpp
    1.37 05/03/22 15:24:35 mronstrom@stripped +29 -7
    Lots of debug printouts
    Moved forceSend into the PollGuard class
    Fixed getting the cond_wait_index from object not from stack.

  ndb/src/ndbapi/Ndbif.cpp
    1.31 05/03/22 15:24:35 mronstrom@stripped +36 -13
    Cannot let the dictSignal's break since they use their own
    NdbWaiter object.
    Added comments about implicit calls
    Added return parameter to sendRecSignal
    SendRecSignal uses PollGuard

  ndb/src/ndbapi/NdbWaiter.hpp
    1.3 05/03/22 15:24:35 mronstrom@stripped +5 -15
    Most of the functionality in wait have moved to the PollGuard class

  ndb/src/ndbapi/NdbScanOperation.cpp
    1.65 05/03/22 15:24:35 mronstrom@stripped +46 -24
    Added comments about implicit call of ~PollGuard
    Moved forceSend to PollGuard class

  ndb/src/ndbapi/NdbDictionaryImpl.cpp
    1.67 05/03/22 15:24:34 mronstrom@stripped +14 -4
    Added comments about implicit call of ~PollGuard

  ndb/src/ndbapi/Ndb.cpp
    1.45 05/03/22 15:24:34 mronstrom@stripped +3 -17
    Moved TC_SEIZEREQ to use sendRecSignal

  ndb/include/ndbapi/NdbScanOperation.hpp
    1.31 05/03/22 15:24:34 mronstrom@stripped +1 -2
    Moved forceSend to PollGuard class

  ndb/include/ndbapi/NdbIndexScanOperation.hpp
    1.17 05/03/22 15:24:34 mronstrom@stripped +1 -1
    Moved forceSend to PollGuard class

  ndb/include/ndbapi/Ndb.hpp
    1.42 05/03/22 15:24:33 mronstrom@stripped +2 -1
    Needed a return of the node sequence for TC_SEIZEREQ

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	mronstrom
# Host:	mikael-ronstr-ms-dator.local
# Root:	/Users/mikron/wl2405

--- 1.16/ndb/include/ndbapi/NdbIndexScanOperation.hpp	Mon Jan 10 01:25:08 2005
+++ 1.17/ndb/include/ndbapi/NdbIndexScanOperation.hpp	Tue Mar 22 15:24:34 2005
@@ -143,7 +143,7 @@
 
   void fix_get_values();
   int next_result_ordered(bool fetchAllowed, bool forceSend = false);
-  int send_next_scan_ordered(Uint32 idx, bool forceSend = false);
+  int send_next_scan_ordered(Uint32 idx);
   int compare(Uint32 key, Uint32 cols, const NdbReceiver*, const NdbReceiver*);
 
   Uint32 m_sort_columns;

--- 1.41/ndb/include/ndbapi/Ndb.hpp	Tue Mar 22 02:14:04 2005
+++ 1.42/ndb/include/ndbapi/Ndb.hpp	Tue Mar 22 15:24:33 2005
@@ -1530,7 +1530,8 @@
   int			sendRecSignal(Uint16 aNodeId,
 				      Uint32 aWaitState,
 				      NdbApiSignal* aSignal,
-                                      Uint32 nodeSequence);
+                                      Uint32 nodeSequence,
+                                      Uint32 *ret_conn_seq= 0);
   
   // Sets Restart GCI in Ndb object
   void			RestartGCI(int aRestartGCI);

--- 1.30/ndb/include/ndbapi/NdbScanOperation.hpp	Tue Mar 22 02:14:04 2005
+++ 1.31/ndb/include/ndbapi/NdbScanOperation.hpp	Tue Mar 22 15:24:34 2005
@@ -170,7 +170,6 @@
   int init(const NdbTableImpl* tab, NdbTransaction*);
   int prepareSend(Uint32  TC_ConnectPtr, Uint64  TransactionId);
   int doSend(int ProcessorId);
-  void checkForceSend(bool forceSend);
 
   virtual void setErrorCode(int aErrorCode);
   virtual void setErrorCodeAbort(int aErrorCode);
@@ -212,7 +211,7 @@
   Uint32 m_sent_receivers_count;  // NOTE needs mutex to access
   NdbReceiver** m_sent_receivers; // receive thread puts them here
   
-  int send_next_scan(Uint32 cnt, bool close, bool forceSend = false);
+  int send_next_scan(Uint32 cnt, bool close);
   void receiver_delivered(NdbReceiver*);
   void receiver_completed(NdbReceiver*);
   void execCLOSE_SCAN_REP();

--- 1.44/ndb/src/ndbapi/Ndb.cpp	Wed Jan 19 14:56:36 2005
+++ 1.45/ndb/src/ndbapi/Ndb.cpp	Tue Mar 22 15:24:34 2005
@@ -165,23 +165,9 @@
   tSignal->setData(theMyRef, 2);	// Set my block reference
   tNdbCon->Status(NdbTransaction::Connecting); // Set status to connecting
   Uint32 nodeSequence;
-  { // send and receive signal
-    Guard guard(tp->theMutexPtr);
-    nodeSequence = tp->getNodeSequence(tNode);
-    bool node_is_alive = tp->get_node_alive(tNode);
-    if (node_is_alive) { 
-      tReturnCode = tp->sendSignal(tSignal, tNode);  
-      releaseSignal(tSignal); 
-      if (tReturnCode != -1) {
-        theImpl->theWaiter.m_node = tNode;  
-        theImpl->theWaiter.m_state = WAIT_TC_SEIZE;  
-        tReturnCode = receiveResponse(); 
-      }//if
-    } else {
-      releaseSignal(tSignal);
-      tReturnCode = -1;
-    }//if
-  }
+  tReturnCode= sendRecSignal(tNode, WAIT_TC_SEIZE, tSignal,
+                             0, nodeSequence);
+  releaseSignal(tSignal); 
   if ((tReturnCode == 0) && (tNdbCon->Status() == NdbTransaction::Connected))
{
     //************************************************
     // Send and receive was successful

--- 1.66/ndb/src/ndbapi/NdbDictionaryImpl.cpp	Tue Mar 22 02:14:04 2005
+++ 1.67/ndb/src/ndbapi/NdbDictionaryImpl.cpp	Tue Mar 22 15:24:34 2005
@@ -946,8 +946,13 @@
     m_buffer.clear();
 
     // Protected area
-    Uint32 block_no; //TODO fix this
-    PollGuard poll_guard(m_transporter, &m_waiter, block_no);
+    /*
+      The PollGuard has an implicit call of unlock_and_signal through the
+      ~PollGuard method. This method is called implicitly by the compiler
+      in all places where the object is out of context due to a return,
+      break, continue or simply end of statement block
+    */
+    PollGuard poll_guard(m_transporter, &m_waiter, refToBlock(m_reference));
     Uint32 aNodeId;
     if (useMasterNodeId) {
       if ((m_masterNodeId == 0) ||
@@ -3058,8 +3063,13 @@
   for (Uint32 i = 0; i < RETRIES; i++) {
     m_buffer.clear();
     // begin protected
-    Uint32 block_no; //TODO fix this
-    PollGuard poll_guard(m_transporter, &m_waiter, block_no);
+    /*
+      The PollGuard has an implicit call of unlock_and_signal through the
+      ~PollGuard method. This method is called implicitly by the compiler
+      in all places where the object is out of context due to a return,
+      break, continue or simply end of statement block
+    */
+    PollGuard poll_guard(m_transporter, &m_waiter, refToBlock(m_reference));
     Uint16 aNodeId = m_transporter->get_an_alive_node();
     if (aNodeId == 0) {
       m_error.code= 4009;

--- 1.64/ndb/src/ndbapi/NdbScanOperation.cpp	Tue Mar 22 02:14:04 2005
+++ 1.65/ndb/src/ndbapi/NdbScanOperation.cpp	Tue Mar 22 15:24:35 2005
@@ -452,14 +452,20 @@
   
   Uint32 nodeId = theNdbCon->theDBnode;
   TransporterFacade* tp = TransporterFacade::instance();
+  /*
+    The PollGuard has an implicit call of unlock_and_signal through the
+    ~PollGuard method. This method is called implicitly by the compiler
+    in all places where the object is out of context due to a return,
+    break, continue or simply end of statement block
+  */
   PollGuard poll_guard(tp, &theNdb->theImpl->theWaiter,
                        theNdb->theNdbBlockNumber);
   if(theError.code)
     return -1;
 
   Uint32 seq = theNdbCon->theNodeSequence;
-  if(seq == tp->getNodeSequence(nodeId) && send_next_scan(idx, false,
-							  forceSend) == 0){
+  if(seq == tp->getNodeSequence(nodeId) && send_next_scan(idx, false) == 0)
+  {
       
     idx = m_current_api_receiver;
     last = m_api_receivers_count;
@@ -488,7 +494,8 @@
 	/**
 	 * No completed...
 	 */
-        int ret_code= poll_guard.wait_scan(WAITFOR_SCAN_TIMEOUT, nodeId);
+        int ret_code= poll_guard.wait_scan(WAITFOR_SCAN_TIMEOUT, nodeId,
+                                           forceSend);
 	if (ret_code == 0 && seq == tp->getNodeSequence(nodeId)) {
 	  continue;
 	} else {
@@ -548,8 +555,8 @@
 }
 
 int
-NdbScanOperation::send_next_scan(Uint32 cnt, bool stopScanFlag,
-				 bool forceSend){  
+NdbScanOperation::send_next_scan(Uint32 cnt, bool stopScanFlag)
+{
   if(cnt > 0){
     NdbApiSignal tSignal(theNdb->theMyRef);
     tSignal.setSignal(GSN_SCAN_NEXTREQ);
@@ -596,9 +603,6 @@
 	ret = tp->sendSignal(&tSignal, nodeId);
       }
     }
-    
-    if (!ret) checkForceSend(forceSend);
-
     m_sent_receivers_count = last + sent;
     m_api_receivers_count -= cnt;
     m_current_api_receiver = 0;
@@ -608,15 +612,6 @@
   return 0;
 }
 
-void NdbScanOperation::checkForceSend(bool forceSend)
-{
-  if (forceSend) {
-    TransporterFacade::instance()->forceSend(theNdb->theNdbBlockNumber);
-  } else {
-    TransporterFacade::instance()->checkForceSend(theNdb->theNdbBlockNumber);
-  }//if
-}
-
 int 
 NdbScanOperation::prepareSend(Uint32  TC_ConnectPtr, Uint64  TransactionId)
 {
@@ -646,6 +641,12 @@
 	       m_sent_receivers_count);
     
     TransporterFacade* tp = TransporterFacade::instance();
+    /*
+      The PollGuard has an implicit call of unlock_and_signal through the
+      ~PollGuard method. This method is called implicitly by the compiler
+      in all places where the object is out of context due to a return,
+      break, continue or simply end of statement block
+    */
     PollGuard poll_guard(tp, &theNdb->theImpl->theWaiter,
                          theNdb->theNdbBlockNumber);
     close_impl(tp, forceSend, &poll_guard);
@@ -1312,6 +1313,12 @@
     if(fetchAllowed){
       if(DEBUG_NEXT_RESULT) ndbout_c("performing fetch...");
       TransporterFacade* tp = TransporterFacade::instance();
+      /*
+        The PollGuard has an implicit call of unlock_and_signal through the
+        ~PollGuard method. This method is called implicitly by the compiler
+        in all places where the object is out of context due to a return,
+        break, continue or simply end of statement block
+      */
       PollGuard poll_guard(tp, &theNdb->theImpl->theWaiter,
                            theNdb->theNdbBlockNumber);
       if(theError.code)
@@ -1319,11 +1326,12 @@
       Uint32 seq = theNdbCon->theNodeSequence;
       Uint32 nodeId = theNdbCon->theDBnode;
       if(seq == tp->getNodeSequence(nodeId) &&
-	 !send_next_scan_ordered(s_idx, forceSend)){
+	 !send_next_scan_ordered(s_idx)){
 	Uint32 tmp = m_sent_receivers_count;
 	s_idx = m_current_api_receiver; 
 	while(m_sent_receivers_count > 0 && !theError.code){
-          int ret_code= poll_guard.wait_scan(WAITFOR_SCAN_TIMEOUT, nodeId);
+          int ret_code= poll_guard.wait_scan(WAITFOR_SCAN_TIMEOUT, nodeId,
+                                             forceSend);
 	  if (ret_code == 0 && seq == tp->getNodeSequence(nodeId)) {
 	    continue;
 	  }
@@ -1411,7 +1419,8 @@
 }
 
 int
-NdbIndexScanOperation::send_next_scan_ordered(Uint32 idx, bool forceSend){  
+NdbIndexScanOperation::send_next_scan_ordered(Uint32 idx)
+{
   if(idx == theParallelism)
     return 0;
   
@@ -1449,7 +1458,6 @@
   TransporterFacade * tp = TransporterFacade::instance();
   tSignal.setLength(4+1);
   int ret= tp->sendSignal(&tSignal, nodeId);
-  if (!ret) checkForceSend(forceSend);
   return ret;
 }
 
@@ -1471,7 +1479,8 @@
    */
   while(theError.code == 0 && m_sent_receivers_count)
   {
-    int return_code= poll_guard->wait_scan(WAITFOR_SCAN_TIMEOUT, nodeId);
+    int return_code= poll_guard->wait_scan(WAITFOR_SCAN_TIMEOUT, nodeId,
+                                           false);
     switch(return_code){
     case 0:
       break;
@@ -1528,7 +1537,7 @@
   }
   
   // Send close scan
-  if(send_next_scan(api+conf, true, forceSend) == -1)
+  if(send_next_scan(api+conf, true) == -1)
   {
     theNdbCon->theReleaseOnClose = true;
     return -1;
@@ -1539,7 +1548,8 @@
    */
   while(m_sent_receivers_count+m_api_receivers_count+m_conf_receivers_count)
   {
-    int return_code= poll_guard->wait_scan(WAITFOR_SCAN_TIMEOUT, nodeId);
+    int return_code= poll_guard->wait_scan(WAITFOR_SCAN_TIMEOUT, nodeId,
+                                           forceSend);
     switch(return_code){
     case 0:
       break;
@@ -1579,6 +1589,12 @@
 {
   
   TransporterFacade* tp = TransporterFacade::instance();
+  /*
+    The PollGuard has an implicit call of unlock_and_signal through the
+    ~PollGuard method. This method is called implicitly by the compiler
+    in all places where the object is out of context due to a return,
+    break, continue or simply end of statement block
+  */
   PollGuard poll_guard(tp, &theNdb->theImpl->theWaiter,
                        theNdb->theNdbBlockNumber);
   Uint32 nodeId = theNdbCon->theDBnode;
@@ -1608,6 +1624,12 @@
   
   {
     TransporterFacade* tp = TransporterFacade::instance();
+    /*
+      The PollGuard has an implicit call of unlock_and_signal through the
+      ~PollGuard method. This method is called implicitly by the compiler
+      in all places where the object is out of context due to a return,
+      break, continue or simply end of statement block
+    */
     PollGuard poll_guard(tp, &theNdb->theImpl->theWaiter,
                          theNdb->theNdbBlockNumber);
     res= close_impl(tp, forceSend, &poll_guard);

--- 1.30/ndb/src/ndbapi/Ndbif.cpp	Tue Mar 22 02:14:04 2005
+++ 1.31/ndb/src/ndbapi/Ndbif.cpp	Tue Mar 22 15:24:35 2005
@@ -680,12 +680,12 @@
   case GSN_LIST_TABLES_CONF:
     NdbDictInterface::execSignal(&theDictionary->m_receiver,
 				 aSignal, ptr);
-    break;
+    return;
     
   case GSN_SUB_META_DATA:
   case GSN_SUB_REMOVE_CONF:
   case GSN_SUB_REMOVE_REF:
-    break; // ignore these signals
+    return; // ignore these signals
   case GSN_SUB_GCP_COMPLETE_REP:
   case GSN_SUB_START_CONF:
   case GSN_SUB_START_REF:
@@ -694,7 +694,7 @@
   case GSN_SUB_STOP_REF:
     NdbDictInterface::execSignal(&theDictionary->m_receiver,
 				 aSignal, ptr);
-    break;
+    return;
 
   case GSN_DIHNDBTAMPER:
     {
@@ -859,6 +859,7 @@
          Wake up the thread waiting for response and remove it from queue
          of objects waiting for receive completion
       */
+      ndbout << "Remove t_waiter " << hex << t_waiter << " from
queue" << endl;
       tp->remove_from_cond_wait_queue(t_waiter);
       t_waiter->cond_signal();
     }
@@ -926,6 +927,7 @@
           we must remove it from the conditional wait queue so that we
           don't assign it as poll owner later on.
         */
+        ndbout << "Remove t_waiter " << hex << t_waiter << " from
queue" << endl;
         tp->remove_from_cond_wait_queue(t_waiter);
         t_waiter->cond_signal();
       }
@@ -1242,6 +1244,12 @@
 int	
 Ndb::sendPollNdb(int aMillisecondNumber, int minNoOfEventsToWakeup, int forceSend)
 {
+  /*
+    The PollGuard has an implicit call of unlock_and_signal through the
+    ~PollGuard method. This method is called implicitly by the compiler
+    in all places where the object is out of context due to a return,
+    break, continue or simply end of statement block
+  */
   PollGuard pg(TransporterFacade::instance(), &theImpl->theWaiter,
                theNdbBlockNumber);
   sendPrepTrans(forceSend);
@@ -1280,6 +1288,12 @@
 int	
 Ndb::pollNdb(int aMillisecondNumber, int minNoOfEventsToWakeup)
 {
+  /*
+    The PollGuard has an implicit call of unlock_and_signal through the
+    ~PollGuard method. This method is called implicitly by the compiler
+    in all places where the object is out of context due to a return,
+    break, continue or simply end of statement block
+  */
   PollGuard pg(TransporterFacade::instance(), &theImpl->theWaiter,
                theNdbBlockNumber);
   return poll_trans(aMillisecondNumber, minNoOfEventsToWakeup, &pg);
@@ -1323,7 +1337,8 @@
 Ndb::sendRecSignal(Uint16 node_id,
 		   Uint32 aWaitState,
 		   NdbApiSignal* aSignal,
-                   Uint32 conn_seq)
+                   Uint32 conn_seq,
+                   Uint32 *ret_conn_seq)
 {
   /*
   In most situations 0 is returned.
@@ -1336,19 +1351,28 @@
   */
 
   int return_code;
+  Uint32 read_conn_seq;
   TransporterFacade* tp = TransporterFacade::instance();
-  Uint32 send_size = 1; // Always sends one signal only 
-  tp->lock_mutex();
+  Uint32 send_size = 1; // Always sends one signal only
   // Protected area
+  /*
+    The PollGuard has an implicit call of unlock_and_signal through the
+    ~PollGuard method. This method is called implicitly by the compiler
+    in all places where the object is out of context due to a return,
+    break, continue or simply end of statement block
+  */
+  PollGuard poll_guard(tp,&theImpl->theWaiter,theNdbBlockNumber);
+  read_conn_seq= tp->getNodeSequence(node_id);
+  if (ret_conn_seq)
+    *ret_conn_seq= read_conn_seq;
   if ((tp->get_node_alive(node_id)) &&
-      ((tp->getNodeSequence(node_id) == conn_seq) ||
+      ((read_conn_seq == conn_seq) ||
        (conn_seq == 0))) {
     if (tp->check_send_size(node_id, send_size)) {
       return_code = tp->sendSignal(aSignal, node_id);
       if (return_code != -1) {
-        theImpl->theWaiter.m_node = node_id;
-        theImpl->theWaiter.m_state = aWaitState;
-        return_code = receiveResponse();
+        return poll_guard.wait_n_unlock(WAITFOR_RESPONSE_TIMEOUT,node_id,
+                                         aWaitState, false);
       } else {
 	return_code = -3;
       }
@@ -1357,16 +1381,15 @@
     }//if
   } else {
     if ((tp->get_node_stopping(node_id)) &&
-        ((tp->getNodeSequence(node_id) == conn_seq) ||
+        ((read_conn_seq == conn_seq) ||
          (conn_seq == 0))) {
       return_code = -5;
     } else {
       return_code = -2;
     }//if
   }//if
-  tp->unlock_mutex();
-  // End of protected area
   return return_code;
+  // End of protected area
 }//Ndb::sendRecSignal()
 
 void

--- 1.36/ndb/src/ndbapi/TransporterFacade.cpp	Tue Mar 22 02:14:05 2005
+++ 1.37/ndb/src/ndbapi/TransporterFacade.cpp	Tue Mar 22 15:24:35 2005
@@ -1262,27 +1262,36 @@
 
   It replaces the method receiveResponse previously used on the Ndb object
 */
-int PollGuard::wait_n_unlock(int wait_time, NodeId nodeId, Uint32 state)
+int PollGuard::wait_n_unlock(int wait_time, NodeId nodeId, Uint32 state,
+                             bool forceSend)
 {
   int ret_val;
+  ndbout << "wait_n_unlock on " << hex << m_waiter;
+  ndbout << " node = " << nodeId << " state " << state <<
endl;
   m_waiter->set_node(nodeId);
   m_waiter->set_state(state);
-  ret_val= wait_for_input_in_loop(wait_time);
+  ret_val= wait_for_input_in_loop(wait_time, forceSend);
   unlock_and_signal();
   return ret_val;
 }
 
-int PollGuard::wait_scan(int wait_time, NodeId nodeId)
+int PollGuard::wait_scan(int wait_time, NodeId nodeId, bool forceSend)
 {
   m_waiter->set_node(nodeId);
   m_waiter->set_state(WAIT_SCAN);
-  return wait_for_input_in_loop(wait_time);
+  ndbout << "wait_scan " << hex << m_waiter;
+  ndbout << " node = " << nodeId << " state ";
+  ndbout << m_waiter->get_state() << endl;
+  return wait_for_input_in_loop(wait_time, forceSend);
 }
 
-int PollGuard::wait_for_input_in_loop(int wait_time)
+int PollGuard::wait_for_input_in_loop(int wait_time, bool forceSend)
 {
   int ret_val;
-  m_tp->checkForceSend(m_block_no);
+  if (forceSend)
+    m_tp->forceSend(m_block_no);
+  else
+    m_tp->checkForceSend(m_block_no);
   NDB_TICKS curr_time = NdbTick_CurrentMillisecond();
   NDB_TICKS max_time = curr_time + (NDB_TICKS)wait_time;
   do
@@ -1290,19 +1299,25 @@
     wait_for_input(wait_time);
     Uint32 state= m_waiter->get_state();
     if (state == NO_WAIT)
+    {
+      ndbout << "NO_WAIT 1" << endl;
       return 0;
+    }
     else if (state == WAIT_NODE_FAILURE)
     {
+      ndbout << "WAIT_NODE_FAILURE 1" << endl;
       ret_val= -2;
       break;
     }
     wait_time= max_time - NdbTick_CurrentMillisecond();
     if (wait_time <= 0)
     {
+      ndbout << "WST_WAIT_TIMEOUT 1" << endl;
       m_waiter->set_state(WST_WAIT_TIMEOUT);
       ret_val= -1;
       break;
     }
+    ndbout << "m_waiter " << hex << m_waiter << "woken up without
being ready and without timeout" << endl;
   } while (1);
 #ifdef VM_TRACE
   ndbout << "ERR: receiveResponse - theImpl->theWaiter.m_state = ";
@@ -1322,14 +1337,19 @@
       conditional mutex until the thread owning the poll "right"
       will wake us up after all data is received. If no data arrives
       we will wake up eventually due to the timeout.
+      After receiving all data we take the object out of the cond wait
+      queue if it hasn't happened already. It is usually already out of the
+      queue but at time-out it could be that the object is still there.
     */
+    ndbout << "Not poll owner" << endl;
     Uint32 cond_wait_index= m_tp->put_in_cond_wait_queue(m_waiter);
     m_waiter->wait(wait_time);
-    if (cond_wait_index != TransporterFacade::MAX_NO_THREADS)
+    if (m_waiter->get_cond_wait_index() != TransporterFacade::MAX_NO_THREADS)
       m_tp->remove_from_cond_wait_queue(m_waiter);
   }
   else
   {
+    ndbout << "Poll owner" << endl;
     /*
       We got the poll "right" and we poll until data is received. After
       receiving data we will check if all data is received, if not we
@@ -1360,12 +1380,14 @@
   */
   if (m_tp->get_poll_owner() == m_waiter)
   {
+    ndbout << "Completed as poll owner" << endl;
     m_waiter->set_poll_owner(false);
     t_signal_cond_waiter= m_tp->rem_last_from_cond_wait_queue();
     m_tp->set_poll_owner(t_signal_cond_waiter);
     if (t_signal_cond_waiter)
       t_signal_cond_waiter->set_poll_owner(true);
   }
+  ndbout << "Completed" << endl;
   m_tp->unlock_mutex();
   if (t_signal_cond_waiter)
     t_signal_cond_waiter->cond_signal();

--- 1.25/ndb/src/ndbapi/TransporterFacade.hpp	Tue Mar 22 02:14:05 2005
+++ 1.26/ndb/src/ndbapi/TransporterFacade.hpp	Tue Mar 22 15:24:35 2005
@@ -283,10 +283,11 @@
   public:
   PollGuard(TransporterFacade *tp, NdbWaiter *aWaiter, Uint32 block_no);
   ~PollGuard() { unlock_and_signal(); }
-  int wait_n_unlock(int wait_time, NodeId nodeId, Uint32 state);
-  int wait_for_input_in_loop(int wait_time);
+  int wait_n_unlock(int wait_time, NodeId nodeId, Uint32 state,
+                    bool forceSend= false);
+  int wait_for_input_in_loop(int wait_time, bool forceSend);
   void wait_for_input(int wait_time);
-  int wait_scan(int wait_time, NodeId nodeId);
+  int wait_scan(int wait_time, NodeId nodeId, bool forceSend);
   void unlock_and_signal();
   private:
   TransporterFacade *m_tp;

--- 1.2/ndb/src/ndbapi/NdbWaiter.hpp	Tue Mar 22 02:14:04 2005
+++ 1.3/ndb/src/ndbapi/NdbWaiter.hpp	Tue Mar 22 15:24:35 2005
@@ -75,21 +75,11 @@
 NdbWaiter::wait(int waitTime)
 {
   const bool forever = (waitTime == -1);
-  const NDB_TICKS maxTime = NdbTick_CurrentMillisecond() + waitTime;
-  while (1) {
-    if (m_state == NO_WAIT || m_state == WAIT_NODE_FAILURE)
-      break;
-    if (forever) {
-      NdbCondition_Wait(m_condition, (NdbMutex*)m_mutex);
-    } else {
-      if (waitTime <= 0) {
-        m_state = WST_WAIT_TIMEOUT;
-        break;
-      }
-      NdbCondition_WaitTimeout(m_condition, (NdbMutex*)m_mutex, waitTime);
-      waitTime = maxTime - NdbTick_CurrentMillisecond();
-    }
-  }
+  assert(!m_poll_owner);
+  if (!forever)
+    NdbCondition_WaitTimeout(m_condition, (NdbMutex*)m_mutex, waitTime);
+  else
+    NdbCondition_Wait(m_condition, (NdbMutex*)m_mutex);
 }
 
 inline
Thread
bk commit into 5.0 tree (mronstrom:1.1841)mikael22 Mar