SL-11657 Further improvements

meow-7.2.2
andreykproductengine 2019-08-29 22:15:54 +03:00
parent cdcdc4b3e3
commit 23acff80c0
2 changed files with 58 additions and 13 deletions

View File

@ -142,6 +142,9 @@ const F32 PHYSICS_TIMESTEP = 1.f / 45.f;
const U32 MAX_INV_FILE_READ_FAILS = 25;
const S32 MAX_OBJECT_BINARY_DATA_SIZE = 60 + 16;
const F64 INVENTORY_UPDATE_WAIT_TIME_DESYNC = 5; // seconds
const F64 INVENTORY_UPDATE_WAIT_TIME_OUTDATED = 1;
static LLTrace::BlockTimerStatHandle FTM_CREATE_OBJECT("Create Object");
// static
@ -2979,6 +2982,8 @@ void LLViewerObject::fetchInventoryFromServer()
if (!isInventoryPending())
{
delete mInventory;
// Results in processTaskInv
LLMessageSystem* msg = gMessageSystem;
msg->newMessageFast(_PREHASH_RequestTaskInventory);
msg->nextBlockFast(_PREHASH_AgentData);
@ -2988,11 +2993,44 @@ void LLViewerObject::fetchInventoryFromServer()
msg->addU32Fast(_PREHASH_LocalID, mLocalID);
msg->sendReliable(mRegionp->getHost());
// this will get reset by dirtyInventory or doInventoryCallback
// This will get reset by doInventoryCallback or processTaskInv
mInvRequestState = INVENTORY_REQUEST_PENDING;
}
}
void LLViewerObject::fetchInventoryDelayed(const F64 &time_seconds)
{
// unless already waiting, drop previous request and shedule an update
if (mInvRequestState != INVENTORY_REQUEST_WAIT)
{
if (mInvRequestXFerId != 0)
{
// abort download.
gXferManager->abortRequestById(mInvRequestXFerId, -1);
mInvRequestXFerId = 0;
}
mInvRequestState = INVENTORY_REQUEST_WAIT; // affects isInventoryPending()
LLCoros::instance().launch("LLViewerObject::fetchInventoryDelayedCoro()",
boost::bind(&LLViewerObject::fetchInventoryDelayedCoro, mID, time_seconds));
}
}
//static
void LLViewerObject::fetchInventoryDelayedCoro(const LLUUID task_inv, const F64 time_seconds)
{
llcoro::suspendUntilTimeout(time_seconds);
LLViewerObject *obj = gObjectList.findObject(task_inv);
if (obj)
{
// Might be good idea to prolong delay here in case expected serial changed.
// As it is, it will get a response with obsolete serial and will delay again.
// drop waiting state to unlock isInventoryPending()
obj->mInvRequestState = INVENTORY_REQUEST_STOPPED;
obj->fetchInventoryFromServer();
}
}
LLControlAvatar *LLViewerObject::getControlAvatar()
{
return getRootEdit()->mControlAvatar.get();
@ -3166,30 +3204,32 @@ void LLViewerObject::processTaskInv(LLMessageSystem* msg, void** user_data)
// we can receive multiple task updates simultaneously, make sure we will not rewrite newer with older update
msg->getS16Fast(_PREHASH_InventoryData, _PREHASH_Serial, ft->mSerial);
if (ft->mSerial == object->mInventorySerialNum)
if (ft->mSerial == object->mInventorySerialNum
&& ft->mSerial < object->mExpectedInventorySerialNum)
{
// Loop Protection.
// We received same serial twice.
// Viewer did some changes to inventory that couldn't be saved server side
// or something went wrong to cause serial to be out of sync
// or something went wrong to cause serial to be out of sync.
// Drop xfer and restart after some time, assign server's value as expected
LL_WARNS() << "Task inventory serial might be out of sync, server serial: " << ft->mSerial << " client expected serial: " << object->mExpectedInventorySerialNum << LL_ENDL;
object->mExpectedInventorySerialNum = ft->mSerial;
object->fetchInventoryDelayed(INVENTORY_UPDATE_WAIT_TIME_DESYNC);
}
if (ft->mSerial < object->mExpectedInventorySerialNum)
else if (ft->mSerial < object->mExpectedInventorySerialNum)
{
// out of date message, record to current serial for loop protection, but do not load it
// just drop xfer to restart on idle
// Out of date message, record to current serial for loop protection, but do not load it
// Drop xfer and restart after some time
if (ft->mSerial < object->mInventorySerialNum)
{
LL_WARNS() << "Somehow task serial decreased, out of order packet?" << LL_ENDL;
LL_WARNS() << "Task serial decreased. Potentially out of order packet or desync." << LL_ENDL;
}
object->mInventorySerialNum = ft->mSerial;
object->mInvRequestXFerId = 0;
object->mInvRequestState = INVENTORY_REQUEST_STOPPED;
object->fetchInventoryDelayed(INVENTORY_UPDATE_WAIT_TIME_OUTDATED);
}
else if (ft->mSerial >= object->mExpectedInventorySerialNum)
{
// We received version we expected or newer. Load it.
object->mInventorySerialNum = ft->mSerial;
object->mExpectedInventorySerialNum = ft->mSerial;

View File

@ -621,9 +621,13 @@ private:
static void initObjectDataMap();
// forms task inventory request if none are pending
// forms task inventory request if none are pending, marks request as pending
void fetchInventoryFromServer();
// forms task inventory request after some time passed, marks request as pending
void fetchInventoryDelayed(const F64 &time_seconds);
static void fetchInventoryDelayedCoro(const LLUUID task_inv, const F64 time_seconds);
public:
//
// Viewer-side only types - use the LL_PCODE_APP mask.
@ -807,8 +811,9 @@ protected:
enum EInventoryRequestState
{
INVENTORY_REQUEST_STOPPED,
INVENTORY_REQUEST_PENDING,
INVENTORY_XFER
INVENTORY_REQUEST_WAIT, // delay before requesting
INVENTORY_REQUEST_PENDING, // just did fetchInventoryFromServer()
INVENTORY_XFER // processed response from 'fetch', now doing an xfer
};
EInventoryRequestState mInvRequestState;
U64 mInvRequestXFerId;