/**************************************************************************** int releaseConnectToNdb(NdbTransaction* aConnectConnection); Return Value: -1 if error Parameters: aConnectConnection : Seized schema connection to DBTC Remark: Release and disconnect from DBTC a connection and seize it to theConIdleList. *****************************************************************************/ void Ndb::releaseConnectToNdb(NdbTransaction* a_con) { DBUG_ENTER("Ndb::releaseConnectToNdb"); NdbApiSignal tSignal(theMyRef); int tConPtr; // I need to close the connection irrespective of whether I // manage to reach NDB or not. if (a_con == NULL) DBUG_VOID_RETURN; Uint32 node_id = a_con->getConnectedNodeId(); Uint32 conn_seq = a_con->theNodeSequence; tSignal.setSignal(GSN_TCRELEASEREQ); tSignal.setData((tConPtr = a_con->getTC_ConnectPtr()), 1); tSignal.setData(theMyRef, 2); tSignal.setData(a_con->ptr2int(), 3); a_con->Status(NdbTransaction::DisConnecting); a_con->theMagicNumber = 0x37412619; int ret_code = sendRecSignal(node_id, WAIT_TC_RELEASE, &tSignal, conn_seq); if (ret_code == 0) { ; } else if (ret_code == -1) { TRACE_DEBUG("Time-out when TCRELEASE sent"); } else if (ret_code == -2) { TRACE_DEBUG("Node failed when TCRELEASE sent"); } else if (ret_code == -3) { TRACE_DEBUG("Send failed when TCRELEASE sent"); } else if (ret_code == -4) { TRACE_DEBUG("Send buffer full when TCRELEASE sent"); } else if (ret_code == -5) { TRACE_DEBUG("Node stopping when TCRELEASE sent"); } else { ndbout << "Impossible return from sendRecSignal when TCRELEASE" << endl; abort(); }//if releaseNdbCon(a_con); DBUG_VOID_RETURN; }
/** * We're holding the trp_client lock while performing poll from * ClusterMgr. So we always execute all the execSIGNAL-methods in * ClusterMgr with protection other methods that use the trp_client * lock (reportDisconnect, reportConnect, is_cluster_completely_unavailable, * ArbitMgr (sendSignalToQmgr)). */ void ClusterMgr::trp_deliver_signal(const NdbApiSignal* sig, const LinearSectionPtr ptr[3]) { const Uint32 gsn = sig->theVerId_signalNumber; const Uint32 * theData = sig->getDataPtr(); switch (gsn) { case GSN_API_REGREQ: execAPI_REGREQ(theData); break; case GSN_API_REGCONF: execAPI_REGCONF(sig, ptr); break; case GSN_API_REGREF: execAPI_REGREF(theData); break; case GSN_NODE_FAILREP: execNODE_FAILREP(sig, ptr); break; case GSN_NF_COMPLETEREP: execNF_COMPLETEREP(sig, ptr); 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 (theFacade.m_globalDictCache == NULL) break; const AlterTableRep* rep = (const AlterTableRep*)theData; theFacade.m_globalDictCache->lock(); theFacade.m_globalDictCache-> alter_table_rep((const char*)ptr[0].p, rep->tableId, rep->tableVersion, rep->changeType == AlterTableRep::CT_ALTERED); theFacade.m_globalDictCache->unlock(); break; } case GSN_SUB_GCP_COMPLETE_REP: { /** * Report */ theFacade.for_each(this, sig, ptr); /** * Reply */ { BlockReference ownRef = numberToRef(API_CLUSTERMGR, theFacade.ownId()); NdbApiSignal tSignal(* sig); Uint32* send= tSignal.getDataPtrSend(); memcpy(send, theData, tSignal.getLength() << 2); CAST_PTR(SubGcpCompleteAck, send)->rep.senderRef = ownRef; Uint32 ref= sig->theSendersBlockRef; Uint32 aNodeId= refToNode(ref); tSignal.theReceiversBlockNumber= refToBlock(ref); tSignal.theVerId_signalNumber= GSN_SUB_GCP_COMPLETE_ACK; tSignal.theSendersBlockRef = API_CLUSTERMGR; safe_noflush_sendSignal(&tSignal, aNodeId); } break; } case GSN_TAKE_OVERTCCONF: { /** * Report */ theFacade.for_each(this, sig, ptr); return; } case GSN_CONNECT_REP: { execCONNECT_REP(sig, ptr); return; } case GSN_DISCONNECT_REP: { execDISCONNECT_REP(sig, ptr); return; } case GSN_CLOSE_COMREQ: { theFacade.perform_close_clnt(this); return; } case GSN_EXPAND_CLNT: { theFacade.expand_clnt(); return; } default: break; } return; }