// Functionality: // Remove the UDT instance from the list. // Parameters: // 1) [in] u: pointer to the UDT instance // Returned value: // None. public void remove(CUDT u) { CRNode n = u.m_pRNode; if (!n.m_bOnList) return; if (null == n.m_pPrev) { // n is the first node m_pUList = n.m_pNext; if (null == m_pUList) m_pLast = null; else m_pUList.m_pPrev = null; } else { n.m_pPrev.m_pNext = n.m_pNext; if (null == n.m_pNext) { // n is the last node m_pLast = n.m_pPrev; } else n.m_pNext.m_pPrev = n.m_pPrev; } n.m_pNext = n.m_pPrev = null; n.m_bOnList = false; }
private CRNode m_pLast = null; // the last node // Functionality: // Insert a new UDT instance to the list. // Parameters: // 1) [in] u: pointer to the UDT instance // Returned value: // None. public void insert(CUDT u) { CRNode n = u.m_pRNode; CClock.rdtsc(n.m_llTimeStamp); n.m_bOnList = true; if (null == m_pUList) { // empty list, insert as the single node n.m_pPrev = n.m_pNext = null; m_pLast = m_pUList = n; return; } // always insert at the end for RcvUList n.m_pPrev = m_pLast; n.m_pNext = null; m_pLast.m_pNext = n; m_pLast = n; }
// Functionality: // Move the UDT instance to the end of the list, if it already exists; otherwise, do nothing. // Parameters: // 1) [in] u: pointer to the UDT instance // Returned value: // None. public void update(CUDT u) { CRNode n = u.m_pRNode; if (!n.m_bOnList) return; CClock.rdtsc(n.m_llTimeStamp); // if n is the last node, do not need to change if (null == n.m_pNext) return; if (null == n.m_pPrev) { m_pUList = n.m_pNext; m_pUList.m_pPrev = null; } else { n.m_pPrev.m_pNext = n.m_pNext; n.m_pNext.m_pPrev = n.m_pPrev; } n.m_pPrev = m_pLast; n.m_pNext = null; m_pLast.m_pNext = n; m_pLast = n; }
// Functionality: // initialize a UDT entity and bind to a local address. // Parameters: // None. // Returned value: // None. public void open() { CGuard cg = new CGuard(m_ConnectionLock); // Initial sequence number, loss, acknowledgement, etc. m_iPktSize = m_iMSS - 28; m_iPayloadSize = m_iPktSize - CPacket.m_iPktHdrSize; m_iEXPCount = 1; m_iBandwidth = 1; m_iDeliveryRate = 16; m_iAckSeqNo = 0; m_ullLastAckTime = 0; // trace information m_StartTime = CClock.getTime(); m_llSentTotal = m_llRecvTotal = m_iSndLossTotal = m_iRcvLossTotal = m_iRetransTotal = m_iSentACKTotal = m_iRecvACKTotal = m_iSentNAKTotal = m_iRecvNAKTotal = 0; m_LastSampleTime = CClock.getTime(); m_llTraceSent = m_llTraceRecv = m_iTraceSndLoss = m_iTraceRcvLoss = m_iTraceRetrans = m_iSentACK = m_iRecvACK = m_iSentNAK = m_iRecvNAK = 0; m_llSndDuration = m_llSndDurationTotal = 0; // structures for queue if (null == m_pSNode) m_pSNode = new CSNode(); m_pSNode.m_pUDT = this; m_pSNode.m_llTimeStamp = 1; m_pSNode.m_iHeapLoc = -1; if (null == m_pRNode) m_pRNode = new CRNode(); m_pRNode.m_pUDT = this; m_pRNode.m_llTimeStamp = 1; m_pRNode.m_pPrev = m_pRNode.m_pNext = null; m_pRNode.m_bOnList = false; m_iRTT = 10 * m_iSYNInterval; m_iRTTVar = m_iRTT >> 1; m_ullCPUFrequency = CClock.getCPUFrequency(); // set up the timers m_ullSYNInt = m_iSYNInterval * m_ullCPUFrequency; m_ullACKInt = m_ullSYNInt; m_ullNAKInt = (m_iRTT + 4 * m_iRTTVar) * m_ullCPUFrequency; m_ullEXPInt = (m_iRTT + 4 * m_iRTTVar) * m_ullCPUFrequency + m_ullSYNInt; m_ullMinEXPInt = 100000 * m_ullCPUFrequency; CClock.rdtsc(m_ullNextACKTime); m_ullNextACKTime += m_ullSYNInt; CClock.rdtsc(m_ullNextNAKTime); m_ullNextNAKTime += m_ullNAKInt; CClock.rdtsc(m_ullNextEXPTime); m_ullNextEXPTime += m_ullEXPInt; m_iPktCount = 0; m_iLightACKCount = 1; m_ullTargetTime = 0; m_ullTimeDiff = 0; // Now UDT is opened. m_bOpened = true; }
internal CRNode m_pRNode; // node information for UDT list used in rcv queue #endregion #region constructor and desctructor CUDT(CUDT ancestor) { m_pSndBuffer = null; m_pRcvBuffer = null; m_pSndLossList = null; m_pRcvLossList = null; m_pACKWindow = null; m_pSndTimeWindow = null; m_pRcvTimeWindow = null; m_pSndQueue = null; m_pRcvQueue = null; m_pPeerAddr = null; m_pSNode = null; m_pRNode = null; // Initilize mutex and condition variables initSynch(); // Default UDT configurations m_iMSS = ancestor.m_iMSS; m_bSynSending = ancestor.m_bSynSending; m_bSynRecving = ancestor.m_bSynRecving; m_iFlightFlagSize = ancestor.m_iFlightFlagSize; m_iSndBufSize = ancestor.m_iSndBufSize; m_iRcvBufSize = ancestor.m_iRcvBufSize; m_Linger = ancestor.m_Linger; m_iUDPSndBufSize = ancestor.m_iUDPSndBufSize; m_iUDPRcvBufSize = ancestor.m_iUDPRcvBufSize; m_iSockType = ancestor.m_iSockType; m_iIPversion = ancestor.m_iIPversion; m_bRendezvous = ancestor.m_bRendezvous; m_iSndTimeOut = ancestor.m_iSndTimeOut; m_iRcvTimeOut = ancestor.m_iRcvTimeOut; m_bReuseAddr = true; // this must be true, because all accepted sockets shared the same port with the listener m_llMaxBW = ancestor.m_llMaxBW; m_pCCFactory = ancestor.m_pCCFactory.clone(); m_pCC = null; m_pCache = ancestor.m_pCache; // Initial status m_bOpened = false; m_bListening = false; m_bConnected = false; m_bClosing = false; m_bShutdown = false; m_bBroken = false; }