SL-11657 Further improvements
parent
cdcdc4b3e3
commit
23acff80c0
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue