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
parent
439d26ccdc
commit
b9b38db567
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue