diff options
Diffstat (limited to 'indra/llmessage/llcircuit.cpp')
-rw-r--r-- | indra/llmessage/llcircuit.cpp | 109 |
1 files changed, 58 insertions, 51 deletions
diff --git a/indra/llmessage/llcircuit.cpp b/indra/llmessage/llcircuit.cpp index 0db9f8e2f1..3ba2dfb104 100644 --- a/indra/llmessage/llcircuit.cpp +++ b/indra/llmessage/llcircuit.cpp @@ -2,30 +2,25 @@ * @file llcircuit.cpp * @brief Class to track UDP endpoints for the message system. * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library 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 + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -60,8 +55,8 @@ #include "llrand.h" #include "llstl.h" #include "lltransfermanager.h" +#include "llmodularmath.h" -const F32 PING_INTERVAL = 5.f; // seconds const S32 PING_START_BLOCK = 3; // How many pings behind we have to be to consider ourself blocked. const S32 PING_RELEASE_BLOCK = 2; // How many pings behind we have to be to consider ourself unblocked. @@ -69,12 +64,15 @@ const F32 TARGET_PERIOD_LENGTH = 5.f; // seconds const F32 LL_DUPLICATE_SUPPRESSION_TIMEOUT = 60.f; //seconds - this can be long, as time-based cleanup is // only done when wrapping packetids, now... -LLCircuitData::LLCircuitData(const LLHost &host, TPACKETID in_id) +LLCircuitData::LLCircuitData(const LLHost &host, TPACKETID in_id, + const F32 circuit_heartbeat_interval, const F32 circuit_timeout) : mHost (host), mWrapID(0), mPacketsOutID(0), mPacketsInID(in_id), mHighestPacketID(in_id), + mTimeoutCallback(NULL), + mTimeoutUserData(NULL), mTrusted(FALSE), mbAllowTimeout(TRUE), mbAlive(TRUE), @@ -100,11 +98,14 @@ LLCircuitData::LLCircuitData(const LLHost &host, TPACKETID in_id) mBytesOutLastPeriod(0), mBytesInThisPeriod(0), mBytesOutThisPeriod(0), - mPeakBPSIn(0), - mPeakBPSOut(0), + mPeakBPSIn(0.f), + mPeakBPSOut(0.f), mPeriodTime(0.0), mExistenceTimer(), - mCurrentResendCount(0) + mCurrentResendCount(0), + mLastPacketGap(0), + mHeartbeatInterval(circuit_heartbeat_interval), + mHeartbeatTimeout(circuit_timeout) { // Need to guarantee that this time is up to date, we may be creating a circuit even though we haven't been // running a message system loop. @@ -112,14 +113,11 @@ LLCircuitData::LLCircuitData(const LLHost &host, TPACKETID in_id) F32 distribution_offset = ll_frand(); mPingTime = mt_sec; - mLastPingSendTime = mt_sec + PING_INTERVAL * distribution_offset; + mLastPingSendTime = mt_sec + mHeartbeatInterval * distribution_offset; mLastPingReceivedTime = mt_sec; - mNextPingSendTime = mLastPingSendTime + 0.95*PING_INTERVAL + ll_frand(0.1f*PING_INTERVAL); + mNextPingSendTime = mLastPingSendTime + 0.95*mHeartbeatInterval + ll_frand(0.1f*mHeartbeatInterval); mPeriodTime = mt_sec; - mTimeoutCallback = NULL; - mTimeoutUserData = NULL; - mLocalEndPointID.generate(); } @@ -184,7 +182,7 @@ LLCircuitData::~LLCircuitData() std::ostream_iterator<TPACKETID> append(str, " "); str << "MSG: -> " << mHost << "\tABORTING RELIABLE:\t"; std::copy(doomed.begin(), doomed.end(), append); - llinfos << str.str().c_str() << llendl; + llinfos << str.str() << llendl; } } @@ -204,7 +202,7 @@ void LLCircuitData::ackReliablePacket(TPACKETID packet_num) std::ostringstream str; str << "MSG: <- " << packetp->mHost << "\tRELIABLE ACKED:\t" << packetp->mPacketID; - llinfos << str.str().c_str() << llendl; + llinfos << str.str() << llendl; } if (packetp->mCallback) { @@ -238,7 +236,7 @@ void LLCircuitData::ackReliablePacket(TPACKETID packet_num) std::ostringstream str; str << "MSG: <- " << packetp->mHost << "\tRELIABLE ACKED:\t" << packetp->mPacketID; - llinfos << str.str().c_str() << llendl; + llinfos << str.str() << llendl; } if (packetp->mCallback) { @@ -342,7 +340,7 @@ S32 LLCircuitData::resendUnackedPackets(const F64 now) std::ostringstream str; str << "MSG: -> " << packetp->mHost << "\tRESENDING RELIABLE:\t" << packetp->mPacketID; - llinfos << str.str().c_str() << llendl; + llinfos << str.str() << llendl; } packetp->mBuffer[0] |= LL_RESENT_FLAG; // tag packet id as being a resend @@ -403,7 +401,7 @@ S32 LLCircuitData::resendUnackedPackets(const F64 now) std::ostringstream str; str << "MSG: -> " << packetp->mHost << "\tABORTING RELIABLE:\t" << packetp->mPacketID; - llinfos << str.str().c_str() << llendl; + llinfos << str.str() << llendl; } if (packetp->mCallback) @@ -428,7 +426,8 @@ S32 LLCircuitData::resendUnackedPackets(const F64 now) } -LLCircuit::LLCircuit() : mLastCircuit(NULL) +LLCircuit::LLCircuit(const F32 circuit_heartbeat_interval, const F32 circuit_timeout) : mLastCircuit(NULL), + mHeartbeatInterval(circuit_heartbeat_interval), mHeartbeatTimeout(circuit_timeout) { } @@ -446,7 +445,7 @@ LLCircuitData *LLCircuit::addCircuitData(const LLHost &host, TPACKETID in_id) { // This should really validate if one already exists llinfos << "LLCircuit::addCircuitData for " << host << llendl; - LLCircuitData *tempp = new LLCircuitData(host, in_id); + LLCircuitData *tempp = new LLCircuitData(host, in_id, mHeartbeatInterval, mHeartbeatTimeout); mCircuitData.insert(circuit_data_map::value_type(host, tempp)); mPingSet.insert(tempp); @@ -676,6 +675,8 @@ void LLCircuitData::checkPacketInID(TPACKETID id, BOOL receive_resent) mPacketsIn++; setPacketInID((id + 1) % LL_MAX_OUT_PACKET_ID); + mLastPacketGap = 0; + mOutOfOrderRate.count(0); return; } @@ -683,6 +684,7 @@ void LLCircuitData::checkPacketInID(TPACKETID id, BOOL receive_resent) // now, check to see if we've got a gap + U32 gap = 0; if ((mPacketsInID == id)) { // nope! bump and wrap the counter, then return @@ -704,13 +706,18 @@ void LLCircuitData::checkPacketInID(TPACKETID id, BOOL receive_resent) // otherwise, walk from mCurrentCircuit->mPacketsInID to id with wrapping, adding the values to the map // and setting mPacketsInID to id + 1 % LL_MAX_OUT_PACKET_ID + // babbage: all operands in expression are unsigned, so modular + // arithmetic will always find correct gap, regardless of wrap arounds. + const U8 width = 24; + gap = LLModularMath::subtract<width>(mPacketsInID, id); + if (mPotentialLostPackets.find(id) != mPotentialLostPackets.end()) { if(gMessageSystem->mVerboseLog) { std::ostringstream str; str << "MSG: <- " << mHost << "\tRECOVERING LOST:\t" << id; - llinfos << str.str().c_str() << llendl; + llinfos << str.str() << llendl; } // llinfos << "removing potential lost: " << id << llendl; mPotentialLostPackets.erase(id); @@ -729,7 +736,7 @@ void LLCircuitData::checkPacketInID(TPACKETID id, BOOL receive_resent) std::ostringstream str; str << "MSG: <- " << mHost << "\tPACKET GAP:\t" << index; - llinfos << str.str().c_str() << llendl; + llinfos << str.str() << llendl; } // llinfos << "adding potential lost: " << index << llendl; @@ -747,7 +754,7 @@ void LLCircuitData::checkPacketInID(TPACKETID id, BOOL receive_resent) std::ostringstream str; str << "MSG: <- " << mHost << "\tPACKET GAP:\t" << id << " expected " << index; - llinfos << str.str().c_str() << llendl; + llinfos << str.str() << llendl; } } @@ -765,6 +772,8 @@ void LLCircuitData::checkPacketInID(TPACKETID id, BOOL receive_resent) } } + mOutOfOrderRate.count(gap); + mLastPacketGap = gap; } @@ -790,7 +799,7 @@ void LLCircuit::updateWatchDogTimers(LLMessageSystem *msgsys) // Always remember to remove it from the set before changing the sorting // key (mNextPingSendTime) mPingSet.erase(psit); - cdp->mNextPingSendTime = cur_time + PING_INTERVAL; + cdp->mNextPingSendTime = cur_time + mHeartbeatInterval; mPingSet.insert(cdp); continue; } @@ -808,7 +817,7 @@ void LLCircuit::updateWatchDogTimers(LLMessageSystem *msgsys) if (cdp->updateWatchDogTimers(msgsys)) { // Randomize our pings a bit by doing some up to 5% early or late - F64 dt = 0.95f*PING_INTERVAL + ll_frand(0.1f*PING_INTERVAL); + F64 dt = 0.95f*mHeartbeatInterval + ll_frand(0.1f*mHeartbeatInterval); // Remove it, and reinsert it with the new next ping time. // Always remove before changing the sorting key. @@ -969,7 +978,7 @@ BOOL LLCircuitData::updateWatchDogTimers(LLMessageSystem *msgsys) std::ostringstream str; str << "MSG: <- " << mHost << "\tLOST PACKET:\t" << (*it).first; - llinfos << str.str().c_str() << llendl; + llinfos << str.str() << llendl; } mPotentialLostPackets.erase(it++); } @@ -1036,7 +1045,7 @@ BOOL LLCircuitData::checkCircuitTimeout() F64 time_since_last_ping = LLMessageSystem::getMessageTimeSeconds() - mLastPingReceivedTime; // Nota Bene: This needs to be turned off if you are debugging multiple simulators - if (time_since_last_ping > PING_INTERVAL_MAX) + if (time_since_last_ping > mHeartbeatTimeout) { llwarns << "LLCircuitData::checkCircuitTimeout for " << mHost << " last ping " << time_since_last_ping << " seconds ago." <<llendl; setAlive(FALSE); @@ -1052,10 +1061,7 @@ BOOL LLCircuitData::checkCircuitTimeout() return FALSE; } } - else if (time_since_last_ping > PING_INTERVAL_ALARM) - { - //llwarns << "Unresponsive circuit: " << mHost << ": " << time_since_last_ping << " seconds since last ping."<< llendl; - } + return TRUE; } @@ -1114,7 +1120,7 @@ void LLCircuit::sendAcks() str << "MSG: -> " << cd->mHost << "\tPACKET ACKS:\t"; std::ostream_iterator<TPACKETID> append(str, " "); std::copy(cd->mAcks.begin(), cd->mAcks.end(), append); - llinfos << str.str().c_str() << llendl; + llinfos << str.str() << llendl; } // empty out the acks list @@ -1269,7 +1275,7 @@ void LLCircuitData::pingTimerStop(const U8 ping_id) delta_ping += 256; } - U32 msec = (U32) ((delta_ping*PING_INTERVAL + time) * 1000.f); + U32 msec = (U32) ((delta_ping*mHeartbeatInterval + time) * 1000.f); setPingDelay(msec); mPingsInTransit = delta_ping; @@ -1360,7 +1366,8 @@ F32 LLCircuitData::getPingInTransitTime() if (mPingsInTransit) { - time_since_ping_was_sent = (F32)((mPingsInTransit*PING_INTERVAL - 1) + (LLMessageSystem::getMessageTimeSeconds() - mPingTime))*1000.f; + time_since_ping_was_sent = (F32)((mPingsInTransit*mHeartbeatInterval - 1) + + (LLMessageSystem::getMessageTimeSeconds() - mPingTime))*1000.f; } return time_since_ping_was_sent; |