Fix for SL-19968 objects missing timing bug due to stall during login

ensure inventory skeleton loading doesn't block the message system from processing packets.
meow-7.2.2
Brad Kittenbrink (Brad Linden) 2023-07-28 16:52:06 -07:00 committed by Brad Linden
parent 439d26ccdc
commit b9b38db567
6 changed files with 209 additions and 31 deletions

View File

@ -475,6 +475,7 @@ LLSDNotationParser::~LLSDNotationParser()
// virtual
S32 LLSDNotationParser::doParse(std::istream& istr, LLSD& data, S32 max_depth) const
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD
// map: { string:object, string:object }
// array: [ object, object, object ]
// undef: !
@ -734,6 +735,7 @@ S32 LLSDNotationParser::doParse(std::istream& istr, LLSD& data, S32 max_depth) c
S32 LLSDNotationParser::parseMap(std::istream& istr, LLSD& map, S32 max_depth) const
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD
// map: { string:object, string:object }
map = LLSD::emptyMap();
S32 parse_count = 0;
@ -794,6 +796,7 @@ S32 LLSDNotationParser::parseMap(std::istream& istr, LLSD& map, S32 max_depth) c
S32 LLSDNotationParser::parseArray(std::istream& istr, LLSD& array, S32 max_depth) const
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD
// array: [ object, object, object ]
array = LLSD::emptyArray();
S32 parse_count = 0;
@ -833,6 +836,7 @@ S32 LLSDNotationParser::parseArray(std::istream& istr, LLSD& array, S32 max_dept
bool LLSDNotationParser::parseString(std::istream& istr, LLSD& data) const
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD
std::string value;
auto count = deserialize_string(istr, value, mMaxBytesLeft);
if(PARSE_FAILURE == count) return false;
@ -843,6 +847,7 @@ bool LLSDNotationParser::parseString(std::istream& istr, LLSD& data) const
bool LLSDNotationParser::parseBinary(std::istream& istr, LLSD& data) const
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD
// binary: b##"ff3120ab1"
// or: b(len)"..."
@ -945,6 +950,7 @@ LLSDBinaryParser::~LLSDBinaryParser()
// virtual
S32 LLSDBinaryParser::doParse(std::istream& istr, LLSD& data, S32 max_depth) const
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD
/**
* Undefined: '!'<br>
* Boolean: '1' for true '0' for false<br>

View File

@ -923,6 +923,8 @@ void LLSDXMLParser::parsePart(const char *buf, llssize len)
// virtual
S32 LLSDXMLParser::doParse(std::istream& input, LLSD& data, S32 max_depth) const
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD
#ifdef XML_PARSER_PERFORMANCE_TESTS
XML_Timer timer( &parseTime );
#endif // XML_PARSER_PERFORMANCE_TESTS

View File

@ -904,6 +904,8 @@ bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new)
mInventoryType = LLInventoryType::IT_NONE;
mAssetUUID.setNull();
}
#if 0 // old implementation. makes a LOT of temporary copies and LLSD::safe(impl) calls
std::string w;
w = INV_ITEM_ID_LABEL;
@ -1050,6 +1052,132 @@ bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new)
{
mCreationDate = sd[w].asInteger();
}
#else // if 0 - new implementation follows
// iterate as map to avoid making unnecessary temp copies of everything
LLSD::map_const_iterator i, end;
end = sd.endMap();
for (i = sd.beginMap(); i != end; ++i)
{
if (i->first == INV_ITEM_ID_LABEL)
{
mUUID = i->second;
}
if (i->first == INV_PARENT_ID_LABEL)
{
mParentUUID = i->second;
}
if (i->first == INV_PERMISSIONS_LABEL)
{
mPermissions = ll_permissions_from_sd(i->second);
}
if (i->first == INV_SALE_INFO_LABEL)
{
// Sale info used to contain next owner perm. It is now in
// the permissions. Thus, we read that out, and fix legacy
// objects. It's possible this op would fail, but it
// should pick up the vast majority of the tasks.
BOOL has_perm_mask = FALSE;
U32 perm_mask = 0;
if (!mSaleInfo.fromLLSD(i->second, has_perm_mask, perm_mask))
{
goto fail;
}
if (has_perm_mask)
{
if (perm_mask == PERM_NONE)
{
perm_mask = mPermissions.getMaskOwner();
}
// fair use fix.
if (!(perm_mask & PERM_COPY))
{
perm_mask |= PERM_TRANSFER;
}
mPermissions.setMaskNext(perm_mask);
}
}
if (i->first == INV_SHADOW_ID_LABEL)
{
mAssetUUID = i->second;
LLXORCipher cipher(MAGIC_ID.mData, UUID_BYTES);
cipher.decrypt(mAssetUUID.mData, UUID_BYTES);
}
if (i->first == INV_ASSET_ID_LABEL)
{
mAssetUUID = i->second;
}
if (i->first == INV_LINKED_ID_LABEL)
{
mAssetUUID = i->second;
}
if (i->first == INV_ASSET_TYPE_LABEL)
{
LLSD const &label = i->second;
if (label.isString())
{
mType = LLAssetType::lookup(label.asString().c_str());
}
else if (label.isInteger())
{
S8 type = (U8) label.asInteger();
mType = static_cast<LLAssetType::EType>(type);
}
}
if (i->first == INV_INVENTORY_TYPE_LABEL)
{
LLSD const &label = i->second;
if (label.isString())
{
mInventoryType = LLInventoryType::lookup(label.asString().c_str());
}
else if (label.isInteger())
{
S8 type = (U8) label.asInteger();
mInventoryType = static_cast<LLInventoryType::EType>(type);
}
}
if (i->first == INV_FLAGS_LABEL)
{
LLSD const &label = i->second;
if (label.isBinary())
{
mFlags = ll_U32_from_sd(label);
}
else if (label.isInteger())
{
mFlags = label.asInteger();
}
}
if (i->first == INV_NAME_LABEL)
{
mName = i->second.asString();
LLStringUtil::replaceNonstandardASCII(mName, ' ');
LLStringUtil::replaceChar(mName, '|', ' ');
}
if (i->first == INV_DESC_LABEL)
{
mDescription = i->second.asString();
LLStringUtil::replaceNonstandardASCII(mDescription, ' ');
}
if (i->first == INV_CREATION_DATE_LABEL)
{
mCreationDate = i->second.asInteger();
}
}
#endif // new version
// Need to convert 1.0 simstate files to a useful inventory type
// and potentially deal with bad inventory tyes eg, a landmark

View File

@ -66,6 +66,7 @@
#include "bufferstream.h"
#include "llcorehttputil.h"
#include "hbxxh.h"
#include "llstartup.h"
//#define DIFF_INVENTORY_FILES
#ifdef DIFF_INVENTORY_FILES
@ -2642,6 +2643,7 @@ bool LLInventoryModel::loadSkeleton(
const LLSD& options,
const LLUUID& owner_id)
{
LL_PROFILE_ZONE_SCOPED;
LL_DEBUGS(LOG_INV) << "importing inventory skeleton for " << owner_id << LL_ENDL;
typedef std::set<LLPointer<LLViewerInventoryCategory>, InventoryIDPtrLess> cat_set_t;
@ -3321,6 +3323,8 @@ bool LLInventoryModel::loadFromFile(const std::string& filename,
LLInventoryModel::changed_items_t& cats_to_update,
bool &is_cache_obsolete)
{
LL_PROFILE_ZONE_NAMED_COLOR("inventory load from file", 0xFF1111);
if(filename.empty())
{
LL_ERRS(LOG_INV) << "filename is Null!" << LL_ENDL;
@ -3338,6 +3342,7 @@ bool LLInventoryModel::loadFromFile(const std::string& filename,
is_cache_obsolete = true; // Obsolete until proven current
U64 lines_count = 0U;
std::string line;
LLPointer<LLSDParser> parser = new LLSDNotationParser();
while (std::getline(file, line))
@ -3386,7 +3391,7 @@ bool LLInventoryModel::loadFromFile(const std::string& filename,
{
if(inv_item->getUUID().isNull())
{
LL_WARNS(LOG_INV) << "Ignoring inventory with null item id: "
LL_DEBUGS(LOG_INV) << "Ignoring inventory with null item id: "
<< inv_item->getName() << LL_ENDL;
}
else
@ -3402,6 +3407,13 @@ bool LLInventoryModel::loadFromFile(const std::string& filename,
}
}
}
static constexpr U64 BATCH_SIZE = 512U;
if ((++lines_count % BATCH_SIZE) == 0)
{
// SL-19968 - make sure message system code gets a chance to run every so often
pump_idle_startup_network();
}
}
file.close();

View File

@ -302,10 +302,22 @@ void callback_cache_name(const LLUUID& id, const std::string& full_name, bool is
// exported functionality
//
void pump_idle_startup_network(void)
{
{
LockMessageChecker lmc(gMessageSystem);
while (lmc.checkAllMessages(gFrameCount, gServicePump))
{
display_startup();
}
lmc.processAcks();
}
display_startup();
}
//
// local classes
//
void update_texture_fetch()
{
LLAppViewer::getTextureCache()->update(1); // unpauses the texture cache thread
@ -1644,15 +1656,7 @@ bool idle_startup()
{
LLStartUp::setStartupState( STATE_AGENT_SEND );
}
{
LockMessageChecker lmc(gMessageSystem);
while (lmc.checkAllMessages(gFrameCount, gServicePump))
{
display_startup();
}
lmc.processAcks();
}
display_startup();
pump_idle_startup_network();
return FALSE;
}
@ -1752,6 +1756,7 @@ bool idle_startup()
//---------------------------------------------------------------------
if (STATE_INVENTORY_SEND == LLStartUp::getStartupState())
{
LL_PROFILE_ZONE_NAMED("State inventory send")
display_startup();
// request mute list
@ -1783,7 +1788,7 @@ bool idle_startup()
}
}
display_startup();
LLSD inv_lib_owner = response["inventory-lib-owner"];
if(inv_lib_owner.isDefined())
{
@ -1791,30 +1796,52 @@ bool idle_startup()
LLSD id = inv_lib_owner[0]["agent_id"];
if(id.isDefined())
{
gInventory.setLibraryOwnerID( LLUUID(id.asUUID()));
gInventory.setLibraryOwnerID(LLUUID(id.asUUID()));
}
}
display_startup();
LLSD inv_skel_lib = response["inventory-skel-lib"];
if(inv_skel_lib.isDefined() && gInventory.getLibraryOwnerID().notNull())
{
if(!gInventory.loadSkeleton(inv_skel_lib, gInventory.getLibraryOwnerID()))
{
LL_WARNS("AppInit") << "Problem loading inventory-skel-lib" << LL_ENDL;
}
}
LLStartUp::setStartupState(STATE_INVENTORY_SKEL);
display_startup();
return FALSE;
}
LLSD inv_skeleton = response["inventory-skeleton"];
if(inv_skeleton.isDefined())
{
if(!gInventory.loadSkeleton(inv_skeleton, gAgent.getID()))
{
LL_WARNS("AppInit") << "Problem loading inventory-skel-targets" << LL_ENDL;
}
}
display_startup();
if (STATE_INVENTORY_SKEL == LLStartUp::getStartupState())
{
LL_PROFILE_ZONE_NAMED("State inventory load skeleton")
LLSD response = LLLoginInstance::getInstance()->getResponse();
LLSD inv_skel_lib = response["inventory-skel-lib"];
if (inv_skel_lib.isDefined() && gInventory.getLibraryOwnerID().notNull())
{
LL_PROFILE_ZONE_NAMED("load library inv")
if (!gInventory.loadSkeleton(inv_skel_lib, gInventory.getLibraryOwnerID()))
{
LL_WARNS("AppInit") << "Problem loading inventory-skel-lib" << LL_ENDL;
}
}
display_startup();
LLSD inv_skeleton = response["inventory-skeleton"];
if (inv_skeleton.isDefined())
{
LL_PROFILE_ZONE_NAMED("load personal inv")
if (!gInventory.loadSkeleton(inv_skeleton, gAgent.getID()))
{
LL_WARNS("AppInit") << "Problem loading inventory-skel-targets" << LL_ENDL;
}
}
display_startup();
LLStartUp::setStartupState(STATE_INVENTORY_SEND2);
display_startup();
return FALSE;
}
if (STATE_INVENTORY_SEND2 == LLStartUp::getStartupState())
{
LL_PROFILE_ZONE_NAMED("State inventory send2")
LLSD response = LLLoginInstance::getInstance()->getResponse();
LLSD inv_basic = response["inventory-basic"];
if(inv_basic.isDefined())

View File

@ -40,6 +40,7 @@ class LLSLURL;
bool idle_startup();
void release_start_screen();
bool login_alert_done(const LLSD& notification, const LLSD& response);
void pump_idle_startup_network();
// start location constants
enum EStartLocation
@ -72,6 +73,8 @@ typedef enum {
STATE_AGENT_WAIT, // Wait for region
STATE_INVENTORY_SEND, // Do inventory transfer
STATE_INVENTORY_CALLBACKS, // Wait for missing system folders and register callbacks
STATE_INVENTORY_SKEL, // Do more inventory skeleton loading
STATE_INVENTORY_SEND2, // Do more inventory init after skeleton is loaded
STATE_MISC, // Do more things (set bandwidth, start audio, save location, etc)
STATE_PRECACHE, // Wait a bit for textures to download
STATE_WEARABLES_WAIT, // Wait for clothing to download