unsigned Ndb_cluster_connection::max_nodegroup() { TransporterFacade *tp = m_impl.m_transporter_facade; if (tp == 0 || tp->ownId() == 0) return 0; Bitmask<MAX_NDB_NODES> ng; tp->lock_mutex(); for(unsigned i= 0; i < no_db_nodes(); i++) { //************************************************ // If any node is answering, ndb is answering //************************************************ trp_node n = tp->theClusterMgr->getNodeInfo(m_impl.m_all_nodes[i].id); if (n.is_confirmed() && n.m_state.nodeGroup <= MAX_NDB_NODES) ng.set(n.m_state.nodeGroup); } tp->unlock_mutex(); if (ng.isclear()) return 0; Uint32 n = ng.find_first(); Uint32 m; do { m = n; } while ((n = ng.find(n+1)) != ng.NotFound); return m; }
int Ndb_cluster_connection::wait_until_ready(int timeout, int timeout_after_first_alive) { DBUG_ENTER("Ndb_cluster_connection::wait_until_ready"); TransporterFacade *tp = TransporterFacade::instance(); if (tp == 0) { DBUG_RETURN(-1); } if (tp->ownId() == 0) { DBUG_RETURN(-1); } int secondsCounter = 0; int milliCounter = 0; int noChecksSinceFirstAliveFound = 0; do { unsigned int foundAliveNode = 0; tp->lock_mutex(); for(unsigned i= 0; i < no_db_nodes(); i++) { //************************************************ // If any node is answering, ndb is answering //************************************************ if (tp->get_node_alive(m_impl.m_all_nodes[i].id) != 0) { foundAliveNode++; } } tp->unlock_mutex(); if (foundAliveNode == no_db_nodes()) { DBUG_RETURN(0); } else if (foundAliveNode > 0) { noChecksSinceFirstAliveFound++; // 100 ms delay -> 10* if (noChecksSinceFirstAliveFound > 10*timeout_after_first_alive) DBUG_RETURN(1); } else if (secondsCounter >= timeout) { // no alive nodes and timed out DBUG_RETURN(-1); } NdbSleep_MilliSleep(100); milliCounter += 100; if (milliCounter >= 1000) { secondsCounter++; milliCounter = 0; }//if } while (1); }
inline int trp_client::raw_sendSignal(const NdbApiSignal * signal, Uint32 nodeId) { assert(m_poll.m_locked); return m_facade->sendSignal(this, signal, nodeId); }
inline int trp_client::raw_sendFragmentedSignal(const NdbApiSignal * signal, Uint32 nodeId, const LinearSectionPtr ptr[3], Uint32 secs) { assert(m_poll.m_locked); return m_facade->sendFragmentedSignal(this, signal, nodeId, ptr, secs); }
inline int trp_client::raw_sendSignal(const NdbApiSignal * signal, Uint32 nodeId, const GenericSectionPtr ptr[3], Uint32 secs) { assert(m_poll.m_locked); return m_facade->sendSignal(signal, nodeId, ptr, secs); }
int Ndb_cluster_connection::wait_until_ready(int timeout, int timeout_after_first_alive) { DBUG_ENTER("Ndb_cluster_connection::wait_until_ready"); TransporterFacade *tp = m_impl.m_transporter_facade; if (tp == 0) { DBUG_RETURN(-1); } if (tp->ownId() == 0) { DBUG_RETURN(-1); } int secondsCounter = 0; int milliCounter = 0; int noChecksSinceFirstAliveFound = 0; do { unsigned int foundAliveNode = get_no_ready(); if (foundAliveNode == no_db_nodes()) { DBUG_RETURN(0); } else if (foundAliveNode > 0) { noChecksSinceFirstAliveFound++; // 100 ms delay -> 10* if (noChecksSinceFirstAliveFound > 10*timeout_after_first_alive) DBUG_RETURN(1); } else if (secondsCounter >= timeout) { // no alive nodes and timed out DBUG_RETURN(-1); } NdbSleep_MilliSleep(100); milliCounter += 100; if (milliCounter >= 1000) { secondsCounter++; milliCounter = 0; }//if } while (1); }
int Ndb_cluster_connection::get_no_ready() { TransporterFacade *tp = m_impl.m_transporter_facade; if (tp == 0 || tp->ownId() == 0) return -1; unsigned int foundAliveNode = 0; tp->lock_mutex(); for(unsigned i= 0; i < no_db_nodes(); i++) { //************************************************ // If any node is answering, ndb is answering //************************************************ if (tp->get_node_alive(m_impl.m_all_nodes[i].id) != 0) { foundAliveNode++; } } tp->unlock_mutex(); return foundAliveNode; }
Uint32 Ndb_cluster_connection_impl::get_next_alive_node(Ndb_cluster_connection_node_iter &iter) { Uint32 id; TransporterFacade *tp = m_impl.m_transporter_facade; if (tp == 0 || tp->ownId() == 0) return 0; while ((id = get_next_node(iter))) { tp->lock_mutex(); if (tp->get_node_alive(id) != 0) { tp->unlock_mutex(); return id; } tp->unlock_mutex(); } return 0; }
inline void trp_client::wakeup() { m_facade->wakeup(this); }
/** * The execute function : Handle received signal */ void execute(void * callbackObj, SignalHeader * const header, Uint8 prio, Uint32 * const theData, LinearSectionPtr ptr[3]){ TransporterFacade * theFacade = (TransporterFacade*)callbackObj; TransporterFacade::ThreadData::Object_Execute oe; Uint32 tRecBlockNo = header->theReceiversBlockNumber; #ifdef API_TRACE if(setSignalLog() && TRACE_GSN(header->theVerId_signalNumber)){ signalLogger.executeSignal(* header, prio, theData, theFacade->ownId(), ptr, header->m_noOfSections); signalLogger.flushSignalLog(); } #endif if (tRecBlockNo >= MIN_API_BLOCK_NO) { oe = theFacade->m_threads.get(tRecBlockNo); if (oe.m_object != 0 && oe.m_executeFunction != 0) { /** * Handle received signal immediately to avoid any unnecessary * copying of data, allocation of memory and other things. Copying * of data could be interesting to support several priority levels * and to support a special memory structure when executing the * signals. Neither of those are interesting when receiving data * in the NDBAPI. The NDBAPI will thus read signal data directly as * it was written by the sender (SCI sender is other node, Shared * memory sender is other process and TCP/IP sender is the OS that * writes the TCP/IP message into a message buffer). */ NdbApiSignal tmpSignal(*header); NdbApiSignal * tSignal = &tmpSignal; tSignal->setDataPtr(theData); (* oe.m_executeFunction) (oe.m_object, tSignal, ptr); }//if } 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 * package the signals so as to avoid unnecessary communication * overhead since TCP/IP has a great performance impact. */ Uint32 Tlength = header->theLength; Uint32 Tsent = 0; /** * Since it contains at least two data packets we will first * copy the signal data to safe place. */ while (Tsent < Tlength) { Uint32 Theader = theData[Tsent]; 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 = theFacade->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); } } } } } return; } else if (tRecBlockNo == API_CLUSTERMGR) {
/****************************************************************************** * int init( int aNrOfCon, int aNrOfOp ); * * Return Value: Return 0 : init was successful. * Return -1: In all other case. * Parameters: aNrOfCon : Number of connections offered to the application. * aNrOfOp : Number of operations offered to the application. * Remark: Create pointers and idle list Synchronous. ****************************************************************************/ int Ndb::init(int aMaxNoOfTransactions) { DBUG_ENTER("Ndb::init"); int i; int aNrOfCon; int aNrOfOp; int tMaxNoOfTransactions; NdbApiSignal* tSignal[16]; // Initiate free list of 16 signal objects if (theInitState != NotInitialised) { switch(theInitState){ case InitConfigError: theError.code = 4117; break; default: theError.code = 4104; break; } DBUG_RETURN(-1); }//if theInitState = StartingInit; TransporterFacade * theFacade = theImpl->m_transporter_facade; theEventBuffer->m_mutex = theFacade->theMutexPtr; const Uint32 tRef = theImpl->open(theFacade); if (tRef == 0) { theError.code = 4105; DBUG_RETURN(-1); // no more free blocknumbers }//if Uint32 nodeId = refToNode(tRef); theNdbBlockNumber = refToBlock(tRef); if (nodeId > 0) { connected(Uint32(tRef)); } /* Init cached min node version */ theFacade->lock_mutex(); theCachedMinDbNodeVersion = theFacade->getMinDbNodeVersion(); theFacade->unlock_mutex(); theDictionary->setTransporter(this, theFacade); aNrOfCon = theImpl->theNoOfDBnodes; aNrOfOp = 2*theImpl->theNoOfDBnodes; // Create connection object in a linked list if((createConIdleList(aNrOfCon)) == -1){ theError.code = 4000; goto error_handler; } // Create operations in a linked list if((createOpIdleList(aNrOfOp)) == -1){ theError.code = 4000; goto error_handler; } tMaxNoOfTransactions = aMaxNoOfTransactions; theMaxNoOfTransactions = tMaxNoOfTransactions; theRemainingStartTransactions= tMaxNoOfTransactions; thePreparedTransactionsArray = new NdbTransaction* [tMaxNoOfTransactions]; theSentTransactionsArray = new NdbTransaction* [tMaxNoOfTransactions]; theCompletedTransactionsArray = new NdbTransaction* [tMaxNoOfTransactions]; if ((thePreparedTransactionsArray == NULL) || (theSentTransactionsArray == NULL) || (theCompletedTransactionsArray == NULL)) { goto error_handler; }//if for (i = 0; i < tMaxNoOfTransactions; i++) { thePreparedTransactionsArray[i] = NULL; theSentTransactionsArray[i] = NULL; theCompletedTransactionsArray[i] = NULL; }//for for (i = 0; i < 16; i++){ tSignal[i] = getSignal(); if(tSignal[i] == NULL) { theError.code = 4000; goto error_handler; } } for (i = 0; i < 16; i++) releaseSignal(tSignal[i]); theInitState = Initialised; DBUG_RETURN(0); error_handler: ndbout << "error_handler" << endl; releaseTransactionArrays(); delete theDictionary; theImpl->close(); DBUG_RETURN(-1); }