diff options
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/llcommon/llassettype.h | 2 | ||||
| -rw-r--r-- | indra/llcommon/llerror.cpp | 2 | ||||
| -rw-r--r-- | indra/llmessage/llassetstorage.cpp | 2381 | ||||
| -rw-r--r-- | indra/llmessage/llassetstorage.h | 112 | ||||
| -rw-r--r-- | indra/newview/VIEWER_VERSION.txt | 2 | ||||
| -rw-r--r-- | indra/newview/app_settings/settings.xml | 20 | ||||
| -rw-r--r-- | indra/newview/llappviewer.cpp | 21 | ||||
| -rw-r--r-- | indra/newview/llmeshrepository.cpp | 147 | ||||
| -rw-r--r-- | indra/newview/llmeshrepository.h | 13 | ||||
| -rw-r--r-- | indra/newview/lltexturefetch.cpp | 95 | ||||
| -rw-r--r-- | indra/newview/lltexturefetch.h | 2 | ||||
| -rw-r--r-- | indra/newview/llviewerassetstats.cpp | 398 | ||||
| -rw-r--r-- | indra/newview/llviewerassetstats.h | 59 | ||||
| -rw-r--r-- | indra/newview/llviewerassetstorage.cpp | 758 | ||||
| -rw-r--r-- | indra/newview/llviewerassetstorage.h | 34 | ||||
| -rw-r--r-- | indra/newview/llviewerdisplay.cpp | 7 | ||||
| -rw-r--r-- | indra/newview/llviewerregion.cpp | 14 | ||||
| -rw-r--r-- | indra/newview/llviewerregion.h | 4 | ||||
| -rw-r--r-- | indra/newview/llvoavatar.cpp | 3 | ||||
| -rw-r--r-- | indra/newview/tests/llviewerassetstats_test.cpp | 26 | ||||
| -rw-r--r-- | indra/test/test.cpp | 2 | 
21 files changed, 1997 insertions, 2105 deletions
| diff --git a/indra/llcommon/llassettype.h b/indra/llcommon/llassettype.h index 3a4b5dad18..b849be9f16 100644 --- a/indra/llcommon/llassettype.h +++ b/indra/llcommon/llassettype.h @@ -152,7 +152,7 @@ public:  	static bool 				lookupIsAssetFetchByIDAllowed(EType asset_type); // the asset allows direct download  	static bool 				lookupIsAssetIDKnowable(EType asset_type); // asset data can be known by the viewer -	 +  	static const std::string&	badLookup(); // error string when a lookup fails  protected: diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index e6407ecf22..9c49f7eff4 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -572,7 +572,7 @@ namespace LLError  		mFunctionString += std::string(mFunction) + ":";  		for (size_t i = 0; i < mTagCount; i++)  		{ -			mTagString += std::string("#") + mTags[i] + ((i == mTagCount - 1) ? "" : ","); +			mTagString += std::string("#") + mTags[i] + ((i == mTagCount - 1) ? " " : ",");  		}  	} diff --git a/indra/llmessage/llassetstorage.cpp b/indra/llmessage/llassetstorage.cpp index bcf4e52b8f..596d57c7b7 100644 --- a/indra/llmessage/llassetstorage.cpp +++ b/indra/llmessage/llassetstorage.cpp @@ -60,64 +60,60 @@ static LLTrace::CountStatHandle<> sFailedDownloadCount("faileddownloads", "Numbe  const LLUUID CATEGORIZE_LOST_AND_FOUND_ID(std::string("00000000-0000-0000-0000-000000000010")); -const U64 TOXIC_ASSET_LIFETIME = (120 * 1000000);		// microseconds - -LLTempAssetStorage::~LLTempAssetStorage() -{ -} +const U64 TOXIC_ASSET_LIFETIME = (120 * 1000000);       // microseconds  ///----------------------------------------------------------------------------  /// LLAssetInfo  ///----------------------------------------------------------------------------  LLAssetInfo::LLAssetInfo( void ) -:	mDescription(), -	mName(), -	mUuid(), -	mCreatorID(), -	mType( LLAssetType::AT_NONE ) +    :   mDescription(), +        mName(), +        mUuid(), +        mCreatorID(), +        mType( LLAssetType::AT_NONE )  { }  LLAssetInfo::LLAssetInfo( const LLUUID& object_id, const LLUUID& creator_id, -						  LLAssetType::EType type, const char* name, -						  const char* desc ) -:	mUuid( object_id ),  -	mCreatorID( creator_id ),  -	mType( type ) +                          LLAssetType::EType type, const char* name, +                          const char* desc ) +    :   mUuid( object_id ),  +        mCreatorID( creator_id ),  +        mType( type )  { -	setName( name ); -	setDescription( desc ); +    setName( name ); +    setDescription( desc );  }  LLAssetInfo::LLAssetInfo( const LLNameValue& nv )  { -	setFromNameValue( nv ); +    setFromNameValue( nv );  }  // make sure the name is short enough, and strip all pipes since they  // are reserved characters in our inventory tracking system.  void LLAssetInfo::setName( const std::string& name )  { -	if( !name.empty() ) -	{ -		mName.assign( name, 0, llmin((U32)name.size(), (U32)DB_INV_ITEM_NAME_STR_LEN) ); -		mName.erase( std::remove(mName.begin(), mName.end(), '|'), -					 mName.end() ); -	} +    if( !name.empty() ) +    { +        mName.assign( name, 0, llmin((U32)name.size(), (U32)DB_INV_ITEM_NAME_STR_LEN) ); +        mName.erase( std::remove(mName.begin(), mName.end(), '|'), +                     mName.end() ); +    }  }  // make sure the name is short enough, and strip all pipes since they  // are reserved characters in our inventory tracking system.  void LLAssetInfo::setDescription( const std::string& desc )  { -	if( !desc.empty() ) -	{ -		mDescription.assign( desc, 0, llmin((U32)desc.size(), -										 (U32)DB_INV_ITEM_DESC_STR_LEN) ); -		mDescription.erase( std::remove(mDescription.begin(), -										mDescription.end(), '|'), -							mDescription.end() ); -	} +    if( !desc.empty() ) +    { +        mDescription.assign( desc, 0, llmin((U32)desc.size(), +                                            (U32)DB_INV_ITEM_DESC_STR_LEN) ); +        mDescription.erase( std::remove(mDescription.begin(), +                                        mDescription.end(), '|'), +                            mDescription.end() ); +    }  }  // Assets (aka potential inventory items) can be applied to an @@ -130,31 +126,31 @@ void LLAssetInfo::setDescription( const std::string& desc )  //   value=<creatorid>|<name>|<description>|  void LLAssetInfo::setFromNameValue( const LLNameValue& nv )  { -	std::string str; -	std::string buf; -	std::string::size_type pos1; -	std::string::size_type pos2; - -	// convert the name to useful information -	str.assign( nv.mName ); -	pos1 = str.find('|'); -	buf.assign( str, 0, pos1++ ); -	mType = LLAssetType::lookup( buf ); -	buf.assign( str, pos1, std::string::npos ); -	mUuid.set( buf ); - -	// convert the value to useful information -	str.assign( nv.getAsset() ); -	pos1 = str.find('|'); -	buf.assign( str, 0, pos1++ ); -	mCreatorID.set( buf ); -	pos2 = str.find( '|', pos1 ); -	buf.assign( str, pos1, (pos2++) - pos1 ); -	setName( buf ); -	buf.assign( str, pos2, std::string::npos ); -	setDescription( buf ); -	LL_DEBUGS("AssetStorage") << "uuid: " << mUuid << LL_ENDL; -	LL_DEBUGS("AssetStorage") << "creator: " << mCreatorID << LL_ENDL; +    std::string str; +    std::string buf; +    std::string::size_type pos1; +    std::string::size_type pos2; + +    // convert the name to useful information +    str.assign( nv.mName ); +    pos1 = str.find('|'); +    buf.assign( str, 0, pos1++ ); +    mType = LLAssetType::lookup( buf ); +    buf.assign( str, pos1, std::string::npos ); +    mUuid.set( buf ); + +    // convert the value to useful information +    str.assign( nv.getAsset() ); +    pos1 = str.find('|'); +    buf.assign( str, 0, pos1++ ); +    mCreatorID.set( buf ); +    pos2 = str.find( '|', pos1 ); +    buf.assign( str, pos1, (pos2++) - pos1 ); +    setName( buf ); +    buf.assign( str, pos2, std::string::npos ); +    setDescription( buf ); +    LL_DEBUGS("AssetStorage") << "uuid: " << mUuid << LL_ENDL; +    LL_DEBUGS("AssetStorage") << "creator: " << mCreatorID << LL_ENDL;  }  ///---------------------------------------------------------------------------- @@ -162,15 +158,15 @@ void LLAssetInfo::setFromNameValue( const LLNameValue& nv )  ///----------------------------------------------------------------------------  LLBaseDownloadRequest::LLBaseDownloadRequest(const LLUUID &uuid, const LLAssetType::EType type) -: mUUID(uuid), -mType(type), -mDownCallback(NULL), -mUserData(NULL), -mHost(), -mIsTemp(FALSE), -mIsPriority(FALSE), -mDataSentInFirstPacket(FALSE), -mDataIsInVFS(FALSE) +    : mUUID(uuid), +      mType(type), +      mDownCallback(NULL), +      mUserData(NULL), +      mHost(), +      mIsTemp(FALSE), +      mIsPriority(FALSE), +      mDataSentInFirstPacket(FALSE), +      mDataIsInVFS(FALSE)  {      // 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. @@ -194,12 +190,13 @@ LLBaseDownloadRequest* LLBaseDownloadRequest::getCopy()  ///----------------------------------------------------------------------------  LLAssetRequest::LLAssetRequest(const LLUUID &uuid, const LLAssetType::EType type) -:	LLBaseDownloadRequest(uuid, type), -	mUpCallback( NULL ), -	mInfoCallback( NULL ), -	mIsLocal(FALSE), -	mIsUserWaiting(FALSE), -	mTimeout(LL_ASSET_STORAGE_TIMEOUT) +    :   LLBaseDownloadRequest(uuid, type), +        mUpCallback( NULL ), +        mInfoCallback( NULL ), +        mIsLocal(FALSE), +        mIsUserWaiting(FALSE), +        mTimeout(LL_ASSET_STORAGE_TIMEOUT), +        mBytesFetched(0)  {  } @@ -211,31 +208,31 @@ LLAssetRequest::~LLAssetRequest()  // virtual  LLSD LLAssetRequest::getTerseDetails() const  { -	LLSD sd; -	sd["asset_id"] = getUUID(); -	sd["type_long"] = LLAssetType::lookupHumanReadable(getType()); -	sd["type"] = LLAssetType::lookup(getType()); -	sd["time"] = mTime.value(); -	time_t timestamp = (time_t) mTime.value(); -	std::ostringstream time_string; -	time_string << ctime(×tamp); -	sd["time_string"] = time_string.str(); -	return sd; +    LLSD sd; +    sd["asset_id"] = getUUID(); +    sd["type_long"] = LLAssetType::lookupHumanReadable(getType()); +    sd["type"] = LLAssetType::lookup(getType()); +    sd["time"] = mTime.value(); +    time_t timestamp = (time_t) mTime.value(); +    std::ostringstream time_string; +    time_string << ctime(×tamp); +    sd["time_string"] = time_string.str(); +    return sd;  }  // virtual  LLSD LLAssetRequest::getFullDetails() const  { -	LLSD sd = getTerseDetails(); -	sd["host"] = mHost.getIPandPort(); -	sd["requesting_agent"] = mRequestingAgentID; -	sd["is_temp"] = mIsTemp; -	sd["is_local"] = mIsLocal; -	sd["is_priority"] = mIsPriority; -	sd["data_send_in_first_packet"] = mDataSentInFirstPacket; -	sd["data_is_in_vfs"] = mDataIsInVFS; - -	return sd; +    LLSD sd = getTerseDetails(); +    sd["host"] = mHost.getIPandPort(); +    sd["requesting_agent"] = mRequestingAgentID; +    sd["is_temp"] = mIsTemp; +    sd["is_local"] = mIsLocal; +    sd["is_priority"] = mIsPriority; +    sd["data_send_in_first_packet"] = mDataSentInFirstPacket; +    sd["data_is_in_vfs"] = mDataIsInVFS; + +    return sd;  }  LLBaseDownloadRequest* LLAssetRequest::getCopy() @@ -248,7 +245,7 @@ LLBaseDownloadRequest* LLAssetRequest::getCopy()  ///----------------------------------------------------------------------------  LLInvItemRequest::LLInvItemRequest(const LLUUID &uuid, const LLAssetType::EType type) -:	LLBaseDownloadRequest(uuid, type) +    :   LLBaseDownloadRequest(uuid, type)  {  } @@ -267,9 +264,9 @@ LLBaseDownloadRequest* LLInvItemRequest::getCopy()  ///----------------------------------------------------------------------------  LLEstateAssetRequest::LLEstateAssetRequest(const LLUUID &uuid, const LLAssetType::EType atype, -										   EstateAssetType etype) -:	LLBaseDownloadRequest(uuid, atype), -	mEstateAssetType(etype) +                                           EstateAssetType etype) +    :   LLBaseDownloadRequest(uuid, atype), +        mEstateAssetType(etype)  {  } @@ -299,152 +296,150 @@ LLBaseDownloadRequest* LLEstateAssetRequest::getCopy()  LLAssetStorage::LLAssetStorage(LLMessageSystem *msg, LLXferManager *xfer, LLVFS *vfs, LLVFS *static_vfs, const LLHost &upstream_host)  { -	_init(msg, xfer, vfs, static_vfs, upstream_host); +    _init(msg, xfer, vfs, static_vfs, upstream_host);  } -  LLAssetStorage::LLAssetStorage(LLMessageSystem *msg, LLXferManager *xfer, -							   LLVFS *vfs, LLVFS *static_vfs) +                               LLVFS *vfs, LLVFS *static_vfs)  { -	_init(msg, xfer, vfs, static_vfs, LLHost()); +    _init(msg, xfer, vfs, static_vfs, LLHost());  } -  void LLAssetStorage::_init(LLMessageSystem *msg, -						   LLXferManager *xfer, -						   LLVFS *vfs, -						   LLVFS *static_vfs, -						   const LLHost &upstream_host) +                           LLXferManager *xfer, +                           LLVFS *vfs, +                           LLVFS *static_vfs, +                           const LLHost &upstream_host)  { -	mShutDown = FALSE; -	mMessageSys = msg; -	mXferManager = xfer; -	mVFS = vfs; -	mStaticVFS = static_vfs; - -	setUpstream(upstream_host); -	msg->setHandlerFuncFast(_PREHASH_AssetUploadComplete, processUploadComplete, (void **)this); +    mShutDown = FALSE; +    mMessageSys = msg; +    mXferManager = xfer; +    mVFS = vfs; +    mStaticVFS = static_vfs; + +    setUpstream(upstream_host); +    msg->setHandlerFuncFast(_PREHASH_AssetUploadComplete, processUploadComplete, (void **)this);  }  LLAssetStorage::~LLAssetStorage()  { -	mShutDown = TRUE; -	 -	_cleanupRequests(TRUE, LL_ERR_CIRCUIT_GONE); - -	if (gMessageSystem) -	{ -		// Warning!  This won't work if there's more than one asset storage. -		// unregister our callbacks with the message system -		gMessageSystem->setHandlerFuncFast(_PREHASH_AssetUploadComplete, NULL, NULL); -	} - -	// Clear the toxic asset map -	mToxicAssetMap.clear(); +    mShutDown = TRUE; +     +    _cleanupRequests(TRUE, LL_ERR_CIRCUIT_GONE); + +    if (gMessageSystem) +    { +        // Warning!  This won't work if there's more than one asset storage. +        // unregister our callbacks with the message system +        gMessageSystem->setHandlerFuncFast(_PREHASH_AssetUploadComplete, NULL, NULL); +    } + +    // Clear the toxic asset map +    mToxicAssetMap.clear();  }  void LLAssetStorage::setUpstream(const LLHost &upstream_host)  { -	LL_DEBUGS("AppInit") << "AssetStorage: Setting upstream provider to " << upstream_host << LL_ENDL; -	 -	mUpstreamHost = upstream_host; +    LL_DEBUGS("AppInit") << "AssetStorage: Setting upstream provider to " << upstream_host << LL_ENDL; +     +    mUpstreamHost = upstream_host;  }  void LLAssetStorage::checkForTimeouts()  { -	_cleanupRequests(FALSE, LL_ERR_TCP_TIMEOUT); +    _cleanupRequests(FALSE, LL_ERR_TCP_TIMEOUT);  }  void LLAssetStorage::_cleanupRequests(BOOL all, S32 error)  { -	F64Seconds mt_secs = LLMessageSystem::getMessageTimeSeconds(); - -	request_list_t timed_out; -	S32 rt; -	for (rt = 0; rt < RT_COUNT; rt++) -	{ -		request_list_t* requests = getRequestList((ERequestType)rt); -		for (request_list_t::iterator iter = requests->begin(); -			 iter != requests->end(); ) -		{ -			request_list_t::iterator curiter = iter++; -			LLAssetRequest* tmp = *curiter; -			// if all is true, we want to clean up everything -			// otherwise just check for timed out requests -			// EXCEPT for upload timeouts -			if (all  -				|| ((RT_DOWNLOAD == rt) -					&& LL_ASSET_STORAGE_TIMEOUT < (mt_secs - tmp->mTime))) -			{ -				LL_WARNS() << "Asset " << getRequestName((ERequestType)rt) << " request " -						<< (all ? "aborted" : "timed out") << " for " -						<< tmp->getUUID() << "." -						<< LLAssetType::lookup(tmp->getType()) << LL_ENDL; - -				timed_out.push_front(tmp); -				iter = requests->erase(curiter); -			} -		} -	} - -	LLAssetInfo	info; -	for (request_list_t::iterator iter = timed_out.begin(); -		 iter != timed_out.end();  ) -	{ -		request_list_t::iterator curiter = iter++; -		LLAssetRequest* tmp = *curiter; -		if (tmp->mUpCallback) -		{ -			tmp->mUpCallback(tmp->getUUID(), tmp->mUserData, error, LL_EXSTAT_NONE); -		} -		if (tmp->mDownCallback) -		{ -			tmp->mDownCallback(mVFS, tmp->getUUID(), tmp->getType(), tmp->mUserData, error, LL_EXSTAT_NONE); -		} -		if (tmp->mInfoCallback) -		{ -			tmp->mInfoCallback(&info, tmp->mUserData, error); -		} -		delete tmp; -	} +    F64Seconds mt_secs = LLMessageSystem::getMessageTimeSeconds(); + +    request_list_t timed_out; +    S32 rt; +    for (rt = 0; rt < RT_COUNT; rt++) +    { +        request_list_t* requests = getRequestList((ERequestType)rt); +        for (request_list_t::iterator iter = requests->begin(); +             iter != requests->end(); ) +        { +            request_list_t::iterator curiter = iter++; +            LLAssetRequest* tmp = *curiter; +            // if all is true, we want to clean up everything +            // otherwise just check for timed out requests +            // EXCEPT for upload timeouts +            if (all  +                || ((RT_DOWNLOAD == rt) +                    && LL_ASSET_STORAGE_TIMEOUT < (mt_secs - tmp->mTime))) +            { +                LL_WARNS("AssetStorage") << "Asset " << getRequestName((ERequestType)rt) << " request " +                                         << (all ? "aborted" : "timed out") << " for " +                                         << tmp->getUUID() << "." +                                         << LLAssetType::lookup(tmp->getType()) << LL_ENDL; +                 +                timed_out.push_front(tmp); +                iter = requests->erase(curiter); +            } +        } +    } + +    LLAssetInfo     info; +    for (request_list_t::iterator iter = timed_out.begin(); +         iter != timed_out.end();  ) +    { +        request_list_t::iterator curiter = iter++; +        LLAssetRequest* tmp = *curiter; +        if (tmp->mUpCallback) +        { +            tmp->mUpCallback(tmp->getUUID(), tmp->mUserData, error, LL_EXSTAT_NONE); +        } +        if (tmp->mDownCallback) +        { +            tmp->mDownCallback(mVFS, tmp->getUUID(), tmp->getType(), tmp->mUserData, error, LL_EXSTAT_NONE); +        } +        if (tmp->mInfoCallback) +        { +            tmp->mInfoCallback(&info, tmp->mUserData, error); +        } +        delete tmp; +    }  }  BOOL LLAssetStorage::hasLocalAsset(const LLUUID &uuid, const LLAssetType::EType type)  { -	return mStaticVFS->getExists(uuid, type) || mVFS->getExists(uuid, type); +    return mStaticVFS->getExists(uuid, type) || mVFS->getExists(uuid, type);  }  bool LLAssetStorage::findInStaticVFSAndInvokeCallback(const LLUUID& uuid, LLAssetType::EType type, -													  LLGetAssetCallback callback, void *user_data) -{ -	if (user_data) -	{ -		// The *user_data should not be passed without a callback to clean it up. -		llassert(callback != NULL); -	} - -	BOOL exists = mStaticVFS->getExists(uuid, type); -	if (exists) -	{ -		LLVFile file(mStaticVFS, uuid, type); -		U32 size = file.getSize(); -		if (size > 0) -		{ -			// we've already got the file -			if (callback) -			{ -				callback(mStaticVFS, uuid, type, user_data, LL_ERR_NOERR, LL_EXSTAT_VFS_CACHED); -			} -			return true; -		} -		else -		{ -			LL_WARNS() << "Asset vfile " << uuid << ":" << type -					<< " found in static cache with bad size " << file.getSize() << ", ignoring" << LL_ENDL; -		} -	} -	return false; +                                                      LLGetAssetCallback callback, void *user_data) +{ +    if (user_data) +    { +        // The *user_data should not be passed without a callback to clean it up. +        llassert(callback != NULL); +    } + +    BOOL exists = mStaticVFS->getExists(uuid, type); +    if (exists) +    { +        LLVFile file(mStaticVFS, uuid, type); +        U32 size = file.getSize(); +        if (size > 0) +        { +            // we've already got the file +            if (callback) +            { +                callback(mStaticVFS, uuid, type, user_data, LL_ERR_NOERR, LL_EXSTAT_VFS_CACHED); +            } +            return true; +        } +        else +        { +            LL_WARNS("AssetStorage") << "Asset vfile " << uuid << ":" << type +                                     << " found in static cache with bad size " << file.getSize() << ", ignoring" << LL_ENDL; +        } +    } +    return false;  }  /////////////////////////////////////////////////////////////////////////// @@ -452,526 +447,506 @@ bool LLAssetStorage::findInStaticVFSAndInvokeCallback(const LLUUID& uuid, LLAsse  ///////////////////////////////////////////////////////////////////////////  // IW - uuid is passed by value to avoid side effects, please don't re-add &     -void LLAssetStorage::getAssetData(const LLUUID uuid, LLAssetType::EType type, LLGetAssetCallback callback, void *user_data, BOOL is_priority) -{ -	LL_DEBUGS("AssetStorage") << "LLAssetStorage::getAssetData() - " << uuid << "," << LLAssetType::lookup(type) << LL_ENDL; - -	LL_DEBUGS("AssetStorage") << "ASSET_TRACE requesting " << uuid << " type " << LLAssetType::lookup(type) << LL_ENDL; - -	if (user_data) -	{ -		// The *user_data should not be passed without a callback to clean it up. -		llassert(callback != NULL); -	} - -	if (mShutDown) -	{ -		LL_DEBUGS("AssetStorage") << "ASSET_TRACE cancelled " << uuid << " type " << LLAssetType::lookup(type) << " shutting down" << LL_ENDL; - -		if (callback) -		{ -			add(sFailedDownloadCount, 1); -			callback(mVFS, uuid, type, user_data, LL_ERR_ASSET_REQUEST_FAILED, LL_EXSTAT_NONE); -		} -		return; -	} - -	if (uuid.isNull()) -	{ -		// Special case early out for NULL uuid and for shutting down -		if (callback) -		{ -			add(sFailedDownloadCount, 1); -			callback(mVFS, uuid, type, user_data, LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE, LL_EXSTAT_NULL_UUID); -		} -		return; -	} - -	// Try static VFS first. -	if (findInStaticVFSAndInvokeCallback(uuid,type,callback,user_data)) -	{ -		LL_DEBUGS("AssetStorage") << "ASSET_TRACE asset " << uuid << " found in static VFS" << LL_ENDL; -		return; -	} - -	BOOL exists = mVFS->getExists(uuid, type); -	LLVFile file(mVFS, uuid, type); -	U32 size = exists ? file.getSize() : 0; -	 -	if (size > 0) -	{ -		// we've already got the file -		// theoretically, partial files w/o a pending request shouldn't happen -		// unless there's a weird error -		if (callback) -		{ -			callback(mVFS, uuid, type, user_data, LL_ERR_NOERR, LL_EXSTAT_VFS_CACHED); -		} - -		LL_DEBUGS("AssetStorage") << "ASSET_TRACE asset " << uuid << " found in VFS" << LL_ENDL; -	} -	else -	{ -		if (exists) -		{ -			LL_WARNS() << "Asset vfile " << uuid << ":" << type << " found with bad size " << file.getSize() << ", removing" << LL_ENDL; -			file.remove(); -		} -		 -		BOOL duplicate = FALSE; -		 -		// check to see if there's a pending download of this uuid already -		for (request_list_t::iterator iter = mPendingDownloads.begin(); -			 iter != mPendingDownloads.end(); ++iter ) -		{ -			LLAssetRequest  *tmp = *iter; -			if ((type == tmp->getType()) && (uuid == tmp->getUUID())) -			{ -				if (callback == tmp->mDownCallback && user_data == tmp->mUserData) -				{ -					// this is a duplicate from the same subsystem - throw it away -					LL_WARNS() << "Discarding duplicate request for asset " << uuid -							<< "." << LLAssetType::lookup(type) << LL_ENDL; -					return; -				} -				 -				// this is a duplicate request -				// queue the request, but don't actually ask for it again -				duplicate = TRUE; -			} -		} -		if (duplicate) -		{ -			LL_DEBUGS("AssetStorage") << "Adding additional non-duplicate request for asset " << uuid  -					<< "." << LLAssetType::lookup(type) << LL_ENDL; -		} -		 -		// This can be overridden by subclasses -		_queueDataRequest(uuid, type, callback, user_data, duplicate, is_priority);	 -	} - +void LLAssetStorage::getAssetData(const LLUUID uuid, +                                  LLAssetType::EType type,  +                                  LLGetAssetCallback callback,  +                                  void *user_data,  +                                  BOOL is_priority) +{ +    LL_DEBUGS("AssetStorage") << "LLAssetStorage::getAssetData() - " << uuid << "," << LLAssetType::lookup(type) << LL_ENDL; + +    LL_DEBUGS("AssetStorage") << "ASSET_TRACE requesting " << uuid << " type " << LLAssetType::lookup(type) << LL_ENDL; + +    if (user_data) +    { +        // The *user_data should not be passed without a callback to clean it up. +        llassert(callback != NULL); +    } + +    if (mShutDown) +    { +        LL_DEBUGS("AssetStorage") << "ASSET_TRACE cancelled " << uuid << " type " << LLAssetType::lookup(type) << " shutting down" << LL_ENDL; + +        if (callback) +        { +            add(sFailedDownloadCount, 1); +            callback(mVFS, uuid, type, user_data, LL_ERR_ASSET_REQUEST_FAILED, LL_EXSTAT_NONE); +        } +        return; +    } + +    if (uuid.isNull()) +    { +        // Special case early out for NULL uuid and for shutting down +        if (callback) +        { +            add(sFailedDownloadCount, 1); +            callback(mVFS, uuid, type, user_data, LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE, LL_EXSTAT_NULL_UUID); +        } +        return; +    } + +    // Try static VFS first. +    if (findInStaticVFSAndInvokeCallback(uuid,type,callback,user_data)) +    { +        LL_DEBUGS("AssetStorage") << "ASSET_TRACE asset " << uuid << " found in static VFS" << LL_ENDL; +        return; +    } + +    BOOL exists = mVFS->getExists(uuid, type); +    LLVFile file(mVFS, uuid, type); +    U32 size = exists ? file.getSize() : 0; +     +    if (size > 0) +    { +        // we've already got the file +        // theoretically, partial files w/o a pending request shouldn't happen +        // unless there's a weird error +        if (callback) +        { +            callback(mVFS, uuid, type, user_data, LL_ERR_NOERR, LL_EXSTAT_VFS_CACHED); +        } + +        LL_DEBUGS("AssetStorage") << "ASSET_TRACE asset " << uuid << " found in VFS" << LL_ENDL; +    } +    else +    { +        if (exists) +        { +            LL_WARNS("AssetStorage") << "Asset vfile " << uuid << ":" << type << " found with bad size " << file.getSize() << ", removing" << LL_ENDL; +            file.remove(); +        } +         +        BOOL duplicate = FALSE; +         +        // check to see if there's a pending download of this uuid already +        for (request_list_t::iterator iter = mPendingDownloads.begin(); +             iter != mPendingDownloads.end(); ++iter ) +        { +            LLAssetRequest  *tmp = *iter; +            if ((type == tmp->getType()) && (uuid == tmp->getUUID())) +            { +                if (callback == tmp->mDownCallback && user_data == tmp->mUserData) +                { +                    // this is a duplicate from the same subsystem - throw it away +                    LL_WARNS("AssetStorage") << "Discarding duplicate request for asset " << uuid +                                             << "." << LLAssetType::lookup(type) << LL_ENDL; +                    return; +                } +                 +                // this is a duplicate request +                // queue the request, but don't actually ask for it again +                duplicate = TRUE; +            } +        } +        if (duplicate) +        { +            LL_DEBUGS("AssetStorage") << "Adding additional non-duplicate request for asset " << uuid  +                                      << "." << LLAssetType::lookup(type) << LL_ENDL; +        } +         +        _queueDataRequest(uuid, type, callback, user_data, duplicate, is_priority);      +    }  } -// -// *NOTE:  Logic here is replicated in LLViewerAssetStorage::_queueDataRequest. -// Changes here may need to be replicated in the viewer's derived class. -// -void LLAssetStorage::_queueDataRequest(const LLUUID& uuid, LLAssetType::EType atype, -									   LLGetAssetCallback callback, -									   void *user_data, BOOL duplicate, -									   BOOL is_priority) -{ -	if (mUpstreamHost.isOk()) -	{ -		// stash the callback info so we can find it after we get the response message -		LLAssetRequest *req = new LLAssetRequest(uuid, atype); -		req->mDownCallback = callback; -		req->mUserData = user_data; -		req->mIsPriority = is_priority; -	 -		mPendingDownloads.push_back(req); -	 -		if (!duplicate) -		{ -			// send request message to our upstream data provider -			// Create a new asset transfer. -			LLTransferSourceParamsAsset spa; -			spa.setAsset(uuid, atype); - -			// Set our destination file, and the completion callback. -			LLTransferTargetParamsVFile tpvf; -			tpvf.setAsset(uuid, atype); -			tpvf.setCallback(downloadCompleteCallback, *req); - -			//LL_INFOS() << "Starting transfer for " << uuid << LL_ENDL; -			LLTransferTargetChannel *ttcp = gTransferManager.getTargetChannel(mUpstreamHost, LLTCT_ASSET); -			ttcp->requestTransfer(spa, tpvf, 100.f + (is_priority ? 1.f : 0.f)); -		} -	} -	else -	{ -		// uh-oh, we shouldn't have gotten here -		LL_WARNS() << "Attempt to move asset data request upstream w/o valid upstream provider" << LL_ENDL; -		if (callback) -		{ -			add(sFailedDownloadCount, 1); -			callback(mVFS, uuid, atype, user_data, LL_ERR_CIRCUIT_GONE, LL_EXSTAT_NO_UPSTREAM); -		} -	} +// static +void LLAssetStorage::removeAndCallbackPendingDownloads(const LLUUID& file_id, LLAssetType::EType file_type, +                                                       const LLUUID& callback_id, LLAssetType::EType callback_type, +                                                       S32 result_code, LLExtStat ext_status) +{ +    // find and callback ALL pending requests for this UUID +    // SJB: We process the callbacks in reverse order, I do not know if this is important, +    //      but I didn't want to mess with it. +    request_list_t requests; +    for (request_list_t::iterator iter = gAssetStorage->mPendingDownloads.begin(); +         iter != gAssetStorage->mPendingDownloads.end();  ) +    { +        request_list_t::iterator curiter = iter++; +        LLAssetRequest* tmp = *curiter; +        if ((tmp->getUUID() == file_id) && (tmp->getType()== file_type)) +        { +            requests.push_front(tmp); +            iter = gAssetStorage->mPendingDownloads.erase(curiter); +        } +    } +    for (request_list_t::iterator iter = requests.begin(); +         iter != requests.end();  ) +    { +        request_list_t::iterator curiter = iter++; +        LLAssetRequest* tmp = *curiter; +        if (tmp->mDownCallback) +        { +            if (result_code!= LL_ERR_NOERR) +            { +                add(sFailedDownloadCount, 1); +            } +            tmp->mDownCallback(gAssetStorage->mVFS, callback_id, callback_type, tmp->mUserData, result_code, ext_status); +        } +        delete tmp; +    }  } -  void LLAssetStorage::downloadCompleteCallback( -	S32 result, -	const LLUUID& file_id, -	LLAssetType::EType file_type, -	LLBaseDownloadRequest* user_data, LLExtStat ext_status) -{ -	LL_DEBUGS("AssetStorage") << "ASSET_TRACE asset " << file_id << " downloadCompleteCallback" << LL_ENDL; - -	LL_DEBUGS("AssetStorage") << "LLAssetStorage::downloadCompleteCallback() for " << file_id -		 << "," << LLAssetType::lookup(file_type) << LL_ENDL; -	LLAssetRequest* req = (LLAssetRequest*)user_data; -	if(!req) -	{ -		LL_WARNS() << "LLAssetStorage::downloadCompleteCallback called without" -			"a valid request." << LL_ENDL; -		return; -	} -	if (!gAssetStorage) -	{ -		LL_WARNS() << "LLAssetStorage::downloadCompleteCallback called without any asset system, aborting!" << LL_ENDL; -		return; -	} - -	LLUUID callback_id; -	LLAssetType::EType callback_type; - -	// Inefficient since we're doing a find through a list that may have thousands of elements. -	// This is due for refactoring; we will probably change mPendingDownloads into a set. -	request_list_t::iterator download_iter = std::find(gAssetStorage->mPendingDownloads.begin(),  -													   gAssetStorage->mPendingDownloads.end(), -													   req); - -	if (download_iter != gAssetStorage->mPendingDownloads.end()) -	{ -		callback_id = file_id; -		callback_type = file_type; -	} -	else -	{ -		// either has already been deleted by _cleanupRequests or it's a transfer. -		callback_id = req->getUUID(); -		callback_type = req->getType(); -	} - -	if (LL_ERR_NOERR == result) -	{ -		// we might have gotten a zero-size file -		LLVFile vfile(gAssetStorage->mVFS, callback_id, callback_type); -		if (vfile.getSize() <= 0) -		{ -			LL_WARNS() << "downloadCompleteCallback has non-existent or zero-size asset " << callback_id << LL_ENDL; -			 -			result = LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE; -			vfile.remove(); -		} -	} - -	// find and callback ALL pending requests for this UUID -	// SJB: We process the callbacks in reverse order, I do not know if this is important, -	//      but I didn't want to mess with it. -	request_list_t requests; -	for (request_list_t::iterator iter = gAssetStorage->mPendingDownloads.begin(); -		 iter != gAssetStorage->mPendingDownloads.end();  ) -	{ -		request_list_t::iterator curiter = iter++; -		LLAssetRequest* tmp = *curiter; -		if ((tmp->getUUID() == file_id) && (tmp->getType()== file_type)) -		{ -			requests.push_front(tmp); -			iter = gAssetStorage->mPendingDownloads.erase(curiter); -		} -	} -	for (request_list_t::iterator iter = requests.begin(); -		 iter != requests.end();  ) -	{ -		request_list_t::iterator curiter = iter++; -		LLAssetRequest* tmp = *curiter; -		if (tmp->mDownCallback) -		{ -			if (result != LL_ERR_NOERR) -			{ -				add(sFailedDownloadCount, 1); -			} -			tmp->mDownCallback(gAssetStorage->mVFS, callback_id, callback_type, tmp->mUserData, result, ext_status); -		} -		delete tmp; -	} -} - -void LLAssetStorage::getEstateAsset(const LLHost &object_sim, const LLUUID &agent_id, const LLUUID &session_id, -									const LLUUID &asset_id, LLAssetType::EType atype, EstateAssetType etype, -									 LLGetAssetCallback callback, void *user_data, BOOL is_priority) -{ -	LL_DEBUGS() << "LLAssetStorage::getEstateAsset() - " << asset_id << "," << LLAssetType::lookup(atype) << ", estatetype " << etype << LL_ENDL; - -	// -	// Probably will get rid of this early out? -	// -	if (asset_id.isNull()) -	{ -		// Special case early out for NULL uuid -		if (callback) -		{ -			add(sFailedDownloadCount, 1); -			callback(mVFS, asset_id, atype, user_data, LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE, LL_EXSTAT_NULL_UUID); -		} -		return; -	} - -	// Try static VFS first. -	if (findInStaticVFSAndInvokeCallback(asset_id,atype,callback,user_data)) -	{ -		return; -	} -	 -	BOOL exists = mVFS->getExists(asset_id, atype); -	LLVFile file(mVFS, asset_id, atype); -	U32 size = exists ? file.getSize() : 0; - -	if (size > 0) -	{ -		// we've already got the file -		// theoretically, partial files w/o a pending request shouldn't happen -		// unless there's a weird error -		if (callback) -		{ -			callback(mVFS, asset_id, atype, user_data, LL_ERR_NOERR, LL_EXSTAT_VFS_CACHED); -		} -	} -	else -	{ -		if (exists) -		{ -			LL_WARNS() << "Asset vfile " << asset_id << ":" << atype << " found with bad size " << file.getSize() << ", removing" << LL_ENDL; -			file.remove(); -		} - -		// See whether we should talk to the object's originating sim, or the upstream provider. -		LLHost source_host; -		if (object_sim.isOk()) -		{ -			source_host = object_sim; -		} -		else -		{ -			source_host = mUpstreamHost; -		} -		if (source_host.isOk()) -		{ -			// stash the callback info so we can find it after we get the response message -			LLEstateAssetRequest req(asset_id, atype, etype); -			req.mDownCallback = callback; -			req.mUserData = user_data; -			req.mIsPriority = is_priority; - -			// send request message to our upstream data provider -			// Create a new asset transfer. -			LLTransferSourceParamsEstate spe; -			spe.setAgentSession(agent_id, session_id); -			spe.setEstateAssetType(etype); - -			// Set our destination file, and the completion callback. -			LLTransferTargetParamsVFile tpvf; -			tpvf.setAsset(asset_id, atype); -			tpvf.setCallback(downloadEstateAssetCompleteCallback, req); - -			LL_DEBUGS("AssetStorage") << "Starting transfer for " << asset_id << LL_ENDL; -			LLTransferTargetChannel *ttcp = gTransferManager.getTargetChannel(source_host, LLTCT_ASSET); -			ttcp->requestTransfer(spe, tpvf, 100.f + (is_priority ? 1.f : 0.f)); -		} -		else -		{ -			// uh-oh, we shouldn't have gotten here -			LL_WARNS() << "Attempt to move asset data request upstream w/o valid upstream provider" << LL_ENDL; -			if (callback) -			{ -				add(sFailedDownloadCount, 1); -				callback(mVFS, asset_id, atype, user_data, LL_ERR_CIRCUIT_GONE, LL_EXSTAT_NO_UPSTREAM); -			} -		} -	} +    S32 result, +    const LLUUID& file_id, +    LLAssetType::EType file_type, +    LLBaseDownloadRequest* user_data, +    LLExtStat ext_status) +{ +    LL_DEBUGS("AssetStorage") << "ASSET_TRACE asset " << file_id << " downloadCompleteCallback" << LL_ENDL; + +    LL_DEBUGS("AssetStorage") << "LLAssetStorage::downloadCompleteCallback() for " << file_id +                              << "," << LLAssetType::lookup(file_type) << LL_ENDL; +    LLAssetRequest* req = (LLAssetRequest*)user_data; +    if(!req) +    { +        LL_WARNS("AssetStorage") << "LLAssetStorage::downloadCompleteCallback called without" +            "a valid request." << LL_ENDL; +        return; +    } +    if (!gAssetStorage) +    { +        LL_WARNS("AssetStorage") << "LLAssetStorage::downloadCompleteCallback called without any asset system, aborting!" << LL_ENDL; +        return; +    } + +    LLUUID callback_id; +    LLAssetType::EType callback_type; + +    // Inefficient since we're doing a find through a list that may have thousands of elements. +    // This is due for refactoring; we will probably change mPendingDownloads into a set. +    request_list_t::iterator download_iter = std::find(gAssetStorage->mPendingDownloads.begin(),  +                                                       gAssetStorage->mPendingDownloads.end(), +                                                       req); + +    if (download_iter != gAssetStorage->mPendingDownloads.end()) +    { +        callback_id = file_id; +        callback_type = file_type; +    } +    else +    { +        // either has already been deleted by _cleanupRequests or it's a transfer. +        callback_id = req->getUUID(); +        callback_type = req->getType(); +    } + +    if (LL_ERR_NOERR == result) +    { +        // we might have gotten a zero-size file +        LLVFile vfile(gAssetStorage->mVFS, callback_id, callback_type); +        if (vfile.getSize() <= 0) +        { +            LL_WARNS("AssetStorage") << "downloadCompleteCallback has non-existent or zero-size asset " << callback_id << LL_ENDL; +             +            result = LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE; +            vfile.remove(); +        } +        else +        { +#if 1 +            for (request_list_t::iterator iter = gAssetStorage->mPendingDownloads.begin(); +                 iter != gAssetStorage->mPendingDownloads.end(); ++iter  ) +            { +                LLAssetRequest* dlreq = *iter; +                if ((dlreq->getUUID() == file_id) && (dlreq->getType()== file_type)) +                { +                    dlreq->mBytesFetched = vfile.getSize(); +                } +            } +#endif +        } +    } + +    removeAndCallbackPendingDownloads(file_id, file_type, callback_id, callback_type, ext_status, result); +} + +void LLAssetStorage::getEstateAsset( +    const LLHost &object_sim, +    const LLUUID &agent_id,  +    const LLUUID &session_id, +    const LLUUID &asset_id,  +    LLAssetType::EType atype,  +    EstateAssetType etype, +    LLGetAssetCallback callback,  +    void *user_data,  +    BOOL is_priority) +{ +    LL_DEBUGS() << "LLAssetStorage::getEstateAsset() - " << asset_id << "," << LLAssetType::lookup(atype) << ", estatetype " << etype << LL_ENDL; + +    // +    // Probably will get rid of this early out? +    // +    if (asset_id.isNull()) +    { +        // Special case early out for NULL uuid +        if (callback) +        { +            add(sFailedDownloadCount, 1); +            callback(mVFS, asset_id, atype, user_data, LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE, LL_EXSTAT_NULL_UUID); +        } +        return; +    } + +    // Try static VFS first. +    if (findInStaticVFSAndInvokeCallback(asset_id,atype,callback,user_data)) +    { +        return; +    } +     +    BOOL exists = mVFS->getExists(asset_id, atype); +    LLVFile file(mVFS, asset_id, atype); +    U32 size = exists ? file.getSize() : 0; + +    if (size > 0) +    { +        // we've already got the file +        // theoretically, partial files w/o a pending request shouldn't happen +        // unless there's a weird error +        if (callback) +        { +            callback(mVFS, asset_id, atype, user_data, LL_ERR_NOERR, LL_EXSTAT_VFS_CACHED); +        } +    } +    else +    { +        if (exists) +        { +            LL_WARNS("AssetStorage") << "Asset vfile " << asset_id << ":" << atype << " found with bad size " << file.getSize() << ", removing" << LL_ENDL; +            file.remove(); +        } + +        // See whether we should talk to the object's originating sim, or the upstream provider. +        LLHost source_host; +        if (object_sim.isOk()) +        { +            source_host = object_sim; +        } +        else +        { +            source_host = mUpstreamHost; +        } +        if (source_host.isOk()) +        { +            // stash the callback info so we can find it after we get the response message +            LLEstateAssetRequest req(asset_id, atype, etype); +            req.mDownCallback = callback; +            req.mUserData = user_data; +            req.mIsPriority = is_priority; + +            // send request message to our upstream data provider +            // Create a new asset transfer. +            LLTransferSourceParamsEstate spe; +            spe.setAgentSession(agent_id, session_id); +            spe.setEstateAssetType(etype); + +            // Set our destination file, and the completion callback. +            LLTransferTargetParamsVFile tpvf; +            tpvf.setAsset(asset_id, atype); +            tpvf.setCallback(downloadEstateAssetCompleteCallback, req); + +            LL_DEBUGS("AssetStorage") << "Starting transfer for " << asset_id << LL_ENDL; +            LLTransferTargetChannel *ttcp = gTransferManager.getTargetChannel(source_host, LLTCT_ASSET); +            ttcp->requestTransfer(spe, tpvf, 100.f + (is_priority ? 1.f : 0.f)); +        } +        else +        { +            // uh-oh, we shouldn't have gotten here +            LL_WARNS("AssetStorage") << "Attempt to move asset data request upstream w/o valid upstream provider" << LL_ENDL; +            if (callback) +            { +                add(sFailedDownloadCount, 1); +                callback(mVFS, asset_id, atype, user_data, LL_ERR_CIRCUIT_GONE, LL_EXSTAT_NO_UPSTREAM); +            } +        } +    }  }  void LLAssetStorage::downloadEstateAssetCompleteCallback( -	S32 result, -	const LLUUID& file_id, -	LLAssetType::EType file_type, -	LLBaseDownloadRequest* user_data, -	LLExtStat ext_status) -{ -	LLEstateAssetRequest *req = (LLEstateAssetRequest*)user_data; -	if(!req) -	{ -		LL_WARNS() << "LLAssetStorage::downloadEstateAssetCompleteCallback called" -			" without a valid request." << LL_ENDL; -		return; -	} -	if (!gAssetStorage) -	{ -		LL_WARNS() << "LLAssetStorage::downloadEstateAssetCompleteCallback called" -			" without any asset system, aborting!" << LL_ENDL; -		return; -	} - -	req->setUUID(file_id); -	req->setType(file_type); -	if (LL_ERR_NOERR == result) -	{ -		// we might have gotten a zero-size file -		LLVFile vfile(gAssetStorage->mVFS, req->getUUID(), req->getAType()); -		if (vfile.getSize() <= 0) -		{ -			LL_WARNS() << "downloadCompleteCallback has non-existent or zero-size asset!" << LL_ENDL; - -			result = LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE; -			vfile.remove(); -		} -	} - -	if (result != LL_ERR_NOERR) -	{ -		add(sFailedDownloadCount, 1); -	} -	req->mDownCallback(gAssetStorage->mVFS, req->getUUID(), req->getAType(), req->mUserData, result, ext_status); -} - -void LLAssetStorage::getInvItemAsset(const LLHost &object_sim, const LLUUID &agent_id, const LLUUID &session_id, -									 const LLUUID &owner_id, const LLUUID &task_id, const LLUUID &item_id, -									 const LLUUID &asset_id, LLAssetType::EType atype, -									 LLGetAssetCallback callback, void *user_data, BOOL is_priority) -{ -	LL_DEBUGS() << "LLAssetStorage::getInvItemAsset() - " << asset_id << "," << LLAssetType::lookup(atype) << LL_ENDL; - -	// -	// Probably will get rid of this early out? -	// -	//if (asset_id.isNull()) -	//{ -	//	// Special case early out for NULL uuid -	//	if (callback) -	//	{ -	//		callback(mVFS, asset_id, atype, user_data, LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE); -	//	} -	//	return; -	//} - -	bool exists = false;  -	U32 size = 0; - -	if(asset_id.notNull()) -	{ -		// Try static VFS first. -		if (findInStaticVFSAndInvokeCallback( asset_id, atype, callback, user_data)) -		{ -			return; -		} - -		exists = mVFS->getExists(asset_id, atype); -		LLVFile file(mVFS, asset_id, atype); -		size = exists ? file.getSize() : 0; -		if(exists && size < 1) -		{ -			LL_WARNS() << "Asset vfile " << asset_id << ":" << atype << " found with bad size " << file.getSize() << ", removing" << LL_ENDL; -			file.remove(); -		} - -	} - -	if (size > 0) -	{ -		// we've already got the file -		// theoretically, partial files w/o a pending request shouldn't happen -		// unless there's a weird error -		if (callback) -		{ -			callback(mVFS, asset_id, atype, user_data, LL_ERR_NOERR, LL_EXSTAT_VFS_CACHED); -		} -	} -	else -	{ -		// See whether we should talk to the object's originating sim, -		// or the upstream provider. -		LLHost source_host; -		if (object_sim.isOk()) -		{ -			source_host = object_sim; -		} -		else -		{ -			source_host = mUpstreamHost; -		} -		if (source_host.isOk()) -		{ -			// stash the callback info so we can find it after we get the response message -			LLInvItemRequest req(asset_id, atype); -			req.mDownCallback = callback; -			req.mUserData = user_data; -			req.mIsPriority = is_priority; - -			// send request message to our upstream data provider -			// Create a new asset transfer. -			LLTransferSourceParamsInvItem spi; -			spi.setAgentSession(agent_id, session_id); -			spi.setInvItem(owner_id, task_id, item_id); -			spi.setAsset(asset_id, atype); - -			// Set our destination file, and the completion callback. -			LLTransferTargetParamsVFile tpvf; -			tpvf.setAsset(asset_id, atype); -			tpvf.setCallback(downloadInvItemCompleteCallback, req); - -			LL_DEBUGS("AssetStorage") << "Starting transfer for inventory asset " -				<< item_id << " owned by " << owner_id << "," << task_id -				<< LL_ENDL; -			LLTransferTargetChannel *ttcp = gTransferManager.getTargetChannel(source_host, LLTCT_ASSET); -			ttcp->requestTransfer(spi, tpvf, 100.f + (is_priority ? 1.f : 0.f)); -		} -		else -		{ -			// uh-oh, we shouldn't have gotten here -			LL_WARNS() << "Attempt to move asset data request upstream w/o valid upstream provider" << LL_ENDL; -			if (callback) -			{ -				add(sFailedDownloadCount, 1); -				callback(mVFS, asset_id, atype, user_data, LL_ERR_CIRCUIT_GONE, LL_EXSTAT_NO_UPSTREAM); -			} -		} -	} +    S32 result, +    const LLUUID& file_id, +    LLAssetType::EType file_type, +    LLBaseDownloadRequest* user_data, +    LLExtStat ext_status) +{ +    LLEstateAssetRequest *req = (LLEstateAssetRequest*)user_data; +    if(!req) +    { +        LL_WARNS("AssetStorage") << "LLAssetStorage::downloadEstateAssetCompleteCallback called" +            " without a valid request." << LL_ENDL; +        return; +    } +    if (!gAssetStorage) +    { +        LL_WARNS("AssetStorage") << "LLAssetStorage::downloadEstateAssetCompleteCallback called" +            " without any asset system, aborting!" << LL_ENDL; +        return; +    } + +    req->setUUID(file_id); +    req->setType(file_type); +    if (LL_ERR_NOERR == result) +    { +        // we might have gotten a zero-size file +        LLVFile vfile(gAssetStorage->mVFS, req->getUUID(), req->getAType()); +        if (vfile.getSize() <= 0) +        { +            LL_WARNS("AssetStorage") << "downloadCompleteCallback has non-existent or zero-size asset!" << LL_ENDL; + +            result = LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE; +            vfile.remove(); +        } +    } + +    if (result != LL_ERR_NOERR) +    { +        add(sFailedDownloadCount, 1); +    } +    req->mDownCallback(gAssetStorage->mVFS, req->getUUID(), req->getAType(), req->mUserData, result, ext_status); +} + +void LLAssetStorage::getInvItemAsset( +    const LLHost &object_sim,  +    const LLUUID &agent_id,  +    const LLUUID &session_id, +    const LLUUID &owner_id, +    const LLUUID &task_id,  +    const LLUUID &item_id, +    const LLUUID &asset_id,  +    LLAssetType::EType atype, +    LLGetAssetCallback callback,  +    void *user_data,  +    BOOL is_priority) +{ +    LL_DEBUGS() << "LLAssetStorage::getInvItemAsset() - " << asset_id << "," << LLAssetType::lookup(atype) << LL_ENDL; + +    bool exists = false;  +    U32 size = 0; + +    if(asset_id.notNull()) +    { +        // Try static VFS first. +        if (findInStaticVFSAndInvokeCallback( asset_id, atype, callback, user_data)) +        { +            return; +        } + +        exists = mVFS->getExists(asset_id, atype); +        LLVFile file(mVFS, asset_id, atype); +        size = exists ? file.getSize() : 0; +        if(exists && size < 1) +        { +            LL_WARNS("AssetStorage") << "Asset vfile " << asset_id << ":" << atype << " found with bad size " << file.getSize() << ", removing" << LL_ENDL; +            file.remove(); +        } + +    } + +    if (size > 0) +    { +        // we've already got the file +        // theoretically, partial files w/o a pending request shouldn't happen +        // unless there's a weird error +        if (callback) +        { +            callback(mVFS, asset_id, atype, user_data, LL_ERR_NOERR, LL_EXSTAT_VFS_CACHED); +        } +    } +    else +    { +        // See whether we should talk to the object's originating sim, +        // or the upstream provider. +        LLHost source_host; +        if (object_sim.isOk()) +        { +            source_host = object_sim; +        } +        else +        { +            source_host = mUpstreamHost; +        } +        if (source_host.isOk()) +        { +            // stash the callback info so we can find it after we get the response message +            LLInvItemRequest req(asset_id, atype); +            req.mDownCallback = callback; +            req.mUserData = user_data; +            req.mIsPriority = is_priority; + +            // send request message to our upstream data provider +            // Create a new asset transfer. +            LLTransferSourceParamsInvItem spi; +            spi.setAgentSession(agent_id, session_id); +            spi.setInvItem(owner_id, task_id, item_id); +            spi.setAsset(asset_id, atype); + +            LL_DEBUGS("ViewerAsset") << "requesting inv item id " << item_id << " asset_id " << asset_id << " type " << LLAssetType::lookup(atype) << LL_ENDL; +             +            // Set our destination file, and the completion callback. +            LLTransferTargetParamsVFile tpvf; +            tpvf.setAsset(asset_id, atype); +            tpvf.setCallback(downloadInvItemCompleteCallback, req); + +            LL_DEBUGS("AssetStorage") << "Starting transfer for inventory asset " +                                      << item_id << " owned by " << owner_id << "," << task_id +                                      << LL_ENDL; +            LLTransferTargetChannel *ttcp = gTransferManager.getTargetChannel(source_host, LLTCT_ASSET); +            ttcp->requestTransfer(spi, tpvf, 100.f + (is_priority ? 1.f : 0.f)); +        } +        else +        { +            // uh-oh, we shouldn't have gotten here +            LL_WARNS("AssetStorage") << "Attempt to move asset data request upstream w/o valid upstream provider" << LL_ENDL; +            if (callback) +            { +                add(sFailedDownloadCount, 1); +                callback(mVFS, asset_id, atype, user_data, LL_ERR_CIRCUIT_GONE, LL_EXSTAT_NO_UPSTREAM); +            } +        } +    }  }  void LLAssetStorage::downloadInvItemCompleteCallback( -	S32 result, -	const LLUUID& file_id, -	LLAssetType::EType file_type, -	LLBaseDownloadRequest* user_data, -	LLExtStat ext_status) -{ -	LLInvItemRequest *req = (LLInvItemRequest*)user_data; -	if(!req) -	{ -		LL_WARNS() << "LLAssetStorage::downloadEstateAssetCompleteCallback called" -			" without a valid request." << LL_ENDL; -		return; -	} -	if (!gAssetStorage) -	{ -		LL_WARNS() << "LLAssetStorage::downloadCompleteCallback called without any asset system, aborting!" << LL_ENDL; -		return; -	} - -	req->setUUID(file_id); -	req->setType(file_type); -	if (LL_ERR_NOERR == result) -	{ -		// we might have gotten a zero-size file -		LLVFile vfile(gAssetStorage->mVFS, req->getUUID(), req->getType()); -		if (vfile.getSize() <= 0) -		{ -			LL_WARNS() << "downloadCompleteCallback has non-existent or zero-size asset!" << LL_ENDL; - -			result = LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE; -			vfile.remove(); -		} -	} - -	if (result != LL_ERR_NOERR) -	{ -		add(sFailedDownloadCount, 1); -	} -	req->mDownCallback(gAssetStorage->mVFS, req->getUUID(), req->getType(), req->mUserData, result, ext_status); +    S32 result, +    const LLUUID& file_id, +    LLAssetType::EType file_type, +    LLBaseDownloadRequest* user_data, +    LLExtStat ext_status) +{ +    LLInvItemRequest *req = (LLInvItemRequest*)user_data; +    if(!req) +    { +        LL_WARNS("AssetStorage") << "LLAssetStorage::downloadEstateAssetCompleteCallback called" +            " without a valid request." << LL_ENDL; +        return; +    } +    if (!gAssetStorage) +    { +        LL_WARNS("AssetStorage") << "LLAssetStorage::downloadCompleteCallback called without any asset system, aborting!" << LL_ENDL; +        return; +    } + +    req->setUUID(file_id); +    req->setType(file_type); +    if (LL_ERR_NOERR == result) +    { +        // we might have gotten a zero-size file +        LLVFile vfile(gAssetStorage->mVFS, req->getUUID(), req->getType()); +        if (vfile.getSize() <= 0) +        { +            LL_WARNS("AssetStorage") << "downloadCompleteCallback has non-existent or zero-size asset!" << LL_ENDL; + +            result = LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE; +            vfile.remove(); +        } +    } + +    if (result != LL_ERR_NOERR) +    { +        add(sFailedDownloadCount, 1); +    } +    req->mDownCallback(gAssetStorage->mVFS, req->getUUID(), req->getType(), req->mUserData, result, ext_status);  }  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -979,654 +954,558 @@ void LLAssetStorage::downloadInvItemCompleteCallback(  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////  // static -void LLAssetStorage::uploadCompleteCallback(const LLUUID& uuid, void *user_data, S32 result, LLExtStat ext_status) // StoreAssetData callback (fixed) -{ -	if (!gAssetStorage) -	{ -		LL_WARNS() << "LLAssetStorage::uploadCompleteCallback has no gAssetStorage!" << LL_ENDL; -		return; -	} -	LLAssetRequest	*req	 = (LLAssetRequest *)user_data; -	BOOL			success  = TRUE; - -	if (result) -	{ -		LL_WARNS() << "LLAssetStorage::uploadCompleteCallback " << result << ":" << getErrorString(result) << " trying to upload file to upstream provider" << LL_ENDL; -		success = FALSE; -	} - -	// we're done grabbing the file, tell the client -	gAssetStorage->mMessageSys->newMessageFast(_PREHASH_AssetUploadComplete); -	gAssetStorage->mMessageSys->nextBlockFast(_PREHASH_AssetBlock); -	gAssetStorage->mMessageSys->addUUIDFast(_PREHASH_UUID, uuid); -	gAssetStorage->mMessageSys->addS8Fast(_PREHASH_Type, req->getType()); -	gAssetStorage->mMessageSys->addBOOLFast(_PREHASH_Success, success); -	gAssetStorage->mMessageSys->sendReliable(req->mHost); - -	delete req; +void LLAssetStorage::uploadCompleteCallback( +    const LLUUID& uuid,  +    void *user_data,  +    S32 result,  +    LLExtStat ext_status) // StoreAssetData callback (fixed) +{ +    if (!gAssetStorage) +    { +        LL_WARNS("AssetStorage") << "LLAssetStorage::uploadCompleteCallback has no gAssetStorage!" << LL_ENDL; +        return; +    } +    LLAssetRequest  *req     = (LLAssetRequest *)user_data; +    BOOL            success  = TRUE; + +    if (result) +    { +        LL_WARNS("AssetStorage") << "LLAssetStorage::uploadCompleteCallback " << result << ":" << getErrorString(result) << " trying to upload file to upstream provider" << LL_ENDL; +        success = FALSE; +    } + +    // we're done grabbing the file, tell the client +    gAssetStorage->mMessageSys->newMessageFast(_PREHASH_AssetUploadComplete); +    gAssetStorage->mMessageSys->nextBlockFast(_PREHASH_AssetBlock); +    gAssetStorage->mMessageSys->addUUIDFast(_PREHASH_UUID, uuid); +    gAssetStorage->mMessageSys->addS8Fast(_PREHASH_Type, req->getType()); +    gAssetStorage->mMessageSys->addBOOLFast(_PREHASH_Success, success); +    gAssetStorage->mMessageSys->sendReliable(req->mHost); + +    delete req;  }  void LLAssetStorage::processUploadComplete(LLMessageSystem *msg, void **user_data)  { -	LLAssetStorage	*this_ptr = (LLAssetStorage *)user_data; -	LLUUID			uuid; -	S8				asset_type_s8; -	LLAssetType::EType asset_type; -	BOOL			success = FALSE; - -	msg->getUUIDFast(_PREHASH_AssetBlock, _PREHASH_UUID, uuid); -	msg->getS8Fast(_PREHASH_AssetBlock, _PREHASH_Type, asset_type_s8); -	msg->getBOOLFast(_PREHASH_AssetBlock, _PREHASH_Success, success); - -	asset_type = (LLAssetType::EType)asset_type_s8; -	this_ptr->_callUploadCallbacks(uuid, asset_type, success, LL_EXSTAT_NONE); +    LLAssetStorage  *this_ptr = (LLAssetStorage *)user_data; +    LLUUID          uuid; +    S8              asset_type_s8; +    LLAssetType::EType asset_type; +    BOOL            success = FALSE; + +    msg->getUUIDFast(_PREHASH_AssetBlock, _PREHASH_UUID, uuid); +    msg->getS8Fast(_PREHASH_AssetBlock, _PREHASH_Type, asset_type_s8); +    msg->getBOOLFast(_PREHASH_AssetBlock, _PREHASH_Success, success); + +    asset_type = (LLAssetType::EType)asset_type_s8; +    this_ptr->_callUploadCallbacks(uuid, asset_type, success, LL_EXSTAT_NONE);  }  void LLAssetStorage::_callUploadCallbacks(const LLUUID &uuid, LLAssetType::EType asset_type, BOOL success, LLExtStat ext_status )  { -	// SJB: We process the callbacks in reverse order, I do not know if this is important, -	//      but I didn't want to mess with it. -	request_list_t requests; -	for (request_list_t::iterator iter = mPendingUploads.begin(); -		 iter != mPendingUploads.end();  ) -	{ -		request_list_t::iterator curiter = iter++; -		LLAssetRequest* req = *curiter; -		if ((req->getUUID() == uuid) && (req->getType() == asset_type)) -		{ -			requests.push_front(req); -			iter = mPendingUploads.erase(curiter); -		} -	} -	for (request_list_t::iterator iter = mPendingLocalUploads.begin(); -		 iter != mPendingLocalUploads.end();  ) -	{ -		request_list_t::iterator curiter = iter++; -		LLAssetRequest* req = *curiter; -		if ((req->getUUID() == uuid) && (req->getType() == asset_type)) -		{ -			requests.push_front(req); -			iter = mPendingLocalUploads.erase(curiter); -		} -	} -	for (request_list_t::iterator iter = requests.begin(); -		 iter != requests.end();  ) -	{ -		request_list_t::iterator curiter = iter++; -		LLAssetRequest* req = *curiter; -		if (req->mUpCallback) -		{ -			req->mUpCallback(uuid, req->mUserData, (success ?  LL_ERR_NOERR :  LL_ERR_ASSET_REQUEST_FAILED ), ext_status ); -		} -		delete req; -	} +    // SJB: We process the callbacks in reverse order, I do not know if this is important, +    //      but I didn't want to mess with it. +    request_list_t requests; +    for (request_list_t::iterator iter = mPendingUploads.begin(); +         iter != mPendingUploads.end();  ) +    { +        request_list_t::iterator curiter = iter++; +        LLAssetRequest* req = *curiter; +        if ((req->getUUID() == uuid) && (req->getType() == asset_type)) +        { +            requests.push_front(req); +            iter = mPendingUploads.erase(curiter); +        } +    } +    for (request_list_t::iterator iter = mPendingLocalUploads.begin(); +         iter != mPendingLocalUploads.end();  ) +    { +        request_list_t::iterator curiter = iter++; +        LLAssetRequest* req = *curiter; +        if ((req->getUUID() == uuid) && (req->getType() == asset_type)) +        { +            requests.push_front(req); +            iter = mPendingLocalUploads.erase(curiter); +        } +    } +    for (request_list_t::iterator iter = requests.begin(); +         iter != requests.end();  ) +    { +        request_list_t::iterator curiter = iter++; +        LLAssetRequest* req = *curiter; +        if (req->mUpCallback) +        { +            req->mUpCallback(uuid, req->mUserData, (success ?  LL_ERR_NOERR :  LL_ERR_ASSET_REQUEST_FAILED ), ext_status ); +        } +        delete req; +    }  }  LLAssetStorage::request_list_t* LLAssetStorage::getRequestList(LLAssetStorage::ERequestType rt)  { -	switch (rt) -	{ -	case RT_DOWNLOAD: -		return &mPendingDownloads; -	case RT_UPLOAD: -		return &mPendingUploads; -	case RT_LOCALUPLOAD: -		return &mPendingLocalUploads; -	default: -		LL_WARNS() << "Unable to find request list for request type '" << rt << "'" << LL_ENDL; -		return NULL; -	} +    switch (rt) +    { +        case RT_DOWNLOAD: +            return &mPendingDownloads; +        case RT_UPLOAD: +            return &mPendingUploads; +        case RT_LOCALUPLOAD: +            return &mPendingLocalUploads; +        default: +            LL_WARNS("AssetStorage") << "Unable to find request list for request type '" << rt << "'" << LL_ENDL; +            return NULL; +    }  }  const LLAssetStorage::request_list_t* LLAssetStorage::getRequestList(LLAssetStorage::ERequestType rt) const  { -	switch (rt) -	{ -	case RT_DOWNLOAD: -		return &mPendingDownloads; -	case RT_UPLOAD: -		return &mPendingUploads; -	case RT_LOCALUPLOAD: -		return &mPendingLocalUploads; -	default: -		LL_WARNS() << "Unable to find request list for request type '" << rt << "'" << LL_ENDL; -		return NULL; -	} +    switch (rt) +    { +        case RT_DOWNLOAD: +            return &mPendingDownloads; +        case RT_UPLOAD: +            return &mPendingUploads; +        case RT_LOCALUPLOAD: +            return &mPendingLocalUploads; +        default: +            LL_WARNS("AssetStorage") << "Unable to find request list for request type '" << rt << "'" << LL_ENDL; +            return NULL; +    }  }  // static  std::string LLAssetStorage::getRequestName(LLAssetStorage::ERequestType rt)  { -	switch (rt) -	{ -	case RT_DOWNLOAD: -		return "download"; -	case RT_UPLOAD: -		return "upload"; -	case RT_LOCALUPLOAD: -		return "localupload"; -	default: -		LL_WARNS() << "Unable to find request name for request type '" << rt << "'" << LL_ENDL; -		return ""; -	} +    switch (rt) +    { +        case RT_DOWNLOAD: +            return "download"; +        case RT_UPLOAD: +            return "upload"; +        case RT_LOCALUPLOAD: +            return "localupload"; +        default: +            LL_WARNS("AssetStorage") << "Unable to find request name for request type '" << rt << "'" << LL_ENDL; +            return ""; +    }  }  S32 LLAssetStorage::getNumPending(LLAssetStorage::ERequestType rt) const  { -	const request_list_t* requests = getRequestList(rt); -	S32 num_pending = -1; -	if (requests) -	{ -		num_pending = requests->size(); -	} -	return num_pending; +    const request_list_t* requests = getRequestList(rt); +    S32 num_pending = -1; +    if (requests) +    { +        num_pending = requests->size(); +    } +    return num_pending;  }  S32 LLAssetStorage::getNumPendingDownloads() const  { -	return getNumPending(RT_DOWNLOAD); +    return getNumPending(RT_DOWNLOAD);  }  S32 LLAssetStorage::getNumPendingUploads() const  { -	return getNumPending(RT_UPLOAD); +    return getNumPending(RT_UPLOAD);  }  S32 LLAssetStorage::getNumPendingLocalUploads()  { -	return getNumPending(RT_LOCALUPLOAD); +    return getNumPending(RT_LOCALUPLOAD);  } -// virtual  LLSD LLAssetStorage::getPendingDetails(LLAssetStorage::ERequestType rt, -										LLAssetType::EType asset_type, -										const std::string& detail_prefix) const +                                       LLAssetType::EType asset_type, +                                       const std::string& detail_prefix) const  { -	const request_list_t* requests = getRequestList(rt); -	LLSD sd; -	sd["requests"] = getPendingDetailsImpl(requests, asset_type, detail_prefix); -	return sd; +    const request_list_t* requests = getRequestList(rt); +    LLSD sd; +    sd["requests"] = getPendingDetailsImpl(requests, asset_type, detail_prefix); +    return sd;  } -// virtual  LLSD LLAssetStorage::getPendingDetailsImpl(const LLAssetStorage::request_list_t* requests, -										LLAssetType::EType asset_type, -										const std::string& detail_prefix) const -{ -	LLSD details; -	if (requests) -	{ -		request_list_t::const_iterator it = requests->begin(); -		request_list_t::const_iterator end = requests->end(); -		for ( ; it != end; ++it) -		{ -			LLAssetRequest* req = *it; -			if (   (LLAssetType::AT_NONE == asset_type) -				|| (req->getType() == asset_type) ) -			{ -				LLSD row = req->getTerseDetails(); - -				std::ostringstream detail; -				detail	<< detail_prefix << "/" << LLAssetType::lookup(req->getType()) -						<< "/" << req->getUUID(); -				row["detail"] = LLURI(detail.str()); - -				details.append(row); -			} -		} -	} -	return details; +                                           LLAssetType::EType asset_type, +                                           const std::string& detail_prefix) const +{ +    LLSD details; +    if (requests) +    { +        request_list_t::const_iterator it = requests->begin(); +        request_list_t::const_iterator end = requests->end(); +        for ( ; it != end; ++it) +        { +            LLAssetRequest* req = *it; +            if (   (LLAssetType::AT_NONE == asset_type) +                   || (req->getType() == asset_type) ) +            { +                LLSD row = req->getTerseDetails(); + +                std::ostringstream detail; +                detail  << detail_prefix << "/" << LLAssetType::lookup(req->getType()) +                        << "/" << req->getUUID(); +                row["detail"] = LLURI(detail.str()); + +                details.append(row); +            } +        } +    } +    return details;  }  // static  const LLAssetRequest* LLAssetStorage::findRequest(const LLAssetStorage::request_list_t* requests, -										LLAssetType::EType asset_type, -										const LLUUID& asset_id) -{ -	if (requests)  -	{ -		// Search the requests list for the asset. -		request_list_t::const_iterator iter = requests->begin(); -		request_list_t::const_iterator end  = requests->end(); -		for (; iter != end; ++iter) -		{ -			const LLAssetRequest* req = *iter; -			if (asset_type == req->getType() && -				asset_id == req->getUUID() ) -			{ -				return req; -			} -		} -	} -	return NULL; +                                                  LLAssetType::EType asset_type, +                                                  const LLUUID& asset_id) +{ +    if (requests)  +    { +        // Search the requests list for the asset. +        request_list_t::const_iterator iter = requests->begin(); +        request_list_t::const_iterator end  = requests->end(); +        for (; iter != end; ++iter) +        { +            const LLAssetRequest* req = *iter; +            if (asset_type == req->getType() && +                asset_id == req->getUUID() ) +            { +                return req; +            } +        } +    } +    return NULL;  }  // static  LLAssetRequest* LLAssetStorage::findRequest(LLAssetStorage::request_list_t* requests, -										LLAssetType::EType asset_type, -										const LLUUID& asset_id) -{ -	if (requests)  -	{ -		// Search the requests list for the asset. -		request_list_t::iterator iter = requests->begin(); -		request_list_t::iterator end  = requests->end(); -		for (; iter != end; ++iter) -		{ -			LLAssetRequest* req = *iter; -			if (asset_type == req->getType() && -				asset_id == req->getUUID() ) -			{ -				return req; -			} -		} -	} -	return NULL; +                                            LLAssetType::EType asset_type, +                                            const LLUUID& asset_id) +{ +    if (requests)  +    { +        // Search the requests list for the asset. +        request_list_t::iterator iter = requests->begin(); +        request_list_t::iterator end  = requests->end(); +        for (; iter != end; ++iter) +        { +            LLAssetRequest* req = *iter; +            if (asset_type == req->getType() && +                asset_id == req->getUUID() ) +            { +                return req; +            } +        } +    } +    return NULL;  } -// virtual  LLSD LLAssetStorage::getPendingRequest(LLAssetStorage::ERequestType rt, -										LLAssetType::EType asset_type, -										const LLUUID& asset_id) const +                                       LLAssetType::EType asset_type, +                                       const LLUUID& asset_id) const  { -	const request_list_t* requests = getRequestList(rt); -	return getPendingRequestImpl(requests, asset_type, asset_id); +    const request_list_t* requests = getRequestList(rt); +    return getPendingRequestImpl(requests, asset_type, asset_id);  } -// virtual  LLSD LLAssetStorage::getPendingRequestImpl(const LLAssetStorage::request_list_t* requests, -										LLAssetType::EType asset_type, -										const LLUUID& asset_id) const +                                           LLAssetType::EType asset_type, +                                           const LLUUID& asset_id) const  { -	LLSD sd; -	const LLAssetRequest* req = findRequest(requests, asset_type, asset_id); -	if (req) -	{ -		sd = req->getFullDetails(); -	} -	return sd; +    LLSD sd; +    const LLAssetRequest* req = findRequest(requests, asset_type, asset_id); +    if (req) +    { +        sd = req->getFullDetails(); +    } +    return sd;  } -// virtual  bool LLAssetStorage::deletePendingRequest(LLAssetStorage::ERequestType rt, -											LLAssetType::EType asset_type, -											const LLUUID& asset_id) +                                          LLAssetType::EType asset_type, +                                          const LLUUID& asset_id)  { -	request_list_t* requests = getRequestList(rt); -	if (deletePendingRequestImpl(requests, asset_type, asset_id)) -	{ -		LL_DEBUGS("AssetStorage") << "Asset " << getRequestName(rt) << " request for " -				<< asset_id << "." << LLAssetType::lookup(asset_type) -				<< " removed from pending queue." << LL_ENDL; -		return true; -	} -	return false; +    request_list_t* requests = getRequestList(rt); +    if (deletePendingRequestImpl(requests, asset_type, asset_id)) +    { +        LL_DEBUGS("AssetStorage") << "Asset " << getRequestName(rt) << " request for " +                                  << asset_id << "." << LLAssetType::lookup(asset_type) +                                  << " removed from pending queue." << LL_ENDL; +        return true; +    } +    return false;  } -// virtual  bool LLAssetStorage::deletePendingRequestImpl(LLAssetStorage::request_list_t* requests, -											LLAssetType::EType asset_type, -											const LLUUID& asset_id) -{ -	LLAssetRequest* req = findRequest(requests, asset_type, asset_id); -	if (req) -	{ -		// Remove the request from this list. -		requests->remove(req); -		S32 error = LL_ERR_TCP_TIMEOUT; -		// Run callbacks. -		if (req->mUpCallback) -		{ -			req->mUpCallback(req->getUUID(), req->mUserData, error, LL_EXSTAT_REQUEST_DROPPED); -		} -		if (req->mDownCallback) -		{ -			add(sFailedDownloadCount, 1); -			req->mDownCallback(mVFS, req->getUUID(), req->getType(), req->mUserData, error, LL_EXSTAT_REQUEST_DROPPED); -		} -		if (req->mInfoCallback) -		{ -			LLAssetInfo info; -			req->mInfoCallback(&info, req->mUserData, error); -		} -		delete req; -		return true; -	} -	 -	return false; +                                              LLAssetType::EType asset_type, +                                              const LLUUID& asset_id) +{ +    LLAssetRequest* req = findRequest(requests, asset_type, asset_id); +    if (req) +    { +        // Remove the request from this list. +        requests->remove(req); +        S32 error = LL_ERR_TCP_TIMEOUT; +        // Run callbacks. +        if (req->mUpCallback) +        { +            req->mUpCallback(req->getUUID(), req->mUserData, error, LL_EXSTAT_REQUEST_DROPPED); +        } +        if (req->mDownCallback) +        { +            add(sFailedDownloadCount, 1); +            req->mDownCallback(mVFS, req->getUUID(), req->getType(), req->mUserData, error, LL_EXSTAT_REQUEST_DROPPED); +        } +        if (req->mInfoCallback) +        { +            LLAssetInfo info; +            req->mInfoCallback(&info, req->mUserData, error); +        } +        delete req; +        return true; +    } +     +    return false;  }  // static  const char* LLAssetStorage::getErrorString(S32 status)  { -	switch( status ) -	{ -	case LL_ERR_NOERR: -		return "No error"; +    switch( status ) +    { +        case LL_ERR_NOERR: +            return "No error"; -	case LL_ERR_ASSET_REQUEST_FAILED: -		return "Asset request: failed"; +        case LL_ERR_ASSET_REQUEST_FAILED: +            return "Asset request: failed"; -	case LL_ERR_ASSET_REQUEST_NONEXISTENT_FILE: -		return "Asset request: non-existent file"; +        case LL_ERR_ASSET_REQUEST_NONEXISTENT_FILE: +            return "Asset request: non-existent file"; -	case LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE: -		return "Asset request: asset not found in database"; +        case LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE: +            return "Asset request: asset not found in database"; -	case LL_ERR_EOF: -		return "End of file"; +        case LL_ERR_EOF: +            return "End of file"; -	case LL_ERR_CANNOT_OPEN_FILE: -		return "Cannot open file"; +        case LL_ERR_CANNOT_OPEN_FILE: +            return "Cannot open file"; -	case LL_ERR_FILE_NOT_FOUND: -		return "File not found"; +        case LL_ERR_FILE_NOT_FOUND: +            return "File not found"; -	case LL_ERR_TCP_TIMEOUT: -		return "File transfer timeout"; +        case LL_ERR_TCP_TIMEOUT: +            return "File transfer timeout"; -	case LL_ERR_CIRCUIT_GONE: -		return "Circuit gone"; +        case LL_ERR_CIRCUIT_GONE: +            return "Circuit gone"; -	case LL_ERR_PRICE_MISMATCH: -		return "Viewer and server do not agree on price"; +        case LL_ERR_PRICE_MISMATCH: +            return "Viewer and server do not agree on price"; -	default: -		return "Unknown status"; -	} +        default: +            return "Unknown status"; +    }  } - - -void LLAssetStorage::getAssetData(const LLUUID uuid, LLAssetType::EType type, void (*callback)(const char*, const LLUUID&, void *, S32, LLExtStat), void *user_data, BOOL is_priority) +void LLAssetStorage::getAssetData(const LLUUID uuid,  +                                  LLAssetType::EType type,  +                                  void (*callback)(const char*,  +                                                   const LLUUID&,  +                                                   void *,  +                                                   S32,  +                                                   LLExtStat),  +                                  void *user_data,  +                                  BOOL is_priority)  { -	// check for duplicates here, since we're about to fool the normal duplicate checker -	for (request_list_t::iterator iter = mPendingDownloads.begin(); -		 iter != mPendingDownloads.end();  ) -	{ -		LLAssetRequest* tmp = *iter++; -		if (type == tmp->getType() &&  -			uuid == tmp->getUUID() && -			legacyGetDataCallback == tmp->mDownCallback && -			callback == ((LLLegacyAssetRequest *)tmp->mUserData)->mDownCallback && -			user_data == ((LLLegacyAssetRequest *)tmp->mUserData)->mUserData) -		{ -			// this is a duplicate from the same subsystem - throw it away -			LL_DEBUGS("AssetStorage") << "Discarding duplicate request for UUID " << uuid << LL_ENDL; -			return; -		} -	} -	 -	 -	LLLegacyAssetRequest *legacy = new LLLegacyAssetRequest; - -	legacy->mDownCallback = callback; -	legacy->mUserData = user_data; - -	getAssetData(uuid, type, legacyGetDataCallback, (void **)legacy, -				 is_priority); -} +    // check for duplicates here, since we're about to fool the normal duplicate checker +    for (request_list_t::iterator iter = mPendingDownloads.begin(); +         iter != mPendingDownloads.end();  ) +    { +        LLAssetRequest* tmp = *iter++; +        if (type == tmp->getType() &&  +            uuid == tmp->getUUID() && +            legacyGetDataCallback == tmp->mDownCallback && +            callback == ((LLLegacyAssetRequest *)tmp->mUserData)->mDownCallback && +            user_data == ((LLLegacyAssetRequest *)tmp->mUserData)->mUserData) +        { +            // this is a duplicate from the same subsystem - throw it away +            LL_DEBUGS("AssetStorage") << "Discarding duplicate request for UUID " << uuid << LL_ENDL; +            return; +        } +    } +     +     +    LLLegacyAssetRequest *legacy = new LLLegacyAssetRequest; -// static -void LLAssetStorage::legacyGetDataCallback(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType type, void *user_data, S32 status, LLExtStat ext_status) -{ -	LLLegacyAssetRequest *legacy = (LLLegacyAssetRequest *)user_data; -	std::string filename; - -	// Check if the asset is marked toxic, and don't load bad stuff -	BOOL toxic = gAssetStorage->isAssetToxic( uuid ); - -	if ( !status -		&& !toxic ) -	{ -		LLVFile file(vfs, uuid, type); - -		std::string uuid_str; - -		uuid.toString(uuid_str); -		filename = llformat("%s.%s",gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_str).c_str(),LLAssetType::lookup(type)); - -		LLFILE* fp = LLFile::fopen(filename, "wb");	/* Flawfinder: ignore */  -		if (fp) -		{ -			const S32 buf_size = 65536; -			U8 copy_buf[buf_size]; -			while (file.read(copy_buf, buf_size))	/* Flawfinder: ignore */ -			{ -				if (fwrite(copy_buf, file.getLastBytesRead(), 1, fp) < 1) -				{ -					// return a bad file error if we can't write the whole thing -					status = LL_ERR_CANNOT_OPEN_FILE; -				} -			} - -			fclose(fp); -		} -		else -		{ -			status = LL_ERR_CANNOT_OPEN_FILE; -		} -	} - -	if (status != LL_ERR_NOERR) -	{ -		add(sFailedDownloadCount, 1); -	} -	legacy->mDownCallback(filename.c_str(), uuid, legacy->mUserData, status, ext_status); -	delete legacy; -} - -// this is overridden on the viewer and the sim, so it doesn't really do anything -// virtual  -void LLAssetStorage::storeAssetData( -	const LLTransactionID& tid, -	LLAssetType::EType asset_type, -	LLStoreAssetCallback callback, -	void* user_data, -	bool temp_file, -	bool is_priority, -	bool store_local, -	bool user_waiting, -	F64Seconds timeout) -{ -	LL_WARNS() << "storeAssetData: wrong version called" << LL_ENDL; -	// LLAssetStorage metric: Virtual base call -	reportMetric( LLUUID::null, asset_type, LLStringUtil::null, LLUUID::null, 0, MR_BAD_FUNCTION, __FILE__, __LINE__, "Illegal call to base: LLAssetStorage::storeAssetData 1" ); -} - -// virtual -// this does nothing, viewer and sim both override this. -void LLAssetStorage::storeAssetData( -	const LLUUID& asset_id, -	LLAssetType::EType asset_type, -	LLStoreAssetCallback callback, -	void* user_data, -	bool temp_file , -	bool is_priority, -	bool store_local, -	const LLUUID& requesting_agent_id, -	bool user_waiting, -	F64Seconds timeout) -{ -	LL_WARNS() << "storeAssetData: wrong version called" << LL_ENDL; -	// LLAssetStorage metric: Virtual base call -	reportMetric( asset_id, asset_type, LLStringUtil::null, requesting_agent_id, 0, MR_BAD_FUNCTION, __FILE__, __LINE__, "Illegal call to base: LLAssetStorage::storeAssetData 2" ); -} +    legacy->mDownCallback = callback; +    legacy->mUserData = user_data; -// virtual -// this does nothing, viewer and sim both override this. -void LLAssetStorage::storeAssetData( -	const std::string& filename, -	const LLUUID& asset_id, -	LLAssetType::EType asset_type, -	LLStoreAssetCallback callback, -	void* user_data, -	bool temp_file, -	bool is_priority, -	bool user_waiting, -	F64Seconds timeout) -{ -	LL_WARNS() << "storeAssetData: wrong version called" << LL_ENDL; -	// LLAssetStorage metric: Virtual base call -	reportMetric( asset_id, asset_type, LLStringUtil::null, LLUUID::null, 0, MR_BAD_FUNCTION, __FILE__, __LINE__, "Illegal call to base: LLAssetStorage::storeAssetData 3" ); +    getAssetData(uuid, type, legacyGetDataCallback, (void **)legacy, +                 is_priority);  } -// virtual -// this does nothing, viewer and sim both override this. -void LLAssetStorage::storeAssetData( -	const std::string& filename, -	const LLTransactionID &transactoin_id, -	LLAssetType::EType asset_type, -	LLStoreAssetCallback callback, -	void* user_data, -	bool temp_file, -	bool is_priority, -	bool user_waiting, -	F64Seconds timeout) -{ -	LL_WARNS() << "storeAssetData: wrong version called" << LL_ENDL; -	// LLAssetStorage metric: Virtual base call -	reportMetric( LLUUID::null, asset_type, LLStringUtil::null, LLUUID::null, 0, MR_BAD_FUNCTION, __FILE__, __LINE__, "Illegal call to base: LLAssetStorage::storeAssetData 4" ); +// static +void LLAssetStorage::legacyGetDataCallback(LLVFS *vfs, +                                           const LLUUID &uuid,  +                                           LLAssetType::EType type, +                                           void *user_data,  +                                           S32 status,  +                                           LLExtStat ext_status) +{ +    LLLegacyAssetRequest *legacy = (LLLegacyAssetRequest *)user_data; +    std::string filename; + +    // Check if the asset is marked toxic, and don't load bad stuff +    BOOL toxic = gAssetStorage->isAssetToxic( uuid ); + +    if ( !status +         && !toxic ) +    { +        LLVFile file(vfs, uuid, type); + +        std::string uuid_str; + +        uuid.toString(uuid_str); +        filename = llformat("%s.%s",gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_str).c_str(),LLAssetType::lookup(type)); + +        LLFILE* fp = LLFile::fopen(filename, "wb");     /* Flawfinder: ignore */  +        if (fp) +        { +            const S32 buf_size = 65536; +            U8 copy_buf[buf_size]; +            while (file.read(copy_buf, buf_size))   /* Flawfinder: ignore */ +            { +                if (fwrite(copy_buf, file.getLastBytesRead(), 1, fp) < 1) +                { +                    // return a bad file error if we can't write the whole thing +                    status = LL_ERR_CANNOT_OPEN_FILE; +                } +            } + +            fclose(fp); +        } +        else +        { +            status = LL_ERR_CANNOT_OPEN_FILE; +        } +    } + +    if (status != LL_ERR_NOERR) +    { +        add(sFailedDownloadCount, 1); +    } +    legacy->mDownCallback(filename.c_str(), uuid, legacy->mUserData, status, ext_status); +    delete legacy;  }  // static  void LLAssetStorage::legacyStoreDataCallback(const LLUUID &uuid, void *user_data, S32 status, LLExtStat ext_status)  { -	LLLegacyAssetRequest *legacy = (LLLegacyAssetRequest *)user_data; -	if (legacy && legacy->mUpCallback) -	{ -		legacy->mUpCallback(uuid, legacy->mUserData, status, ext_status); -	} -	delete legacy; +    LLLegacyAssetRequest *legacy = (LLLegacyAssetRequest *)user_data; +    if (legacy && legacy->mUpCallback) +    { +        legacy->mUpCallback(uuid, legacy->mUserData, status, ext_status); +    } +    delete legacy;  } -// virtual -void LLAssetStorage::addTempAssetData(const LLUUID& asset_id, const LLUUID& agent_id, const std::string& host_name)  -{ } - -// virtual -BOOL LLAssetStorage::hasTempAssetData(const LLUUID& texture_id) const  -{ return FALSE; } - -// virtual -std::string LLAssetStorage::getTempAssetHostName(const LLUUID& texture_id) const  -{ return std::string(); } - -// virtual -LLUUID LLAssetStorage::getTempAssetAgentID(const LLUUID& texture_id) const  -{ return LLUUID::null; } - -// virtual -void LLAssetStorage::removeTempAssetData(const LLUUID& asset_id)  -{ } - -// virtual -void LLAssetStorage::removeTempAssetDataByAgentID(const LLUUID& agent_id)  -{ } - -// virtual -void LLAssetStorage::dumpTempAssetData(const LLUUID& avatar_id) const  -{ } - -// virtual -void LLAssetStorage::clearTempAssetData()  -{ } -  // static  void LLAssetStorage::reportMetric( const LLUUID& asset_id, const LLAssetType::EType asset_type, const std::string& in_filename, -								   const LLUUID& agent_id, S32 asset_size, EMetricResult result, -								   const char *file, const S32 line, const std::string& in_message ) -{ -	if( !metric_recipient ) -	{ -		LL_DEBUGS("AssetStorage") << "Couldn't store LLAssetStoreage::reportMetric - no metrics_recipient" << LL_ENDL; -		return; -	} - -	std::string filename(in_filename); -	if (filename.empty()) -		filename = ll_safe_string(file); -	 -	// Create revised message - new_message = "in_message :: file:line" -	std::stringstream new_message; -	new_message << in_message << " :: " << filename << ":" << line; - -	// Change always_report to true if debugging... do not check it in this way -	static bool always_report = false; -	const char *metric_name = "LLAssetStorage::Metrics"; - -	bool success = result == MR_OKAY; - -	if( (!success) || always_report ) -	{ -		LLSD stats; -		stats["asset_id"] = asset_id; -		stats["asset_type"] = asset_type; -		stats["filename"] = filename; -		stats["agent_id"] = agent_id; -		stats["asset_size"] = (S32)asset_size; -		stats["result"] = (S32)result; - -		metric_recipient->recordEventDetails( metric_name, new_message.str(), success, stats); -	} -	else -	{ -		metric_recipient->recordEvent(metric_name, new_message.str(), success); -	} +                                   const LLUUID& agent_id, S32 asset_size, EMetricResult result, +                                   const char *file, const S32 line, const std::string& in_message ) +{ +    if( !metric_recipient ) +    { +        LL_DEBUGS("AssetStorage") << "Couldn't store LLAssetStoreage::reportMetric - no metrics_recipient" << LL_ENDL; +        return; +    } + +    std::string filename(in_filename); +    if (filename.empty()) +        filename = ll_safe_string(file); +     +    // Create revised message - new_message = "in_message :: file:line" +    std::stringstream new_message; +    new_message << in_message << " :: " << filename << ":" << line; + +    // Change always_report to true if debugging... do not check it in this way +    static bool always_report = false; +    const char *metric_name = "LLAssetStorage::Metrics"; + +    bool success = result == MR_OKAY; + +    if( (!success) || always_report ) +    { +        LLSD stats; +        stats["asset_id"] = asset_id; +        stats["asset_type"] = asset_type; +        stats["filename"] = filename; +        stats["agent_id"] = agent_id; +        stats["asset_size"] = (S32)asset_size; +        stats["result"] = (S32)result; + +        metric_recipient->recordEventDetails( metric_name, new_message.str(), success, stats); +    } +    else +    { +        metric_recipient->recordEvent(metric_name, new_message.str(), success); +    }  }  // Check if an asset is in the toxic map.  If it is, the entry is updated -BOOL	LLAssetStorage::isAssetToxic( const LLUUID& uuid ) +BOOL LLAssetStorage::isAssetToxic( const LLUUID& uuid )  { -	BOOL is_toxic = FALSE; - -	if ( !uuid.isNull() ) -	{ -		toxic_asset_map_t::iterator iter = mToxicAssetMap.find( uuid ); -		if ( iter != mToxicAssetMap.end() ) -		{	// Found toxic asset -			(*iter).second = LLFrameTimer::getTotalTime() + TOXIC_ASSET_LIFETIME; -			is_toxic = TRUE; -		}  -	} -	return is_toxic; +    BOOL is_toxic = FALSE; + +    if ( !uuid.isNull() ) +    { +        toxic_asset_map_t::iterator iter = mToxicAssetMap.find( uuid ); +        if ( iter != mToxicAssetMap.end() ) +        {   // Found toxic asset +            (*iter).second = LLFrameTimer::getTotalTime() + TOXIC_ASSET_LIFETIME; +            is_toxic = TRUE; +        }  +    } +    return is_toxic;  }  // Clean the toxic asset list, remove old entries -void	LLAssetStorage::flushOldToxicAssets( BOOL force_it ) -{ -	// Scan and look for old entries -	U64 now = LLFrameTimer::getTotalTime(); -	toxic_asset_map_t::iterator iter = mToxicAssetMap.begin(); -	while ( iter != mToxicAssetMap.end() ) -	{ -		if ( force_it -			|| (*iter).second < now ) -		{	// Too old - remove it -			mToxicAssetMap.erase( iter++ ); -		} -		else -		{ -			iter++; -		} -	} +void LLAssetStorage::flushOldToxicAssets( BOOL force_it ) +{ +    // Scan and look for old entries +    U64 now = LLFrameTimer::getTotalTime(); +    toxic_asset_map_t::iterator iter = mToxicAssetMap.begin(); +    while ( iter != mToxicAssetMap.end() ) +    { +        if ( force_it +             || (*iter).second < now ) +        {   // Too old - remove it +            mToxicAssetMap.erase( iter++ ); +        } +        else +        { +            iter++; +        } +    }  }  // Add an item to the toxic asset map -void	LLAssetStorage::markAssetToxic( const LLUUID& uuid ) -{	 -	if ( !uuid.isNull() ) -	{ -		// Set the value to the current time.  Creates a new entry if needed -		mToxicAssetMap[ uuid ] = LLFrameTimer::getTotalTime() + TOXIC_ASSET_LIFETIME; -	} +void LLAssetStorage::markAssetToxic( const LLUUID& uuid ) +{    +    if ( !uuid.isNull() ) +    { +        // Set the value to the current time.  Creates a new entry if needed +        mToxicAssetMap[ uuid ] = LLFrameTimer::getTotalTime() + TOXIC_ASSET_LIFETIME; +    }  } diff --git a/indra/llmessage/llassetstorage.h b/indra/llmessage/llassetstorage.h index 0f23754096..33b88473b9 100644 --- a/indra/llmessage/llassetstorage.h +++ b/indra/llmessage/llassetstorage.h @@ -138,6 +138,7 @@ public:  	BOOL	mIsUserWaiting;		// We don't want to try forever if a user is waiting for a result.  	F64Seconds		mTimeout;			// Amount of time before timing out.  	LLUUID	mRequestingAgentID;	// Only valid for uploads from an agent +    F64	mBytesFetched;  	virtual LLSD getTerseDetails() const;  	virtual LLSD getFullDetails() const; @@ -186,18 +187,9 @@ typedef std::map<LLUUID,U64,lluuid_less> toxic_asset_map_t;  // we can use bind and remove the userData parameter.  //   typedef void (*LLGetAssetCallback)(LLVFS *vfs, const LLUUID &asset_id, -										 LLAssetType::EType asset_type, void *user_data, S32 status, LLExtStat ext_status); +                                   LLAssetType::EType asset_type, void *user_data, S32 status, LLExtStat ext_status); -class LLTempAssetStorage -{ -public: -	virtual ~LLTempAssetStorage() =0; -	virtual void addTempAssetData(const LLUUID& asset_id, -								  const LLUUID& agent_id, -								  const std::string& host_name) = 0; -}; - -class LLAssetStorage : public LLTempAssetStorage +class LLAssetStorage  {  public:  	// VFS member is public because static child methods need it :( @@ -240,12 +232,11 @@ public:  	void setUpstream(const LLHost &upstream_host); -	virtual BOOL hasLocalAsset(const LLUUID &uuid, LLAssetType::EType type); +	BOOL hasLocalAsset(const LLUUID &uuid, LLAssetType::EType type);  	// public interface methods  	// note that your callback may get called BEFORE the function returns - -	virtual void getAssetData(const LLUUID uuid, LLAssetType::EType atype, LLGetAssetCallback cb, void *user_data, BOOL is_priority = FALSE); +	void getAssetData(const LLUUID uuid, LLAssetType::EType atype, LLGetAssetCallback cb, void *user_data, BOOL is_priority = FALSE);  	/*  	 * TransactionID version @@ -260,25 +251,11 @@ public:  		bool is_priority = false,  		bool store_local = false,  		bool user_waiting= false, -		F64Seconds timeout=LL_ASSET_STORAGE_TIMEOUT); - -	/* -	 * AssetID version -	 * Sim needs both store_local and requesting_agent_id. -	 */ -	virtual	void storeAssetData( -		const LLUUID& asset_id, -		LLAssetType::EType asset_type, -		LLStoreAssetCallback callback, -		void* user_data, -		bool temp_file = false, -		bool is_priority = false, -		bool store_local = false, -		const LLUUID& requesting_agent_id = LLUUID::null, -		bool user_waiting= false, -		F64Seconds timeout=LL_ASSET_STORAGE_TIMEOUT); +		F64Seconds timeout=LL_ASSET_STORAGE_TIMEOUT) = 0; -	virtual void checkForTimeouts(); +    virtual void logAssetStorageInfo() = 0; +     +	void checkForTimeouts();  	void getEstateAsset(const LLHost &object_sim, const LLUUID &agent_id, const LLUUID &session_id,  									const LLUUID &asset_id, LLAssetType::EType atype, EstateAssetType etype, @@ -303,17 +280,17 @@ protected:  	bool findInStaticVFSAndInvokeCallback(const LLUUID& uuid, LLAssetType::EType type,  										  LLGetAssetCallback callback, void *user_data); -	virtual LLSD getPendingDetailsImpl(const request_list_t* requests, -	 				LLAssetType::EType asset_type, -	 				const std::string& detail_prefix) const; +	LLSD getPendingDetailsImpl(const request_list_t* requests, +                               LLAssetType::EType asset_type, +                               const std::string& detail_prefix) const; -	virtual LLSD getPendingRequestImpl(const request_list_t* requests, -							LLAssetType::EType asset_type, -							const LLUUID& asset_id) const; +	LLSD getPendingRequestImpl(const request_list_t* requests, +                               LLAssetType::EType asset_type, +                               const LLUUID& asset_id) const; -	virtual bool deletePendingRequestImpl(request_list_t* requests, -							LLAssetType::EType asset_type, -							const LLUUID& asset_id); +	bool deletePendingRequestImpl(request_list_t* requests, +                                  LLAssetType::EType asset_type, +                                  const LLUUID& asset_id);  public:  	static const LLAssetRequest* findRequest(const request_list_t* requests, @@ -332,19 +309,23 @@ public:  	S32 getNumPendingLocalUploads();  	S32 getNumPending(ERequestType rt) const; -	virtual LLSD getPendingDetails(ERequestType rt, -	 				LLAssetType::EType asset_type, -	 				const std::string& detail_prefix) const; +	LLSD getPendingDetails(ERequestType rt, +                           LLAssetType::EType asset_type, +                           const std::string& detail_prefix) const; -	virtual LLSD getPendingRequest(ERequestType rt, -							LLAssetType::EType asset_type, -							const LLUUID& asset_id) const; +	LLSD getPendingRequest(ERequestType rt, +                           LLAssetType::EType asset_type, +                           const LLUUID& asset_id) const; -	virtual bool deletePendingRequest(ERequestType rt, -							LLAssetType::EType asset_type, -							const LLUUID& asset_id); +	bool deletePendingRequest(ERequestType rt, +                              LLAssetType::EType asset_type, +                              const LLUUID& asset_id); +    static void removeAndCallbackPendingDownloads(const LLUUID& file_id, LLAssetType::EType file_type, +                                                  const LLUUID& callback_id, LLAssetType::EType callback_type, +                                                  S32 result_code, LLExtStat ext_status); +      	// download process callbacks  	static void downloadCompleteCallback(  		S32 result, @@ -370,23 +351,10 @@ public:  	static const char* getErrorString( S32 status );  	// deprecated file-based methods +    // Not overriden  	void getAssetData(const LLUUID uuid, LLAssetType::EType type, void (*callback)(const char*, const LLUUID&, void *, S32, LLExtStat), void *user_data, BOOL is_priority = FALSE);  	/* -	 * AssetID version. -	 */ -	virtual void storeAssetData( -		const std::string& filename, -		const LLUUID& asset_id, -		LLAssetType::EType type, -		LLStoreAssetCallback callback, -		void* user_data, -		bool temp_file = false, -		bool is_priority = false, -		bool user_waiting = false, -		F64Seconds timeout  = LL_ASSET_STORAGE_TIMEOUT); - -	/*  	 * TransactionID version  	 */  	virtual void storeAssetData( @@ -398,23 +366,11 @@ public:  		bool temp_file = false,  		bool is_priority = false,  		bool user_waiting = false, -		F64Seconds timeout  = LL_ASSET_STORAGE_TIMEOUT); +		F64Seconds timeout  = LL_ASSET_STORAGE_TIMEOUT) = 0;  	static void legacyGetDataCallback(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType, void *user_data, S32 status, LLExtStat ext_status);  	static void legacyStoreDataCallback(const LLUUID &uuid, void *user_data, S32 status, LLExtStat ext_status); -	// Temp assets are stored on sim nodes, they have agent ID and location data associated with them. -	// This is a no-op for non-http asset systems -	virtual void addTempAssetData(const LLUUID& asset_id, const LLUUID& agent_id, const std::string& host_name); -	virtual BOOL hasTempAssetData(const LLUUID& texture_id) const; -	virtual std::string getTempAssetHostName(const LLUUID& texture_id) const; -	virtual LLUUID getTempAssetAgentID(const LLUUID& texture_id) const; -	virtual void removeTempAssetData(const LLUUID& asset_id); -	virtual void removeTempAssetDataByAgentID(const LLUUID& agent_id); -	// Pass LLUUID::null for all -	virtual void dumpTempAssetData(const LLUUID& avatar_id) const; -	virtual void clearTempAssetData(); -  	// add extra methods to handle metadata  protected: @@ -424,7 +380,7 @@ protected:  	virtual void _queueDataRequest(const LLUUID& uuid, LLAssetType::EType type,  								   void (*callback)(LLVFS *vfs, const LLUUID&, LLAssetType::EType, void *, S32, LLExtStat),  								   void *user_data, BOOL duplicate, -								   BOOL is_priority); +								   BOOL is_priority) = 0;  private:  	void _init(LLMessageSystem *msg, diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index c20c645d7e..00433367c8 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -5.0.6 +5.0.7 diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index f490551406..c544205df0 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -14705,6 +14705,17 @@        <key>Value</key>        <integer>0</integer>      </map> +    <key>AssetStorageLogFrequency</key> +        <map> +        <key>Comment</key> +        <string>Seconds between display of AssetStorage info in log (0 for never)</string> +        <key>Persist</key> +        <integer>1</integer> +        <key>Type</key> +        <string>F32</string> +        <key>Value</key> +        <real>60.0</real> +        </map>      <key>LogWearableAssetSave</key>      <map>        <key>Comment</key> @@ -14778,6 +14789,15 @@          <key>Value</key>              <real>1</real>          </map> +    <key>PoolSizeAssetStorage</key> +        <map> +        <key>Comment</key> +            <string>Coroutine Pool size for AssetStorage requests</string> +        <key>Type</key> +            <string>U32</string> +        <key>Value</key> +            <real>12</real> +        </map>      <!-- Settings below are for back compatibility only.      They are not used in current viewer anymore. But they can't be removed to avoid diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 4095f1c8ef..37340a42b6 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -844,12 +844,6 @@ bool LLAppViewer::init()      LLMachineID::init();  	{ -		// Viewer metrics initialization -		//static LLCachedControl<bool> metrics_submode(gSavedSettings, -		//											 "QAModeMetrics", -		//											 false, -		//											 "Enables QA features (logging, faster cycling) for metrics collector"); -  		if (gSavedSettings.getBOOL("QAModeMetrics"))  		{  			app_metrics_qa_mode = true; @@ -5928,23 +5922,14 @@ void LLAppViewer::metricsSend(bool enable_reporting)  		{  			std::string	caps_url = regionp->getCapability("ViewerMetrics"); -            if (gSavedSettings.getBOOL("QAModeMetrics")) -            { -                dump_sequential_xml("metric_asset_stats",gViewerAssetStats->asLLSD(true)); -            } -             -			// Make a copy of the main stats to send into another thread. -			// Receiving thread takes ownership. -			LLViewerAssetStats * main_stats(new LLViewerAssetStats(*gViewerAssetStats)); -			main_stats->stop(); -			 +            LLSD sd = gViewerAssetStats->asLLSD(true); +  			// Send a report request into 'thread1' to get the rest of the data  			// and provide some additional parameters while here.  			LLAppViewer::sTextureFetch->commandSendMetrics(caps_url,  														   gAgentSessionID,  														   gAgentID, -														   main_stats); -			main_stats = 0;		// Ownership transferred +														   sd);  		}  		else  		{ diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index f7e0e32256..c4d1917567 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -343,10 +343,6 @@ LLMeshRepository gMeshRepo;  const S32 MESH_HEADER_SIZE = 4096;                      // Important:  assumption is that headers fit in this space -const S32 REQUEST_HIGH_WATER_MIN = 32;					// Limits for GetMesh regions -const S32 REQUEST_HIGH_WATER_MAX = 150;					// Should remain under 2X throttle -const S32 REQUEST_LOW_WATER_MIN = 16; -const S32 REQUEST_LOW_WATER_MAX = 75;  const S32 REQUEST2_HIGH_WATER_MIN = 32;					// Limits for GetMesh2 regions  const S32 REQUEST2_HIGH_WATER_MAX = 100; @@ -808,10 +804,8 @@ LLMeshRepoThread::LLMeshRepoThread()    mHttpLargeOptions(),    mHttpHeaders(),    mHttpPolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID), -  mHttpLegacyPolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID),    mHttpLargePolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID), -  mHttpPriority(0), -  mGetMeshVersion(2) +  mHttpPriority(0)  {  	LLAppCoreHttp & app_core_http(LLAppViewer::instance()->getAppCoreHttp()); @@ -828,7 +822,6 @@ LLMeshRepoThread::LLMeshRepoThread()  	mHttpHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders);  	mHttpHeaders->append(HTTP_OUT_HEADER_ACCEPT, HTTP_CONTENT_VND_LL_MESH);  	mHttpPolicyClass = app_core_http.getPolicy(LLAppCoreHttp::AP_MESH2); -	mHttpLegacyPolicyClass = app_core_http.getPolicy(LLAppCoreHttp::AP_MESH1);  	mHttpLargePolicyClass = app_core_http.getPolicy(LLAppCoreHttp::AP_LARGE_MESH);  } @@ -1103,13 +1096,9 @@ void LLMeshRepoThread::loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod)  }  // Mutex:  must be holding mMutex when called -void LLMeshRepoThread::setGetMeshCaps(const std::string & get_mesh1, -									  const std::string & get_mesh2, -									  int pref_version) +void LLMeshRepoThread::setGetMeshCap(const std::string & mesh_cap)  { -	mGetMeshCapability = get_mesh1; -	mGetMesh2Capability = get_mesh2; -	mGetMeshVersion = pref_version; +	mGetMeshCapability = mesh_cap;  } @@ -1117,29 +1106,14 @@ void LLMeshRepoThread::setGetMeshCaps(const std::string & get_mesh1,  // over a GetMesh cap.  //  // Mutex:  acquires mMutex -void LLMeshRepoThread::constructUrl(LLUUID mesh_id, std::string * url, int * version) +void LLMeshRepoThread::constructUrl(LLUUID mesh_id, std::string * url)  {  	std::string res_url; -	int res_version(2);  	if (gAgent.getRegion())  	{  		LLMutexLock lock(mMutex); - -		// Get a consistent pair of (cap string, version).  The -		// locking could be eliminated here without loss of safety -		// by using a set of staging values in setGetMeshCaps(). -		 -		if (! mGetMesh2Capability.empty() && mGetMeshVersion > 1) -		{ -			res_url = mGetMesh2Capability; -			res_version = 2; -		} -		else -		{ -			res_url = mGetMeshCapability; -			res_version = 1; -		} +        res_url = mGetMeshCapability;  	}  	if (! res_url.empty()) @@ -1149,19 +1123,15 @@ void LLMeshRepoThread::constructUrl(LLUUID mesh_id, std::string * url, int * ver  	}  	else  	{ -		LL_WARNS_ONCE(LOG_MESH) << "Current region does not have GetMesh capability!  Cannot load " +		LL_WARNS_ONCE(LOG_MESH) << "Current region does not have ViewerAsset capability!  Cannot load "  								<< mesh_id << ".mesh" << LL_ENDL;  	}  	*url = res_url; -	*version = res_version;  }  // Issue an HTTP GET request with byte range using the right -// policy class.  Large requests go to the large request class. -// If the current region supports GetMesh2, we prefer that for -// smaller requests otherwise we try to use the traditional -// GetMesh capability and connection concurrency. +// policy class.    //  // @return		Valid handle or LLCORE_HTTP_HANDLE_INVALID.  //				If the latter, actual status is found in @@ -1169,7 +1139,7 @@ void LLMeshRepoThread::constructUrl(LLUUID mesh_id, std::string * url, int * ver  //				next call to this method.  //  // Thread:  repo -LLCore::HttpHandle LLMeshRepoThread::getByteRange(const std::string & url, int cap_version, +LLCore::HttpHandle LLMeshRepoThread::getByteRange(const std::string & url,  												  size_t offset, size_t len,  												  const LLCore::HttpHandler::ptr_t &handler)  { @@ -1180,16 +1150,14 @@ LLCore::HttpHandle LLMeshRepoThread::getByteRange(const std::string & url, int c  	if (len < LARGE_MESH_FETCH_THRESHOLD)  	{ -		handle = mHttpRequest->requestGetByteRange((2 == cap_version -													? mHttpPolicyClass -													: mHttpLegacyPolicyClass), -												   mHttpPriority, -												   url, -												   (disable_range_req ? size_t(0) : offset), -												   (disable_range_req ? size_t(0) : len), -												   mHttpOptions, -												   mHttpHeaders, -												   handler); +		handle = mHttpRequest->requestGetByteRange( mHttpPolicyClass, +                                                    mHttpPriority, +                                                    url, +                                                    (disable_range_req ? size_t(0) : offset), +                                                    (disable_range_req ? size_t(0) : len), +                                                    mHttpOptions, +                                                    mHttpHeaders, +                                                    handler);  		if (LLCORE_HTTP_HANDLE_INVALID != handle)  		{  			++LLMeshRepository::sHTTPRequestCount; @@ -1279,14 +1247,13 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)  			}  			//reading from VFS failed for whatever reason, fetch from sim -			int cap_version(2);  			std::string http_url; -			constructUrl(mesh_id, &http_url, &cap_version); +			constructUrl(mesh_id, &http_url);  			if (!http_url.empty())  			{                  LLMeshHandlerBase::ptr_t handler(new LLMeshSkinInfoHandler(mesh_id, offset, size)); -				LLCore::HttpHandle handle = getByteRange(http_url, cap_version, offset, size, handler); +				LLCore::HttpHandle handle = getByteRange(http_url, offset, size, handler);  				if (LLCORE_HTTP_HANDLE_INVALID == handle)  				{  					LL_WARNS(LOG_MESH) << "HTTP GET request failed for skin info on mesh " << mID @@ -1372,14 +1339,13 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)  			}  			//reading from VFS failed for whatever reason, fetch from sim -			int cap_version(2);  			std::string http_url; -			constructUrl(mesh_id, &http_url, &cap_version); +			constructUrl(mesh_id, &http_url);  			if (!http_url.empty())  			{                  LLMeshHandlerBase::ptr_t handler(new LLMeshDecompositionHandler(mesh_id, offset, size)); -				LLCore::HttpHandle handle = getByteRange(http_url, cap_version, offset, size, handler); +				LLCore::HttpHandle handle = getByteRange(http_url, offset, size, handler);  				if (LLCORE_HTTP_HANDLE_INVALID == handle)  				{  					LL_WARNS(LOG_MESH) << "HTTP GET request failed for decomposition mesh " << mID @@ -1464,14 +1430,13 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)  			}  			//reading from VFS failed for whatever reason, fetch from sim -			int cap_version(2);  			std::string http_url; -			constructUrl(mesh_id, &http_url, &cap_version); +			constructUrl(mesh_id, &http_url);  			if (!http_url.empty())  			{                  LLMeshHandlerBase::ptr_t handler(new LLMeshPhysicsShapeHandler(mesh_id, offset, size)); -				LLCore::HttpHandle handle = getByteRange(http_url, cap_version, offset, size, handler); +				LLCore::HttpHandle handle = getByteRange(http_url, offset, size, handler);  				if (LLCORE_HTTP_HANDLE_INVALID == handle)  				{  					LL_WARNS(LOG_MESH) << "HTTP GET request failed for physics shape on mesh " << mID @@ -1558,9 +1523,8 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params)  	//either cache entry doesn't exist or is corrupt, request header from simulator	  	bool retval = true; -	int cap_version(2);  	std::string http_url; -	constructUrl(mesh_params.getSculptID(), &http_url, &cap_version); +	constructUrl(mesh_params.getSculptID(), &http_url);  	if (!http_url.empty())  	{ @@ -1569,7 +1533,7 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params)  		//NOTE -- this will break of headers ever exceed 4KB		          LLMeshHandlerBase::ptr_t handler(new LLMeshHeaderHandler(mesh_params, 0, MESH_HEADER_SIZE)); -		LLCore::HttpHandle handle = getByteRange(http_url, cap_version, 0, MESH_HEADER_SIZE, handler); +		LLCore::HttpHandle handle = getByteRange(http_url, 0, MESH_HEADER_SIZE, handler);  		if (LLCORE_HTTP_HANDLE_INVALID == handle)  		{  			LL_WARNS(LOG_MESH) << "HTTP GET request failed for mesh header " << mID @@ -1645,14 +1609,13 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod)  			}  			//reading from VFS failed for whatever reason, fetch from sim -			int cap_version(2);  			std::string http_url; -			constructUrl(mesh_id, &http_url, &cap_version); +			constructUrl(mesh_id, &http_url);  			if (!http_url.empty())  			{                  LLMeshHandlerBase::ptr_t handler(new LLMeshLODHandler(mesh_params, lod, offset, size)); -				LLCore::HttpHandle handle = getByteRange(http_url, cap_version, offset, size, handler); +				LLCore::HttpHandle handle = getByteRange(http_url, offset, size, handler);  				if (LLCORE_HTTP_HANDLE_INVALID == handle)  				{  					LL_WARNS(LOG_MESH) << "HTTP GET request failed for LOD on mesh " << mID @@ -3292,8 +3255,7 @@ void LLMeshPhysicsShapeHandler::processData(LLCore::BufferArray * /* body */, S3  LLMeshRepository::LLMeshRepository()  : mMeshMutex(NULL),    mMeshThreadCount(0), -  mThread(NULL), -  mGetMeshVersion(2) +  mThread(NULL)  {  } @@ -3476,35 +3438,21 @@ void LLMeshRepository::notifyLoadedMeshes()  { //called from main thread  	LL_RECORD_BLOCK_TIME(FTM_MESH_FETCH); -	if (1 == mGetMeshVersion) -	{ -		// Legacy GetMesh operation with high connection concurrency -		LLMeshRepoThread::sMaxConcurrentRequests = gSavedSettings.getU32("MeshMaxConcurrentRequests"); -		LLMeshRepoThread::sRequestHighWater = llclamp(2 * S32(LLMeshRepoThread::sMaxConcurrentRequests), -													  REQUEST_HIGH_WATER_MIN, -													  REQUEST_HIGH_WATER_MAX); -		LLMeshRepoThread::sRequestLowWater = llclamp(LLMeshRepoThread::sRequestHighWater / 2, -													 REQUEST_LOW_WATER_MIN, -													 REQUEST_LOW_WATER_MAX); -	} -	else -	{ -		// GetMesh2 operation with keepalives, etc.  With pipelining, -		// we'll increase this.  See llappcorehttp and llcorehttp for -		// discussion on connection strategies. -		LLAppCoreHttp & app_core_http(LLAppViewer::instance()->getAppCoreHttp()); -		S32 scale(app_core_http.isPipelined(LLAppCoreHttp::AP_MESH2) -				  ? (2 * LLAppCoreHttp::PIPELINING_DEPTH) -				  : 5); - -		LLMeshRepoThread::sMaxConcurrentRequests = gSavedSettings.getU32("Mesh2MaxConcurrentRequests"); -		LLMeshRepoThread::sRequestHighWater = llclamp(scale * S32(LLMeshRepoThread::sMaxConcurrentRequests), -													  REQUEST2_HIGH_WATER_MIN, -													  REQUEST2_HIGH_WATER_MAX); -		LLMeshRepoThread::sRequestLowWater = llclamp(LLMeshRepoThread::sRequestHighWater / 2, -													 REQUEST2_LOW_WATER_MIN, -													 REQUEST2_LOW_WATER_MAX); -	} +    // GetMesh2 operation with keepalives, etc.  With pipelining, +    // we'll increase this.  See llappcorehttp and llcorehttp for +    // discussion on connection strategies. +    LLAppCoreHttp & app_core_http(LLAppViewer::instance()->getAppCoreHttp()); +    S32 scale(app_core_http.isPipelined(LLAppCoreHttp::AP_MESH2) +              ? (2 * LLAppCoreHttp::PIPELINING_DEPTH) +              : 5); + +    LLMeshRepoThread::sMaxConcurrentRequests = gSavedSettings.getU32("Mesh2MaxConcurrentRequests"); +    LLMeshRepoThread::sRequestHighWater = llclamp(scale * S32(LLMeshRepoThread::sMaxConcurrentRequests), +                                                  REQUEST2_HIGH_WATER_MIN, +                                                  REQUEST2_HIGH_WATER_MAX); +    LLMeshRepoThread::sRequestLowWater = llclamp(LLMeshRepoThread::sRequestHighWater / 2, +                                                 REQUEST2_LOW_WATER_MIN, +                                                 REQUEST2_LOW_WATER_MAX);  	//clean up completed upload threads  	for (std::vector<LLMeshUploadThread*>::iterator iter = mUploads.begin(); iter != mUploads.end(); ) @@ -3610,15 +3558,10 @@ void LLMeshRepository::notifyLoadedMeshes()  			if (gAgent.getRegion()->getName() != region_name && gAgent.getRegion()->capabilitiesReceived())  			{  				region_name = gAgent.getRegion()->getName(); -				const bool use_v1(gSavedSettings.getBOOL("MeshUseGetMesh1")); -				const std::string mesh1(gAgent.getRegion()->getCapability("GetMesh")); -				const std::string mesh2(gAgent.getRegion()->getCapability("GetMesh2")); -				mGetMeshVersion = (mesh2.empty() || use_v1) ? 1 : 2; -				mThread->setGetMeshCaps(mesh1, mesh2, mGetMeshVersion); +				const std::string mesh_cap(gAgent.getRegion()->getViewerAssetUrl()); +				mThread->setGetMeshCap(mesh_cap);  				LL_DEBUGS(LOG_MESH) << "Retrieving caps for region '" << region_name -									<< "', GetMesh2:  " << mesh2 -									<< ", GetMesh:  " << mesh1 -									<< ", using version:  " << mGetMeshVersion +									<< "', ViewerAsset cap:  " << mesh_cap  									<< LL_ENDL;  			}  		} diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index 30f042845a..23af837f6f 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -279,7 +279,6 @@ public:  	LLCore::HttpOptions::ptr_t			mHttpLargeOptions;  	LLCore::HttpHeaders::ptr_t			mHttpHeaders;  	LLCore::HttpRequest::policy_t		mHttpPolicyClass; -	LLCore::HttpRequest::policy_t		mHttpLegacyPolicyClass;  	LLCore::HttpRequest::policy_t		mHttpLargePolicyClass;  	LLCore::HttpRequest::priority_t		mHttpPriority; @@ -287,8 +286,6 @@ public:  	http_request_set					mHttpRequestSet;			// Outstanding HTTP requests  	std::string mGetMeshCapability; -	std::string mGetMesh2Capability; -	int mGetMeshVersion;  	LLMeshRepoThread();  	~LLMeshRepoThread(); @@ -335,12 +332,10 @@ public:  	// mesh fetch URLs.  	//  	// Mutex:  must be holding mMutex when called -	void setGetMeshCaps(const std::string & get_mesh1, -						const std::string & get_mesh2, -						int pref_version); +	void setGetMeshCap(const std::string & get_mesh);  	// Mutex:  acquires mMutex -	void constructUrl(LLUUID mesh_id, std::string * url, int * version); +	void constructUrl(LLUUID mesh_id, std::string * url);  private:  	// Issue a GET request to a URL with 'Range' header using @@ -349,7 +344,7 @@ private:  	// or dispose of handler.  	//  	// Threads:  Repo thread only -	LLCore::HttpHandle getByteRange(const std::string & url, int cap_version, +	LLCore::HttpHandle getByteRange(const std::string & url,   									size_t offset, size_t len,   									const LLCore::HttpHandler::ptr_t &handler);  }; @@ -585,8 +580,6 @@ public:  	void uploadError(LLSD& args);  	void updateInventory(inventory_data data); - -	int mGetMeshVersion;		// Shadows value in LLMeshRepoThread  };  extern LLMeshRepository gMeshRepo; diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 07b3dc1aa4..b78d0b51d5 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -30,8 +30,6 @@  #include <map>  #include <algorithm> -#include "llstl.h" -  #include "lltexturefetch.h"  #include "lldir.h" @@ -485,7 +483,7 @@ private:  	void recordTextureStart(bool is_http);  	// Threads:  Ttf -	void recordTextureDone(bool is_http); +	void recordTextureDone(bool is_http, F64 byte_count);  	void lockWorkMutex() { mWorkMutex.lock(); }  	void unlockWorkMutex() { mWorkMutex.unlock(); } @@ -824,7 +822,7 @@ public:      TFReqSendMetrics(const std::string & caps_url,          const LLUUID & session_id,          const LLUUID & agent_id, -        LLViewerAssetStats * main_stats); +        LLSD& stats_sd);  	TFReqSendMetrics & operator=(const TFReqSendMetrics &);	// Not defined  	virtual ~TFReqSendMetrics(); @@ -835,7 +833,7 @@ public:  	const std::string mCapsURL;  	const LLUUID mSessionID;  	const LLUUID mAgentID; -	LLViewerAssetStats * mMainStats; +    LLSD mStatsSD;  private:      LLCore::HttpHandler::ptr_t  mHandler; @@ -1351,7 +1349,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  			if (region)  			{ -				std::string http_url = region->getHttpUrl() ; +				std::string http_url = region->getViewerAssetUrl();  				if (!http_url.empty())  				{  					if (mFTType != FTT_DEFAULT) @@ -1426,6 +1424,20 @@ bool LLTextureFetchWorker::doWork(S32 param)  		}  		if (processSimulatorPackets())  		{ +            // Capture some measure of total size for metrics +            F64 byte_count = 0; +            if (mLastPacket >= mFirstPacket) +            { +                for (S32 i=mFirstPacket; i<=mLastPacket; i++) +                { +                    llassert_always((i>=0) && (i<mPackets.size())); +                    if (mPackets[i]) +                    { +                        byte_count += mPackets[i]->mSize; +                    } +                } +            } +  			LL_DEBUGS(LOG_TXT) << mID << ": Loaded from Sim. Bytes: " << mFormattedImage->getDataSize() << LL_ENDL;  			mFetcher->removeFromNetworkQueue(this, false);  			if (mFormattedImage.isNull() || !mFormattedImage->getDataSize()) @@ -1443,7 +1455,8 @@ bool LLTextureFetchWorker::doWork(S32 param)  			}  			setState(DECODE_IMAGE);  			mWriteToCacheState = SHOULD_WRITE; -			recordTextureDone(false); + +			recordTextureDone(false, byte_count);  		}  		else  		{ @@ -2093,7 +2106,7 @@ void LLTextureFetchWorker::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRe  	mFetcher->removeFromHTTPQueue(mID, data_size); -	recordTextureDone(true); +	recordTextureDone(true, data_size);  }																		// -Mw @@ -2222,6 +2235,7 @@ bool LLTextureFetchWorker::processSimulatorPackets()  		S32 buffer_size = mFormattedImage->getDataSize();  		for (S32 i = mFirstPacket; i<=mLastPacket; i++)  		{ +            llassert_always((i>=0) && (i<mPackets.size()));  			llassert_always(mPackets[i]);  			buffer_size += mPackets[i]->mSize;  		} @@ -2493,14 +2507,15 @@ void LLTextureFetchWorker::recordTextureStart(bool is_http)  // Threads:  Ttf -void LLTextureFetchWorker::recordTextureDone(bool is_http) +void LLTextureFetchWorker::recordTextureDone(bool is_http, F64 byte_count)  {  	if (mMetricsStartTime.value())  	{  		LLViewerAssetStatsFF::record_response(LLViewerAssetType::AT_TEXTURE, -													  is_http, -													  LLImageBase::TYPE_AVATAR_BAKE == mType, -													  LLViewerAssetStatsFF::get_timestamp() - mMetricsStartTime); +                                              is_http, +                                              LLImageBase::TYPE_AVATAR_BAKE == mType, +                                              LLViewerAssetStatsFF::get_timestamp() - mMetricsStartTime, +                                              byte_count);  		mMetricsStartTime = (U32Seconds)0;  	}  	LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_TEXTURE, @@ -3863,9 +3878,9 @@ void LLTextureFetch::commandSetRegion(U64 region_handle)  void LLTextureFetch::commandSendMetrics(const std::string & caps_url,  										const LLUUID & session_id,  										const LLUUID & agent_id, -										LLViewerAssetStats * main_stats) +										LLSD& stats_sd)  { -	TFReqSendMetrics * req = new TFReqSendMetrics(caps_url, session_id, agent_id, main_stats); +	TFReqSendMetrics * req = new TFReqSendMetrics(caps_url, session_id, agent_id, stats_sd);  	cmdEnqueue(req);  } @@ -3974,22 +3989,20 @@ TFReqSetRegion::doWork(LLTextureFetch *)  }  TFReqSendMetrics::TFReqSendMetrics(const std::string & caps_url, -        const LLUUID & session_id, -        const LLUUID & agent_id, -        LLViewerAssetStats * main_stats):  +                                   const LLUUID & session_id, +                                   const LLUUID & agent_id, +                                   LLSD& stats_sd):      LLTextureFetch::TFRequest(),      mCapsURL(caps_url),      mSessionID(session_id),      mAgentID(agent_id), -    mMainStats(main_stats), +    mStatsSD(stats_sd),      mHandler(new AssetReportHandler)  {}  TFReqSendMetrics::~TFReqSendMetrics()  { -	delete mMainStats; -	mMainStats = 0;  } @@ -4010,26 +4023,19 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher)  	static volatile bool reporting_started(false);  	static volatile S32 report_sequence(0); -	// We've taken over ownership of the stats copy at this -	// point.  Get a working reference to it for merging here -	// but leave it in 'this'.  Destructor will rid us of it. -	LLViewerAssetStats & main_stats = *mMainStats; - -	LLViewerAssetStats::AssetStats stats; -	main_stats.getStats(stats, true); -	//LLSD merged_llsd = main_stats.asLLSD(); +	// In mStatsSD, we have a copy we own of the LLSD representation +	// of the asset stats. Add some additional fields and ship it off. +    static const S32 metrics_data_version = 2; +      	bool initial_report = !reporting_started; -	stats.session_id = mSessionID; -	stats.agent_id = mAgentID; -	stats.message = "ViewerAssetMetrics"; -	stats.sequence = static_cast<bool>(report_sequence); -	stats.initial = initial_report; -	stats.break_ = static_cast<bool>(LLTextureFetch::svMetricsDataBreak); - -	LLSD sd; -	LLParamSDParser parser; -	parser.writeSD(sd, stats); +	mStatsSD["session_id"] = mSessionID; +	mStatsSD["agent_id"] = mAgentID; +	mStatsSD["message"] = "ViewerAssetMetrics"; +	mStatsSD["sequence"] = report_sequence; +	mStatsSD["initial"] = initial_report; +	mStatsSD["version"] = metrics_data_version; +	mStatsSD["break"] = static_cast<bool>(LLTextureFetch::svMetricsDataBreak);  	// Update sequence number  	if (S32_MAX == ++report_sequence) @@ -4040,8 +4046,13 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher)  	// Limit the size of the stats report if necessary. -	sd["truncated"] = truncate_viewer_metrics(10, sd); +	mStatsSD["truncated"] = truncate_viewer_metrics(10, mStatsSD); +    if (gSavedSettings.getBOOL("QAModeMetrics")) +    { +        dump_sequential_xml("metric_asset_stats",mStatsSD); +    } +              	if (! mCapsURL.empty())  	{  		// Don't care about handle, this is a fire-and-forget operation.   @@ -4049,7 +4060,7 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher)  											fetcher->getMetricsPolicyClass(),  											report_priority,  											mCapsURL, -											sd, +											mStatsSD,  											LLCore::HttpOptions::ptr_t(),  											fetcher->getMetricsHeaders(),  											mHandler); @@ -4063,7 +4074,7 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher)  	// In QA mode, Metrics submode, log the result for ease of testing  	if (fetcher->isQAMode())  	{ -		LL_INFOS(LOG_TXT) << ll_pretty_print_sd(sd) << LL_ENDL; +		LL_INFOS(LOG_TXT) << "ViewerAssetMetrics as submitted\n" << ll_pretty_print_sd(mStatsSD) << LL_ENDL;  	}  	return true; @@ -4580,7 +4591,7 @@ void LLTextureFetchDebugger::debugHTTP()  		return;  	} -	mHTTPUrl = region->getHttpUrl(); +	mHTTPUrl = region->getViewerAssetUrl();  	if (mHTTPUrl.empty())  	{  		LL_INFOS(LOG_TXT) << "Fetch Debugger : Current region URL undefined. Cannot fetch textures through HTTP." << LL_ENDL; diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index 072e6a3307..cfa312ccd9 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -160,7 +160,7 @@ public:  	void commandSendMetrics(const std::string & caps_url,  							const LLUUID & session_id,  							const LLUUID & agent_id, -							LLViewerAssetStats * main_stats); +							LLSD& stats_sd);  	// Threads:  T*  	void commandDataBreak(); diff --git a/indra/newview/llviewerassetstats.cpp b/indra/newview/llviewerassetstats.cpp index 54ac29723f..14e05fd440 100644 --- a/indra/newview/llviewerassetstats.cpp +++ b/indra/newview/llviewerassetstats.cpp @@ -80,6 +80,47 @@   *   */ +namespace LLTrace +{ +// This little bit of shimmery is to allow the creation of +// default-constructed stat and event handles so we can make arrays of +// the things. + +// The only sensible way to use this function is to immediately make a +// copy of the contents, since it always returns the same pointer. +const char *makeNewAutoName() +{ +    static char name[64]; +    static S32 auto_namer_number = 0; +    snprintf(name,64,"auto_name_%d",auto_namer_number); +    auto_namer_number++; +    return name; +} + +template <typename T = F64> +class DCCountStatHandle: +        public CountStatHandle<T> +{ +public: +    DCCountStatHandle(const char *name = makeNewAutoName(), const char *description=NULL): +        CountStatHandle<T>(name,description) +    { +    } +}; + +template <typename T = F64> +class DCEventStatHandle: +        public EventStatHandle<T> +{ +public: +    DCEventStatHandle(const char *name = makeNewAutoName(), const char *description=NULL): +        EventStatHandle<T>(name,description) +    { +    } +}; + +} +  namespace LLViewerAssetStatsFF  {  	static EViewerAssetCategories asset_type_to_category(const LLViewerAssetType::EType at, bool with_http, bool is_temp) @@ -90,176 +131,45 @@ namespace LLViewerAssetStatsFF  		//  - wearables (clothing, bodyparts) which directly affect  		//    user experiences when they log in  		//  - sounds -		//  - gestures +		//  - gestures, including animations  		//  - everything else.  		// -		llassert_always(50 == LLViewerAssetType::AT_COUNT); -		// Multiple asset definitions are floating around so this requires some -		// maintenance and attention. -		static const EViewerAssetCategories asset_to_bin_map[LLViewerAssetType::AT_COUNT] = -		{ -			EVACTextureTempHTTPGet,			// (0) AT_TEXTURE -			EVACSoundUDPGet,				// AT_SOUND -			EVACOtherGet,					// AT_CALLINGCARD -			EVACOtherGet,					// AT_LANDMARK -			EVACOtherGet,					// AT_SCRIPT -			EVACWearableUDPGet,				// AT_CLOTHING -			EVACOtherGet,					// AT_OBJECT -			EVACOtherGet,					// AT_NOTECARD -			EVACOtherGet,					// AT_CATEGORY -			EVACOtherGet,					// AT_ROOT_CATEGORY -			EVACOtherGet,					// (10) AT_LSL_TEXT -			EVACOtherGet,					// AT_LSL_BYTECODE -			EVACOtherGet,					// AT_TEXTURE_TGA -			EVACWearableUDPGet,				// AT_BODYPART -			EVACOtherGet,					// AT_TRASH -			EVACOtherGet,					// AT_SNAPSHOT_CATEGORY -			EVACOtherGet,					// AT_LOST_AND_FOUND -			EVACSoundUDPGet,				// AT_SOUND_WAV -			EVACOtherGet,					// AT_IMAGE_TGA -			EVACOtherGet,					// AT_IMAGE_JPEG -			EVACGestureUDPGet,				// (20) AT_ANIMATION -			EVACGestureUDPGet,				// AT_GESTURE -			EVACOtherGet,					// AT_SIMSTATE -			EVACOtherGet,					// AT_FAVORITE -			EVACOtherGet,					// AT_LINK -			EVACOtherGet,					// AT_LINK_FOLDER -			EVACOtherGet,					//  -			EVACOtherGet,					//  -			EVACOtherGet,					//  -			EVACOtherGet,					//  -			EVACOtherGet,					// (30) -			EVACOtherGet,					//  -			EVACOtherGet,					//  -			EVACOtherGet,					//  -			EVACOtherGet,					//  -			EVACOtherGet,					//  -			EVACOtherGet,					//  -			EVACOtherGet,					//  -			EVACOtherGet,					//  -			EVACOtherGet,					//  -			EVACOtherGet,					// (40) -			EVACOtherGet,					//  -			EVACOtherGet,					//  -			EVACOtherGet,					//  -			EVACOtherGet,					//  -			EVACOtherGet,					// -			EVACOtherGet,					//  -			EVACOtherGet,					//  -			EVACOtherGet,					//  -			EVACOtherGet,					// AT_MESH -			// (50) -		}; - -		if (at < 0 || at >= LLViewerAssetType::AT_COUNT) -		{ -			return EVACOtherGet; -		} -		EViewerAssetCategories ret(asset_to_bin_map[at]); -		if (EVACTextureTempHTTPGet == ret) -		{ -			// Indexed with [is_temp][with_http] -			static const EViewerAssetCategories texture_bin_map[2][2] = -			{ -				{ -					EVACTextureNonTempUDPGet, -					EVACTextureNonTempHTTPGet, -				}, -				{ -					EVACTextureTempUDPGet, -					EVACTextureTempHTTPGet, -				} -			}; -	 -			ret = texture_bin_map[is_temp][with_http]; -		} +        EViewerAssetCategories ret; +        switch (at) +        { +            case LLAssetType::AT_TEXTURE: +                if (is_temp) +                    ret = with_http ? EVACTextureTempHTTPGet : EVACTextureTempUDPGet; +                else +                    ret = with_http ? EVACTextureNonTempHTTPGet : EVACTextureNonTempUDPGet; +                break; +            case LLAssetType::AT_SOUND: +            case LLAssetType::AT_SOUND_WAV: +                ret = with_http ? EVACSoundHTTPGet : EVACSoundUDPGet; +                break; +            case LLAssetType::AT_CLOTHING: +            case LLAssetType::AT_BODYPART: +                ret = with_http ? EVACWearableHTTPGet : EVACWearableUDPGet; +                break; +            case LLAssetType::AT_ANIMATION: +            case LLAssetType::AT_GESTURE: +                ret = with_http ? EVACGestureHTTPGet : EVACGestureUDPGet; +                break; +            case LLAssetType::AT_LANDMARK: +                ret = with_http ? EVACLandmarkHTTPGet : EVACLandmarkUDPGet; +                break; +            default: +                ret = with_http ? EVACOtherHTTPGet : EVACOtherUDPGet; +                break; +        }  		return ret;  	} -	static LLTrace::CountStatHandle<> sEnqueueAssetRequestsTempTextureHTTP   ("enqueuedassetrequeststemptexturehttp",  -																	"Number of temporary texture asset http requests enqueued"), -							sEnqueueAssetRequestsTempTextureUDP    ("enqueuedassetrequeststemptextureudp",  -																	"Number of temporary texture asset udp requests enqueued"), -							sEnqueueAssetRequestsNonTempTextureHTTP("enqueuedassetrequestsnontemptexturehttp",  -																	"Number of texture asset http requests enqueued"), -							sEnqueueAssetRequestsNonTempTextureUDP ("enqueuedassetrequestsnontemptextureudp",  -																	"Number of texture asset udp requests enqueued"), -							sEnqueuedAssetRequestsWearableUdp      ("enqueuedassetrequestswearableudp",  -																	"Number of wearable asset requests enqueued"), -							sEnqueuedAssetRequestsSoundUdp         ("enqueuedassetrequestssoundudp",  -																	"Number of sound asset requests enqueued"), -							sEnqueuedAssetRequestsGestureUdp       ("enqueuedassetrequestsgestureudp",  -																	"Number of gesture asset requests enqueued"), -							sEnqueuedAssetRequestsOther            ("enqueuedassetrequestsother",  -																	"Number of other asset requests enqueued"); - -	static LLTrace::CountStatHandle<>* sEnqueued[EVACCount] = {		 -		&sEnqueueAssetRequestsTempTextureHTTP,    -		&sEnqueueAssetRequestsTempTextureUDP,   -		&sEnqueueAssetRequestsNonTempTextureHTTP, -		&sEnqueueAssetRequestsNonTempTextureUDP, -		&sEnqueuedAssetRequestsWearableUdp, -		&sEnqueuedAssetRequestsSoundUdp, -		&sEnqueuedAssetRequestsGestureUdp, -		&sEnqueuedAssetRequestsOther             -	}; -	 -	static LLTrace::CountStatHandle<> sDequeueAssetRequestsTempTextureHTTP   ("dequeuedassetrequeststemptexturehttp",  -																	"Number of temporary texture asset http requests dequeued"), -							sDequeueAssetRequestsTempTextureUDP    ("dequeuedassetrequeststemptextureudp",  -																	"Number of temporary texture asset udp requests dequeued"), -							sDequeueAssetRequestsNonTempTextureHTTP("dequeuedassetrequestsnontemptexturehttp",  -																	"Number of texture asset http requests dequeued"), -							sDequeueAssetRequestsNonTempTextureUDP ("dequeuedassetrequestsnontemptextureudp",  -																	"Number of texture asset udp requests dequeued"), -							sDequeuedAssetRequestsWearableUdp      ("dequeuedassetrequestswearableudp",  -																	"Number of wearable asset requests dequeued"), -							sDequeuedAssetRequestsSoundUdp         ("dequeuedassetrequestssoundudp",  -																	"Number of sound asset requests dequeued"), -							sDequeuedAssetRequestsGestureUdp       ("dequeuedassetrequestsgestureudp",  -																	"Number of gesture asset requests dequeued"), -							sDequeuedAssetRequestsOther            ("dequeuedassetrequestsother",  -																	"Number of other asset requests dequeued"); - -	static LLTrace::CountStatHandle<>* sDequeued[EVACCount] = { -		&sDequeueAssetRequestsTempTextureHTTP,    -		&sDequeueAssetRequestsTempTextureUDP,   -		&sDequeueAssetRequestsNonTempTextureHTTP, -		&sDequeueAssetRequestsNonTempTextureUDP, -		&sDequeuedAssetRequestsWearableUdp, -		&sDequeuedAssetRequestsSoundUdp, -		&sDequeuedAssetRequestsGestureUdp, -		&sDequeuedAssetRequestsOther             -	}; - -	static LLTrace::EventStatHandle<F64Seconds >	sResponseAssetRequestsTempTextureHTTP   ("assetresponsetimestemptexturehttp", -																							"Time spent responding to temporary texture asset http requests"), -													sResponseAssetRequestsTempTextureUDP    ("assetresponsetimestemptextureudp",  -																							"Time spent responding to temporary texture asset udp requests"), -													sResponseAssetRequestsNonTempTextureHTTP("assetresponsetimesnontemptexturehttp",  -																							"Time spent responding to texture asset http requests"), -													sResponseAssetRequestsNonTempTextureUDP ("assetresponsetimesnontemptextureudp",  -																							"Time spent responding to texture asset udp requests"), -													sResponsedAssetRequestsWearableUdp      ("assetresponsetimeswearableudp",  -																							"Time spent responding to wearable asset requests"), -													sResponsedAssetRequestsSoundUdp         ("assetresponsetimessoundudp",  -																							"Time spent responding to sound asset requests"), -													sResponsedAssetRequestsGestureUdp       ("assetresponsetimesgestureudp",  -																							"Time spent responding to gesture asset requests"), -													sResponsedAssetRequestsOther            ("assetresponsetimesother",  -																							"Time spent responding to other asset requests"); - -	static LLTrace::EventStatHandle<F64Seconds >* sResponse[EVACCount] = { -		&sResponseAssetRequestsTempTextureHTTP,    -		&sResponseAssetRequestsTempTextureUDP,   -		&sResponseAssetRequestsNonTempTextureHTTP, -		&sResponseAssetRequestsNonTempTextureUDP, -		&sResponsedAssetRequestsWearableUdp, -		&sResponsedAssetRequestsSoundUdp, -		&sResponsedAssetRequestsGestureUdp, -		&sResponsedAssetRequestsOther             -	}; +	static LLTrace::DCCountStatHandle<> sEnqueued[EVACCount]; +	static LLTrace::DCCountStatHandle<> sDequeued[EVACCount]; +	static LLTrace::DCEventStatHandle<> sBytesFetched[EVACCount]; +	static LLTrace::DCEventStatHandle<F64Seconds > sResponse[EVACCount];  }  // ------------------------------------------------------ @@ -353,6 +263,26 @@ void LLViewerAssetStats::setRegion(region_handle_t region_handle)  	mRegionHandle = region_handle;  } +template <typename T> +void LLViewerAssetStats::getStat(LLTrace::Recording& rec, T& req, LLViewerAssetStatsFF::EViewerAssetCategories cat, bool compact_output) +{ +	using namespace LLViewerAssetStatsFF; + +    if (!compact_output +        || rec.getSampleCount(sEnqueued[cat])  +        || rec.getSampleCount(sDequeued[cat]) +        || rec.getSampleCount(sResponse[cat])) +    { +        req	.enqueued(rec.getSampleCount(sEnqueued[cat])) +            .dequeued(rec.getSampleCount(sDequeued[cat])) +            .resp_count(rec.getSampleCount(sResponse[cat])) +            .resp_min(rec.getMin(sResponse[cat]).value()) +            .resp_max(rec.getMax(sResponse[cat]).value()) +            .resp_mean(rec.getMean(sResponse[cat]).value()) +            .resp_mean_bytes(rec.getMean(sBytesFetched[cat])); +    } +} +  void LLViewerAssetStats::getStats(AssetStats& stats, bool compact_output)  {  	using namespace LLViewerAssetStatsFF; @@ -365,108 +295,22 @@ void LLViewerAssetStats::getStats(AssetStats& stats, bool compact_output)  	{  		RegionStats& r = stats.regions.add();  		LLTrace::Recording& rec = it->second; -		if (!compact_output -			|| rec.getSum(*sEnqueued[EVACTextureTempHTTPGet])  -			|| rec.getSum(*sDequeued[EVACTextureTempHTTPGet]) -			|| rec.getSum(*sResponse[EVACTextureTempHTTPGet]).value()) -		{ -			r.get_texture_temp_http	.enqueued((S32)rec.getSum(*sEnqueued[EVACTextureTempHTTPGet])) -									.dequeued((S32)rec.getSum(*sDequeued[EVACTextureTempHTTPGet])) -									.resp_count((S32)rec.getSum(*sResponse[EVACTextureTempHTTPGet]).value()) -									.resp_min(rec.getMin(*sResponse[EVACTextureTempHTTPGet]).value()) -									.resp_max(rec.getMax(*sResponse[EVACTextureTempHTTPGet]).value()) -									.resp_mean(rec.getMean(*sResponse[EVACTextureTempHTTPGet]).value()); -		} -		if (!compact_output -			|| rec.getSum(*sEnqueued[EVACTextureTempUDPGet])  -			|| rec.getSum(*sDequeued[EVACTextureTempUDPGet]) -			|| rec.getSum(*sResponse[EVACTextureTempUDPGet]).value()) -		{ -			r.get_texture_temp_udp	.enqueued((S32)rec.getSum(*sEnqueued[EVACTextureTempUDPGet])) -									.dequeued((S32)rec.getSum(*sDequeued[EVACTextureTempUDPGet])) -									.resp_count((S32)rec.getSum(*sResponse[EVACTextureTempUDPGet]).value()) -									.resp_min(rec.getMin(*sResponse[EVACTextureTempUDPGet]).value()) -									.resp_max(rec.getMax(*sResponse[EVACTextureTempUDPGet]).value()) -									.resp_mean(rec.getMean(*sResponse[EVACTextureTempUDPGet]).value()); -		} -		if (!compact_output -			|| rec.getSum(*sEnqueued[EVACTextureNonTempHTTPGet])  -			|| rec.getSum(*sDequeued[EVACTextureNonTempHTTPGet]) -			|| rec.getSum(*sResponse[EVACTextureNonTempHTTPGet]).value()) -		{ -			r.get_texture_non_temp_http	.enqueued((S32)rec.getSum(*sEnqueued[EVACTextureNonTempHTTPGet])) -										.dequeued((S32)rec.getSum(*sDequeued[EVACTextureNonTempHTTPGet])) -										.resp_count((S32)rec.getSum(*sResponse[EVACTextureNonTempHTTPGet]).value()) -										.resp_min(rec.getMin(*sResponse[EVACTextureNonTempHTTPGet]).value()) -										.resp_max(rec.getMax(*sResponse[EVACTextureNonTempHTTPGet]).value()) -										.resp_mean(rec.getMean(*sResponse[EVACTextureNonTempHTTPGet]).value()); -		} - -		if (!compact_output -			|| rec.getSum(*sEnqueued[EVACTextureNonTempUDPGet])  -			|| rec.getSum(*sDequeued[EVACTextureNonTempUDPGet]) -			|| rec.getSum(*sResponse[EVACTextureNonTempUDPGet]).value()) -		{ -			r.get_texture_non_temp_udp	.enqueued((S32)rec.getSum(*sEnqueued[EVACTextureNonTempUDPGet])) -										.dequeued((S32)rec.getSum(*sDequeued[EVACTextureNonTempUDPGet])) -										.resp_count((S32)rec.getSum(*sResponse[EVACTextureNonTempUDPGet]).value()) -										.resp_min(rec.getMin(*sResponse[EVACTextureNonTempUDPGet]).value()) -										.resp_max(rec.getMax(*sResponse[EVACTextureNonTempUDPGet]).value()) -										.resp_mean(rec.getMean(*sResponse[EVACTextureNonTempUDPGet]).value()); -		} - -		if (!compact_output -			|| rec.getSum(*sEnqueued[EVACWearableUDPGet])  -			|| rec.getSum(*sDequeued[EVACWearableUDPGet]) -			|| rec.getSum(*sResponse[EVACWearableUDPGet]).value()) -		{ -			r.get_wearable_udp	.enqueued((S32)rec.getSum(*sEnqueued[EVACWearableUDPGet])) -								.dequeued((S32)rec.getSum(*sDequeued[EVACWearableUDPGet])) -								.resp_count((S32)rec.getSum(*sResponse[EVACWearableUDPGet]).value()) -								.resp_min(rec.getMin(*sResponse[EVACWearableUDPGet]).value()) -								.resp_max(rec.getMax(*sResponse[EVACWearableUDPGet]).value()) -								.resp_mean(rec.getMean(*sResponse[EVACWearableUDPGet]).value()); -		} - -		if (!compact_output -			|| rec.getSum(*sEnqueued[EVACSoundUDPGet])  -			|| rec.getSum(*sDequeued[EVACSoundUDPGet]) -			|| rec.getSum(*sResponse[EVACSoundUDPGet]).value()) -		{ -			r.get_sound_udp	.enqueued((S32)rec.getSum(*sEnqueued[EVACSoundUDPGet])) -							.dequeued((S32)rec.getSum(*sDequeued[EVACSoundUDPGet])) -							.resp_count((S32)rec.getSum(*sResponse[EVACSoundUDPGet]).value()) -							.resp_min(rec.getMin(*sResponse[EVACSoundUDPGet]).value()) -							.resp_max(rec.getMax(*sResponse[EVACSoundUDPGet]).value()) -							.resp_mean(rec.getMean(*sResponse[EVACSoundUDPGet]).value()); -		} - -		if (!compact_output -			|| rec.getSum(*sEnqueued[EVACGestureUDPGet])  -			|| rec.getSum(*sDequeued[EVACGestureUDPGet]) -			|| rec.getSum(*sResponse[EVACGestureUDPGet]).value()) -		{ -			r.get_gesture_udp	.enqueued((S32)rec.getSum(*sEnqueued[EVACGestureUDPGet])) -								.dequeued((S32)rec.getSum(*sDequeued[EVACGestureUDPGet])) -								.resp_count((S32)rec.getSum(*sResponse[EVACGestureUDPGet]).value()) -								.resp_min(rec.getMin(*sResponse[EVACGestureUDPGet]).value()) -								.resp_max(rec.getMax(*sResponse[EVACGestureUDPGet]).value()) -								.resp_mean(rec.getMean(*sResponse[EVACGestureUDPGet]).value()); -		} -			 -		if (!compact_output -			|| rec.getSum(*sEnqueued[EVACOtherGet])  -			|| rec.getSum(*sDequeued[EVACOtherGet]) -			|| rec.getSum(*sResponse[EVACOtherGet]).value()) -			{ -			r.get_other	.enqueued((S32)rec.getSum(*sEnqueued[EVACOtherGet])) -						.dequeued((S32)rec.getSum(*sDequeued[EVACOtherGet])) -						.resp_count((S32)rec.getSum(*sResponse[EVACOtherGet]).value()) -						.resp_min(rec.getMin(*sResponse[EVACOtherGet]).value()) -						.resp_max(rec.getMax(*sResponse[EVACOtherGet]).value()) -						.resp_mean(rec.getMean(*sResponse[EVACOtherGet]).value()); -		} +        getStat(rec, r.get_texture_temp_http, EVACTextureTempHTTPGet, compact_output); +        getStat(rec, r.get_texture_temp_udp, EVACTextureTempUDPGet, compact_output); +        getStat(rec, r.get_texture_non_temp_http, EVACTextureNonTempHTTPGet, compact_output); +        getStat(rec, r.get_texture_non_temp_udp, EVACTextureNonTempUDPGet, compact_output); +        getStat(rec, r.get_wearable_http, EVACWearableHTTPGet, compact_output); +        getStat(rec, r.get_wearable_udp, EVACWearableUDPGet, compact_output); +        getStat(rec, r.get_sound_http, EVACSoundHTTPGet, compact_output); +        getStat(rec, r.get_sound_udp, EVACSoundUDPGet, compact_output); +        getStat(rec, r.get_gesture_http, EVACGestureHTTPGet, compact_output); +        getStat(rec, r.get_gesture_udp, EVACGestureUDPGet, compact_output); +        getStat(rec, r.get_landmark_http, EVACLandmarkHTTPGet, compact_output); +        getStat(rec, r.get_landmark_udp, EVACLandmarkUDPGet, compact_output); +        getStat(rec, r.get_other_http, EVACOtherHTTPGet, compact_output); +        getStat(rec, r.get_other_udp, EVACOtherUDPGet, compact_output); +          		S32 fps = (S32)rec.getLastValue(LLStatViewer::FPS_SAMPLE);  		if (!compact_output || fps != 0)  		{ @@ -479,10 +323,10 @@ void LLViewerAssetStats::getStats(AssetStats& stats, bool compact_output)  		grid_from_region_handle(it->first, &grid_x, &grid_y);  		r	.grid_x(grid_x)  			.grid_y(grid_y) -			.duration(F64Microseconds(rec.getDuration()).value()); +			.duration(F64Seconds(rec.getDuration()).value());  	} -	stats.duration(mCurRecording ? F64Microseconds(mCurRecording->getDuration()).value() : 0.0); +	stats.duration(mCurRecording ? F64Seconds(mCurRecording->getDuration()).value() : 0.0);  }  LLSD LLViewerAssetStats::asLLSD(bool compact_output) @@ -518,21 +362,22 @@ void record_enqueue(LLViewerAssetType::EType at, bool with_http, bool is_temp)  {  	const EViewerAssetCategories eac(asset_type_to_category(at, with_http, is_temp)); -	add(*sEnqueued[int(eac)], 1); +	add(sEnqueued[int(eac)], 1);  }  void record_dequeue(LLViewerAssetType::EType at, bool with_http, bool is_temp)  {  	const EViewerAssetCategories eac(asset_type_to_category(at, with_http, is_temp)); -	add(*sDequeued[int(eac)], 1); +	add(sDequeued[int(eac)], 1);  } -void record_response(LLViewerAssetType::EType at, bool with_http, bool is_temp, LLViewerAssetStats::duration_t duration) +void record_response(LLViewerAssetType::EType at, bool with_http, bool is_temp, LLViewerAssetStats::duration_t duration, F64 bytes)  {  	const EViewerAssetCategories eac(asset_type_to_category(at, with_http, is_temp)); -	record(*sResponse[int(eac)], F64Microseconds(duration)); +	record(sResponse[int(eac)], F64Seconds(duration)); +	record(sBytesFetched[int(eac)], bytes);  }  void init() @@ -561,7 +406,8 @@ LLViewerAssetStats::AssetRequestType::AssetRequestType()  	resp_count("resp_count"),  	resp_min("resp_min"),  	resp_max("resp_max"), -	resp_mean("resp_mean") +	resp_mean("resp_mean"), +    resp_mean_bytes("resp_mean_bytes")  {}  LLViewerAssetStats::FPSStats::FPSStats()  @@ -576,10 +422,16 @@ LLViewerAssetStats::RegionStats::RegionStats()  	get_texture_temp_udp("get_texture_temp_udp"),  	get_texture_non_temp_http("get_texture_non_temp_http"),  	get_texture_non_temp_udp("get_texture_non_temp_udp"), +	get_wearable_http("get_wearable_http"),  	get_wearable_udp("get_wearable_udp"), +	get_sound_http("get_sound_http"),  	get_sound_udp("get_sound_udp"), +	get_gesture_http("get_gesture_http"),  	get_gesture_udp("get_gesture_udp"), -	get_other("get_other"), +	get_landmark_http("get_landmark_http"), +	get_landmark_udp("get_landmark_udp"), +	get_other_http("get_other_http"), +	get_other_udp("get_other_udp"),  	fps("fps"),  	grid_x("grid_x"),  	grid_y("grid_y"), diff --git a/indra/newview/llviewerassetstats.h b/indra/newview/llviewerassetstats.h index 9d425c82fc..718c284224 100644 --- a/indra/newview/llviewerassetstats.h +++ b/indra/newview/llviewerassetstats.h @@ -39,6 +39,29 @@  #include "lltrace.h"  #include "llinitparam.h" +namespace LLViewerAssetStatsFF +{ +	enum EViewerAssetCategories +	{ +		EVACTextureTempHTTPGet,			//< Texture GETs - temp/baked, HTTP +		EVACTextureTempUDPGet,			//< Texture GETs - temp/baked, UDP +		EVACTextureNonTempHTTPGet,		//< Texture GETs - perm, HTTP +		EVACTextureNonTempUDPGet,		//< Texture GETs - perm, UDP +		EVACWearableHTTPGet,			//< Wearable GETs HTTP +		EVACWearableUDPGet,				//< Wearable GETs UDP +		EVACSoundHTTPGet,				//< Sound GETs HTTP +		EVACSoundUDPGet,				//< Sound GETs UDP +		EVACGestureHTTPGet,				//< Gesture GETs HTTP +		EVACGestureUDPGet,				//< Gesture GETs UDP +		EVACLandmarkHTTPGet,			//< Landmark GETs HTTP +		EVACLandmarkUDPGet,				//< Landmark GETs UDP +		EVACOtherHTTPGet,				//< Other GETs HTTP +		EVACOtherUDPGet,				//< Other GETs UDP + +		EVACCount						// Must be last +	}; +} +  /**   * @class LLViewerAssetStats   * @brief Records performance aspects of asset access operations. @@ -74,6 +97,7 @@   * LLViewerAssetStatsFF is provided for conditional test-and-call   * operations.   */ +  class LLViewerAssetStats : public LLStopWatchControlsMixin<LLViewerAssetStats>  {  public: @@ -98,13 +122,14 @@ public:  						resp_count;  		Mandatory<F64>	resp_min,  						resp_max, -						resp_mean; +						resp_mean, +						resp_mean_bytes;  		AssetRequestType();  	};  	struct FPSStats : public LLInitParam::Block<FPSStats> -			{ +    {  		Mandatory<S32>	count;  		Mandatory<F64>	min,  						max, @@ -113,15 +138,21 @@ public:  	};  	struct RegionStats : public LLInitParam::Block<RegionStats> -				{ +    {  		Optional<AssetRequestType>	get_texture_temp_http,  									get_texture_temp_udp,  									get_texture_non_temp_http,  									get_texture_non_temp_udp, +									get_wearable_http,  									get_wearable_udp, +									get_sound_http,  									get_sound_udp, +									get_gesture_http,  									get_gesture_udp, -									get_other; +									get_landmark_http, +									get_landmark_udp, +									get_other_http, +									get_other_udp;  		Optional<FPSStats>			fps;  		Optional<S32>				grid_x,  									grid_y; @@ -165,6 +196,11 @@ public:  	// Retrieve current metrics for all visited regions (NULL region UUID/handle excluded)      // Uses AssetStats structure seen above  	void getStats(AssetStats& stats, bool compact_output); + +    // Retrieve a single asset request type (taken from a single region) +    template <typename T> +    void getStat(LLTrace::Recording& rec, T& req, LLViewerAssetStatsFF::EViewerAssetCategories cat, bool compact_output); +  	LLSD asLLSD(bool compact_output);  protected: @@ -205,19 +241,6 @@ extern LLViewerAssetStats * gViewerAssetStats;  namespace LLViewerAssetStatsFF  { -	enum EViewerAssetCategories -	{ -		EVACTextureTempHTTPGet,			//< Texture GETs - temp/baked, HTTP -		EVACTextureTempUDPGet,			//< Texture GETs - temp/baked, UDP -		EVACTextureNonTempHTTPGet,		//< Texture GETs - perm, HTTP -		EVACTextureNonTempUDPGet,		//< Texture GETs - perm, UDP -		EVACWearableUDPGet,				//< Wearable GETs -		EVACSoundUDPGet,				//< Sound GETs -		EVACGestureUDPGet,				//< Gesture GETs -		EVACOtherGet,					//< Other GETs - -		EVACCount						// Must be last -	};  /**   * @brief Allocation and deallocation of globals. @@ -250,7 +273,7 @@ void record_enqueue(LLViewerAssetType::EType at, bool with_http, bool is_temp);  void record_dequeue(LLViewerAssetType::EType at, bool with_http, bool is_temp);  void record_response(LLViewerAssetType::EType at, bool with_http, bool is_temp, -						  LLViewerAssetStats::duration_t duration); +                     LLViewerAssetStats::duration_t duration, F64 bytes=0);  void record_avatar_stats(); diff --git a/indra/newview/llviewerassetstorage.cpp b/indra/newview/llviewerassetstorage.cpp index 2db9c7e67c..e0b64403ef 100644 --- a/indra/newview/llviewerassetstorage.cpp +++ b/indra/newview/llviewerassetstorage.cpp @@ -33,9 +33,17 @@  #include "message.h"  #include "llagent.h" +#include "llappcorehttp.h" +#include "llviewerregion.h" +  #include "lltransfersourceasset.h"  #include "lltransfertargetvfile.h"  #include "llviewerassetstats.h" +#include "llcoros.h" +#include "llcoproceduremanager.h" +#include "lleventcoro.h" +#include "llsdutil.h" +#include "llworld.h"  ///----------------------------------------------------------------------------  /// LLViewerAssetRequest @@ -51,267 +59,283 @@  class LLViewerAssetRequest : public LLAssetRequest  {  public: -	LLViewerAssetRequest(const LLUUID &uuid, const LLAssetType::EType type) -		: LLAssetRequest(uuid, type), -		  mMetricsStartTime(0) -		{ -		} -	 -	LLViewerAssetRequest & operator=(const LLViewerAssetRequest &);	// Not defined -	// Default assignment operator valid -	 -	// virtual -	~LLViewerAssetRequest() -		{ -			recordMetrics(); -		} +    LLViewerAssetRequest(const LLUUID &uuid, const LLAssetType::EType type, bool with_http) +        : LLAssetRequest(uuid, type), +          mMetricsStartTime(0), +          mWithHTTP(with_http) +    { +    } +     +    LLViewerAssetRequest & operator=(const LLViewerAssetRequest &); // Not defined +    // Default assignment operator valid +     +    // virtual +    ~LLViewerAssetRequest() +    { +        recordMetrics(); +    }  protected: -	void recordMetrics() -		{ -			if (mMetricsStartTime.value()) -			{ -				// Okay, it appears this request was used for useful things.  Record -				// the expected dequeue and duration of request processing. -				LLViewerAssetStatsFF::record_dequeue(mType, false, false); -				LLViewerAssetStatsFF::record_response(mType, false, false, -														   (LLViewerAssetStatsFF::get_timestamp() -															- mMetricsStartTime)); -				mMetricsStartTime = (U32Seconds)0; -			} -		} -	 +    void recordMetrics() +    { +        if (mMetricsStartTime.value()) +        { +            // Okay, it appears this request was used for useful things.  Record +            // the expected dequeue and duration of request processing. +            LLViewerAssetStatsFF::record_dequeue(mType, mWithHTTP, false); +            LLViewerAssetStatsFF::record_response(mType, mWithHTTP, false, +                                                  (LLViewerAssetStatsFF::get_timestamp() +                                                   - mMetricsStartTime), +                                                  mBytesFetched); +            mMetricsStartTime = (U32Seconds)0; +        } +    } +      public: -	LLViewerAssetStats::duration_t		mMetricsStartTime; +    LLViewerAssetStats::duration_t      mMetricsStartTime; +    bool mWithHTTP;  };  ///----------------------------------------------------------------------------  /// LLViewerAssetStorage  ///---------------------------------------------------------------------------- +// Unused?  LLViewerAssetStorage::LLViewerAssetStorage(LLMessageSystem *msg, LLXferManager *xfer, -										   LLVFS *vfs, LLVFS *static_vfs,  -										   const LLHost &upstream_host) -		: LLAssetStorage(msg, xfer, vfs, static_vfs, upstream_host) +                                           LLVFS *vfs, LLVFS *static_vfs,  +                                           const LLHost &upstream_host) +    : LLAssetStorage(msg, xfer, vfs, static_vfs, upstream_host), +      mAssetCoroCount(0), +      mCountRequests(0), +      mCountStarted(0), +      mCountCompleted(0), +      mCountSucceeded(0), +      mTotalBytesFetched(0)  {  }  LLViewerAssetStorage::LLViewerAssetStorage(LLMessageSystem *msg, LLXferManager *xfer, -										   LLVFS *vfs, LLVFS *static_vfs) -		: LLAssetStorage(msg, xfer, vfs, static_vfs) +                                           LLVFS *vfs, LLVFS *static_vfs) +    : LLAssetStorage(msg, xfer, vfs, static_vfs), +      mAssetCoroCount(0), +      mCountRequests(0), +      mCountStarted(0), +      mCountCompleted(0), +      mCountSucceeded(0), +      mTotalBytesFetched(0)  {  }  // virtual   void LLViewerAssetStorage::storeAssetData( -	const LLTransactionID& tid, -	LLAssetType::EType asset_type, -	LLStoreAssetCallback callback, -	void* user_data, -	bool temp_file, -	bool is_priority, -	bool store_local, -	bool user_waiting, -	F64Seconds timeout) +    const LLTransactionID& tid, +    LLAssetType::EType asset_type, +    LLStoreAssetCallback callback, +    void* user_data, +    bool temp_file, +    bool is_priority, +    bool store_local, +    bool user_waiting, +    F64Seconds timeout)  { -	LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); -	LL_DEBUGS("AssetStorage") << "LLViewerAssetStorage::storeAssetData (legacy) " << tid << ":" << LLAssetType::lookup(asset_type) -			<< " ASSET_ID: " << asset_id << LL_ENDL; -	 -	if (mUpstreamHost.isOk()) -	{ -		if (mVFS->getExists(asset_id, asset_type)) -		{ -			// Pack data into this packet if we can fit it. -			U8 buffer[MTUBYTES]; -			buffer[0] = 0; - -			LLVFile vfile(mVFS, asset_id, asset_type, LLVFile::READ); -			S32 asset_size = vfile.getSize(); - -			LLAssetRequest *req = new LLAssetRequest(asset_id, asset_type); -			req->mUpCallback = callback; -			req->mUserData = user_data; - -			if (asset_size < 1) -			{ -				// This can happen if there's a bug in our code or if the VFS has been corrupted. -				LL_WARNS() << "LLViewerAssetStorage::storeAssetData()  Data _should_ already be in the VFS, but it's not! " << asset_id << LL_ENDL; -				// LLAssetStorage metric: Zero size VFS -				reportMetric( asset_id, asset_type, LLStringUtil::null, LLUUID::null, 0, MR_ZERO_SIZE, __FILE__, __LINE__, "The file didn't exist or was zero length (VFS - can't tell which)" ); - -				delete req; -				if (callback) -				{ -					callback(asset_id, user_data, LL_ERR_ASSET_REQUEST_FAILED, LL_EXSTAT_VFS_CORRUPT); -				} -				return; -			} -			else -			{ -				// LLAssetStorage metric: Successful Request -				S32 size = mVFS->getSize(asset_id, asset_type); -				const char *message = "Added to upload queue"; -				reportMetric( asset_id, asset_type, LLStringUtil::null, LLUUID::null, size, MR_OKAY, __FILE__, __LINE__, message ); - -				if(is_priority) -				{ -					mPendingUploads.push_front(req); -				} -				else -				{ -					mPendingUploads.push_back(req); -				} -			} - -			// Read the data from the VFS if it'll fit in this packet. -			if (asset_size + 100 < MTUBYTES) -			{ -				BOOL res = vfile.read(buffer, asset_size);		/* Flawfinder: ignore */ -				S32 bytes_read = res ? vfile.getLastBytesRead() : 0; -				 -				if( bytes_read == asset_size ) -				{ -					req->mDataSentInFirstPacket = TRUE; -					//LL_INFOS() << "LLViewerAssetStorage::createAsset sending data in first packet" << LL_ENDL; -				} -				else -				{ -					LL_WARNS() << "Probable corruption in VFS file, aborting store asset data" << LL_ENDL; - -					// LLAssetStorage metric: VFS corrupt - bogus size -					reportMetric( asset_id, asset_type, LLStringUtil::null, LLUUID::null, asset_size, MR_VFS_CORRUPTION, __FILE__, __LINE__, "VFS corruption" ); - -					if (callback) -					{ -						callback(asset_id, user_data, LL_ERR_ASSET_REQUEST_NONEXISTENT_FILE, LL_EXSTAT_VFS_CORRUPT); -					} -					return; -				} -			} -			else -			{ -				// Too big, do an xfer -				buffer[0] = 0; -				asset_size = 0; -			} -			mMessageSys->newMessageFast(_PREHASH_AssetUploadRequest); -			mMessageSys->nextBlockFast(_PREHASH_AssetBlock); -			mMessageSys->addUUIDFast(_PREHASH_TransactionID, tid); -			mMessageSys->addS8Fast(_PREHASH_Type, (S8)asset_type); -			mMessageSys->addBOOLFast(_PREHASH_Tempfile, temp_file); -			mMessageSys->addBOOLFast(_PREHASH_StoreLocal, store_local); -			mMessageSys->addBinaryDataFast( _PREHASH_AssetData, buffer, asset_size ); -			mMessageSys->sendReliable(mUpstreamHost); -		} -		else -		{ -			LL_WARNS() << "AssetStorage: attempt to upload non-existent vfile " << asset_id << ":" << LLAssetType::lookup(asset_type) << LL_ENDL; -			// LLAssetStorage metric: Zero size VFS -			reportMetric( asset_id, asset_type, LLStringUtil::null, LLUUID::null, 0, MR_ZERO_SIZE, __FILE__, __LINE__, "The file didn't exist or was zero length (VFS - can't tell which)" ); -			if (callback) -			{ -				callback(asset_id, user_data,  LL_ERR_ASSET_REQUEST_NONEXISTENT_FILE, LL_EXSTAT_NONEXISTENT_FILE); -			} -		} -	} -	else -	{ -		LL_WARNS() << "Attempt to move asset store request upstream w/o valid upstream provider" << LL_ENDL; -		// LLAssetStorage metric: Upstream provider dead -		reportMetric( asset_id, asset_type, LLStringUtil::null, LLUUID::null, 0, MR_NO_UPSTREAM, __FILE__, __LINE__, "No upstream provider" ); -		if (callback) -		{ -			callback(asset_id, user_data, LL_ERR_CIRCUIT_GONE, LL_EXSTAT_NO_UPSTREAM); -		} -	} +    LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); +    LL_DEBUGS("AssetStorage") << "LLViewerAssetStorage::storeAssetData (legacy) " << tid << ":" << LLAssetType::lookup(asset_type) +                              << " ASSET_ID: " << asset_id << LL_ENDL; +     +    if (mUpstreamHost.isOk()) +    { +        if (mVFS->getExists(asset_id, asset_type)) +        { +            // Pack data into this packet if we can fit it. +            U8 buffer[MTUBYTES]; +            buffer[0] = 0; + +            LLVFile vfile(mVFS, asset_id, asset_type, LLVFile::READ); +            S32 asset_size = vfile.getSize(); + +            LLAssetRequest *req = new LLAssetRequest(asset_id, asset_type); +            req->mUpCallback = callback; +            req->mUserData = user_data; + +            if (asset_size < 1) +            { +                // This can happen if there's a bug in our code or if the VFS has been corrupted. +                LL_WARNS("AssetStorage") << "LLViewerAssetStorage::storeAssetData()  Data _should_ already be in the VFS, but it's not! " << asset_id << LL_ENDL; +                // LLAssetStorage metric: Zero size VFS +                reportMetric( asset_id, asset_type, LLStringUtil::null, LLUUID::null, 0, MR_ZERO_SIZE, __FILE__, __LINE__, "The file didn't exist or was zero length (VFS - can't tell which)" ); + +                delete req; +                if (callback) +                { +                    callback(asset_id, user_data, LL_ERR_ASSET_REQUEST_FAILED, LL_EXSTAT_VFS_CORRUPT); +                } +                return; +            } +            else +            { +                // LLAssetStorage metric: Successful Request +                S32 size = mVFS->getSize(asset_id, asset_type); +                const char *message = "Added to upload queue"; +                reportMetric( asset_id, asset_type, LLStringUtil::null, LLUUID::null, size, MR_OKAY, __FILE__, __LINE__, message ); + +                if(is_priority) +                { +                    mPendingUploads.push_front(req); +                } +                else +                { +                    mPendingUploads.push_back(req); +                } +            } + +            // Read the data from the VFS if it'll fit in this packet. +            if (asset_size + 100 < MTUBYTES) +            { +                BOOL res = vfile.read(buffer, asset_size);      /* Flawfinder: ignore */ +                S32 bytes_read = res ? vfile.getLastBytesRead() : 0; +                 +                if( bytes_read == asset_size ) +                { +                    req->mDataSentInFirstPacket = TRUE; +                    //LL_INFOS() << "LLViewerAssetStorage::createAsset sending data in first packet" << LL_ENDL; +                } +                else +                { +                    LL_WARNS("AssetStorage") << "Probable corruption in VFS file, aborting store asset data" << LL_ENDL; + +                    // LLAssetStorage metric: VFS corrupt - bogus size +                    reportMetric( asset_id, asset_type, LLStringUtil::null, LLUUID::null, asset_size, MR_VFS_CORRUPTION, __FILE__, __LINE__, "VFS corruption" ); + +                    if (callback) +                    { +                        callback(asset_id, user_data, LL_ERR_ASSET_REQUEST_NONEXISTENT_FILE, LL_EXSTAT_VFS_CORRUPT); +                    } +                    return; +                } +            } +            else +            { +                // Too big, do an xfer +                buffer[0] = 0; +                asset_size = 0; +            } +            mMessageSys->newMessageFast(_PREHASH_AssetUploadRequest); +            mMessageSys->nextBlockFast(_PREHASH_AssetBlock); +            mMessageSys->addUUIDFast(_PREHASH_TransactionID, tid); +            mMessageSys->addS8Fast(_PREHASH_Type, (S8)asset_type); +            mMessageSys->addBOOLFast(_PREHASH_Tempfile, temp_file); +            mMessageSys->addBOOLFast(_PREHASH_StoreLocal, store_local); +            mMessageSys->addBinaryDataFast( _PREHASH_AssetData, buffer, asset_size ); +            mMessageSys->sendReliable(mUpstreamHost); +        } +        else +        { +            LL_WARNS("AssetStorage") << "AssetStorage: attempt to upload non-existent vfile " << asset_id << ":" << LLAssetType::lookup(asset_type) << LL_ENDL; +            // LLAssetStorage metric: Zero size VFS +            reportMetric( asset_id, asset_type, LLStringUtil::null, LLUUID::null, 0, MR_ZERO_SIZE, __FILE__, __LINE__, "The file didn't exist or was zero length (VFS - can't tell which)" ); +            if (callback) +            { +                callback(asset_id, user_data,  LL_ERR_ASSET_REQUEST_NONEXISTENT_FILE, LL_EXSTAT_NONEXISTENT_FILE); +            } +        } +    } +    else +    { +        LL_WARNS("AssetStorage") << "Attempt to move asset store request upstream w/o valid upstream provider" << LL_ENDL; +        // LLAssetStorage metric: Upstream provider dead +        reportMetric( asset_id, asset_type, LLStringUtil::null, LLUUID::null, 0, MR_NO_UPSTREAM, __FILE__, __LINE__, "No upstream provider" ); +        if (callback) +        { +            callback(asset_id, user_data, LL_ERR_CIRCUIT_GONE, LL_EXSTAT_NO_UPSTREAM); +        } +    }  }  void LLViewerAssetStorage::storeAssetData( -	const std::string& filename, -	const LLTransactionID& tid, -	LLAssetType::EType asset_type, -	LLStoreAssetCallback callback, -	void* user_data, -	bool temp_file, -	bool is_priority, -	bool user_waiting, -	F64Seconds timeout) +    const std::string& filename, +    const LLTransactionID& tid, +    LLAssetType::EType asset_type, +    LLStoreAssetCallback callback, +    void* user_data, +    bool temp_file, +    bool is_priority, +    bool user_waiting, +    F64Seconds timeout)  { -	if(filename.empty()) -	{ -		// LLAssetStorage metric: no filename -		reportMetric( LLUUID::null, asset_type, LLStringUtil::null, LLUUID::null, 0, MR_VFS_CORRUPTION, __FILE__, __LINE__, "Filename missing" ); -		LL_ERRS() << "No filename specified" << LL_ENDL; -		return; -	} -	 -	LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); -	LL_DEBUGS("AssetStorage") << "LLViewerAssetStorage::storeAssetData (legacy)" << asset_id << ":" << LLAssetType::lookup(asset_type) << LL_ENDL; - -	LL_DEBUGS("AssetStorage") << "ASSET_ID: " << asset_id << LL_ENDL; - -	S32 size = 0; -	LLFILE* fp = LLFile::fopen(filename, "rb"); -	if (fp) -	{ -		fseek(fp, 0, SEEK_END); -		size = ftell(fp); -		fseek(fp, 0, SEEK_SET); -	} -	if( size ) -	{ -		LLLegacyAssetRequest *legacy = new LLLegacyAssetRequest; -		 -		legacy->mUpCallback = callback; -		legacy->mUserData = user_data; - -		LLVFile file(mVFS, asset_id, asset_type, LLVFile::WRITE); - -		file.setMaxSize(size); - -		const S32 buf_size = 65536; -		U8 copy_buf[buf_size]; -		while ((size = (S32)fread(copy_buf, 1, buf_size, fp))) -		{ -			file.write(copy_buf, size); -		} -		fclose(fp); - -		// if this upload fails, the caller needs to setup a new tempfile for us -		if (temp_file) -		{ -			LLFile::remove(filename); -		} - -		// LLAssetStorage metric: Success not needed; handled in the overloaded method here: - -		LLViewerAssetStorage::storeAssetData( -			tid, -			asset_type, -			legacyStoreDataCallback, -			(void**)legacy, -			temp_file, -			is_priority); -	} -	else // size == 0 (but previous block changes size) -	{ -		if( fp ) -		{ -			// LLAssetStorage metric: Zero size -			reportMetric( asset_id, asset_type, filename, LLUUID::null, 0, MR_ZERO_SIZE, __FILE__, __LINE__, "The file was zero length" ); -		} -		else -		{ -			// LLAssetStorage metric: Missing File -			reportMetric( asset_id, asset_type, filename, LLUUID::null, 0, MR_FILE_NONEXIST, __FILE__, __LINE__, "The file didn't exist" ); -		} -		if (callback) -		{ -			callback(asset_id, user_data, LL_ERR_CANNOT_OPEN_FILE, LL_EXSTAT_BLOCKED_FILE); -		} -	} +    if(filename.empty()) +    { +        // LLAssetStorage metric: no filename +        reportMetric( LLUUID::null, asset_type, LLStringUtil::null, LLUUID::null, 0, MR_VFS_CORRUPTION, __FILE__, __LINE__, "Filename missing" ); +        LL_ERRS() << "No filename specified" << LL_ENDL; +        return; +    } +     +    LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); +    LL_DEBUGS("AssetStorage") << "LLViewerAssetStorage::storeAssetData (legacy)" << asset_id << ":" << LLAssetType::lookup(asset_type) << LL_ENDL; + +    LL_DEBUGS("AssetStorage") << "ASSET_ID: " << asset_id << LL_ENDL; + +    S32 size = 0; +    LLFILE* fp = LLFile::fopen(filename, "rb"); +    if (fp) +    { +        fseek(fp, 0, SEEK_END); +        size = ftell(fp); +        fseek(fp, 0, SEEK_SET); +    } +    if( size ) +    { +        LLLegacyAssetRequest *legacy = new LLLegacyAssetRequest; +         +        legacy->mUpCallback = callback; +        legacy->mUserData = user_data; + +        LLVFile file(mVFS, asset_id, asset_type, LLVFile::WRITE); + +        file.setMaxSize(size); + +        const S32 buf_size = 65536; +        U8 copy_buf[buf_size]; +        while ((size = (S32)fread(copy_buf, 1, buf_size, fp))) +        { +            file.write(copy_buf, size); +        } +        fclose(fp); + +        // if this upload fails, the caller needs to setup a new tempfile for us +        if (temp_file) +        { +            LLFile::remove(filename); +        } + +        // LLAssetStorage metric: Success not needed; handled in the overloaded method here: + +        LLViewerAssetStorage::storeAssetData( +            tid, +            asset_type, +            legacyStoreDataCallback, +            (void**)legacy, +            temp_file, +            is_priority); +    } +    else // size == 0 (but previous block changes size) +    { +        if( fp ) +        { +            // LLAssetStorage metric: Zero size +            reportMetric( asset_id, asset_type, filename, LLUUID::null, 0, MR_ZERO_SIZE, __FILE__, __LINE__, "The file was zero length" ); +        } +        else +        { +            // LLAssetStorage metric: Missing File +            reportMetric( asset_id, asset_type, filename, LLUUID::null, 0, MR_FILE_NONEXIST, __FILE__, __LINE__, "The file didn't exist" ); +        } +        if (callback) +        { +            callback(asset_id, user_data, LL_ERR_CANNOT_OPEN_FILE, LL_EXSTAT_BLOCKED_FILE); +        } +    }  } @@ -334,56 +358,218 @@ void LLViewerAssetStorage::storeAssetData(  // virtual  void LLViewerAssetStorage::_queueDataRequest( -	const LLUUID& uuid, -	LLAssetType::EType atype, -	LLGetAssetCallback callback, -	void *user_data, -	BOOL duplicate, -	BOOL is_priority) +    const LLUUID& uuid, +    LLAssetType::EType atype, +    LLGetAssetCallback callback, +    void *user_data, +    BOOL duplicate, +    BOOL is_priority) +{ +    mCountRequests++; +    queueRequestHttp(uuid, atype, callback, user_data, duplicate, is_priority); +} + +void LLViewerAssetStorage::queueRequestHttp( +    const LLUUID& uuid, +    LLAssetType::EType atype, +    LLGetAssetCallback callback, +    void *user_data, +    BOOL duplicate, +    BOOL is_priority)  { -	if (mUpstreamHost.isOk()) -	{ -		// stash the callback info so we can find it after we get the response message -		LLViewerAssetRequest *req = new LLViewerAssetRequest(uuid, atype); -		req->mDownCallback = callback; -		req->mUserData = user_data; -		req->mIsPriority = is_priority; -		if (!duplicate) -		{ -			// Only collect metrics for non-duplicate requests.  Others  -			// are piggy-backing and will artificially lower averages. -			req->mMetricsStartTime = LLViewerAssetStatsFF::get_timestamp(); -		} -		 -		mPendingDownloads.push_back(req); -	 -		if (!duplicate) -		{ -			// send request message to our upstream data provider -			// Create a new asset transfer. -			LLTransferSourceParamsAsset spa; -			spa.setAsset(uuid, atype); - -			// Set our destination file, and the completion callback. -			LLTransferTargetParamsVFile tpvf; -			tpvf.setAsset(uuid, atype); -			tpvf.setCallback(downloadCompleteCallback, *req); - -			LL_DEBUGS("AssetStorage") << "Starting transfer for " << uuid << LL_ENDL; -			LLTransferTargetChannel *ttcp = gTransferManager.getTargetChannel(mUpstreamHost, LLTCT_ASSET); -			ttcp->requestTransfer(spa, tpvf, 100.f + (is_priority ? 1.f : 0.f)); - -			LLViewerAssetStatsFF::record_enqueue(atype, false, false); -		} -	} -	else -	{ -		// uh-oh, we shouldn't have gotten here -		LL_WARNS() << "Attempt to move asset data request upstream w/o valid upstream provider" << LL_ENDL; -		if (callback) -		{ -			callback(mVFS, uuid, atype, user_data, LL_ERR_CIRCUIT_GONE, LL_EXSTAT_NO_UPSTREAM); -		} -	} +    LL_DEBUGS("ViewerAsset") << "Request asset via HTTP " << uuid << " type " << LLAssetType::lookup(atype) << LL_ENDL; + +    bool with_http = true; +    LLViewerAssetRequest *req = new LLViewerAssetRequest(uuid, atype, with_http); +    req->mDownCallback = callback; +    req->mUserData = user_data; +    req->mIsPriority = is_priority; +    if (!duplicate) +    { +        // Only collect metrics for non-duplicate requests.  Others  +        // are piggy-backing and will artificially lower averages. +        req->mMetricsStartTime = LLViewerAssetStatsFF::get_timestamp(); +    } +    mPendingDownloads.push_back(req); + +    // This is the same as the current UDP logic - don't re-request a duplicate. +    if (!duplicate) +    { +        bool with_http = true; +        bool is_temp = false; +        LLViewerAssetStatsFF::record_enqueue(atype, with_http, is_temp); + +        LLCoprocedureManager::instance().enqueueCoprocedure("AssetStorage","LLViewerAssetStorage::assetRequestCoro", +            boost::bind(&LLViewerAssetStorage::assetRequestCoro, this, req, uuid, atype, callback, user_data)); +    }  } +void LLViewerAssetStorage::capsRecvForRegion(const LLUUID& region_id, std::string pumpname) +{ +    LLViewerRegion *regionp = LLWorld::instance().getRegionFromID(region_id); +    if (!regionp) +    { +        LL_WARNS("ViewerAsset") << "region not found for region_id " << region_id << LL_ENDL; +    } +    else +    { +        mViewerAssetUrl = regionp->getViewerAssetUrl(); +    } + +    LLEventPumps::instance().obtain(pumpname).post(LLSD()); +} + +struct LLScopedIncrement +{ +    LLScopedIncrement(S32& counter): +        mCounter(counter) +    { +        ++mCounter; +    } +    ~LLScopedIncrement() +    { +        --mCounter; +    } +    S32& mCounter; +}; + +void LLViewerAssetStorage::assetRequestCoro( +    LLViewerAssetRequest *req, +    const LLUUID uuid, +    LLAssetType::EType atype, +    LLGetAssetCallback callback, +    void *user_data) +{ +    LLScopedIncrement coro_count_boost(mAssetCoroCount); +    mCountStarted++; +     +    S32 result_code = LL_ERR_NOERR; +    LLExtStat ext_status = LL_EXSTAT_NONE; + +    if (!gAgent.getRegion()) +    { +        LL_WARNS_ONCE("ViewerAsset") << "Asset request fails: no region set" << LL_ENDL; +        result_code = LL_ERR_ASSET_REQUEST_FAILED; +        ext_status = LL_EXSTAT_NONE; +        removeAndCallbackPendingDownloads(uuid, atype, uuid, atype, result_code, ext_status); +		return; +    } +    else if (!gAgent.getRegion()->capabilitiesReceived()) +    { +        LL_WARNS_ONCE("ViewerAsset") << "Waiting for capabilities" << LL_ENDL; + +        LLEventStream capsRecv("waitForCaps", true); + +        gAgent.getRegion()->setCapabilitiesReceivedCallback( +            boost::bind(&LLViewerAssetStorage::capsRecvForRegion, this, _1, capsRecv.getName())); +         +        llcoro::suspendUntilEventOn(capsRecv); +        LL_WARNS_ONCE("ViewerAsset") << "capsRecv got event" << LL_ENDL; +        LL_WARNS_ONCE("ViewerAsset") << "region " << gAgent.getRegion() << " mViewerAssetUrl " << mViewerAssetUrl << LL_ENDL; +    } +    if (mViewerAssetUrl.empty() && gAgent.getRegion()) +    { +        mViewerAssetUrl = gAgent.getRegion()->getViewerAssetUrl(); +    } +    if (mViewerAssetUrl.empty()) +    { +        LL_WARNS_ONCE("ViewerAsset") << "asset request fails: caps received but no viewer asset cap found" << LL_ENDL; +        result_code = LL_ERR_ASSET_REQUEST_FAILED; +        ext_status = LL_EXSTAT_NONE; +        removeAndCallbackPendingDownloads(uuid, atype, uuid, atype, result_code, ext_status); +		return; +    } +    std::string url = getAssetURL(mViewerAssetUrl, uuid,atype); +    LL_DEBUGS("ViewerAsset") << "request url: " << url << LL_ENDL; + +    LLCore::HttpRequest::policy_t httpPolicy(LLAppCoreHttp::AP_TEXTURE); +    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t +        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("assetRequestCoro", httpPolicy)); +    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); +    LLCore::HttpOptions::ptr_t httpOpts = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions); + +    LLSD result = httpAdapter->getRawAndSuspend(httpRequest, url, httpOpts); + +    if (LLApp::isQuitting()) +    { +        // Bail out if result arrives after shutdown has been started. +        return; +    } + +    mCountCompleted++; +     +    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; +    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); +    if (!status) +    { +        LL_DEBUGS("ViewerAsset") << "request failed, status " << status.toTerseString() << LL_ENDL; +        result_code = LL_ERR_ASSET_REQUEST_FAILED; +        ext_status = LL_EXSTAT_NONE; +    } +    else +    { +        LL_DEBUGS("ViewerAsset") << "request succeeded, url " << url << LL_ENDL; + +        const LLSD::Binary &raw = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_RAW].asBinary(); + +        S32 size = raw.size(); +        if (size > 0) +        { +            mTotalBytesFetched += size; +             +			// This create-then-rename flow is modeled on +			// LLTransferTargetVFile, which is what was used in the UDP +			// case. +            LLUUID temp_id; +            temp_id.generate(); +            LLVFile vf(gAssetStorage->mVFS, temp_id, atype, LLVFile::WRITE); +            vf.setMaxSize(size); +            req->mBytesFetched = size; +            if (!vf.write(raw.data(),size)) +            { +                // TODO asset-http: handle error +                LL_WARNS("ViewerAsset") << "Failure in vf.write()" << LL_ENDL; +                result_code = LL_ERR_ASSET_REQUEST_FAILED; +                ext_status = LL_EXSTAT_VFS_CORRUPT; +            } +            else if (!vf.rename(uuid, atype)) +            { +                LL_WARNS("ViewerAsset") << "rename failed" << LL_ENDL; +                result_code = LL_ERR_ASSET_REQUEST_FAILED; +                ext_status = LL_EXSTAT_VFS_CORRUPT; +            } +            else +            { +                mCountSucceeded++; +            } +        } +        else +        { +            // TODO asset-http: handle invalid size case +			LL_WARNS("ViewerAsset") << "bad size" << LL_ENDL; +            result_code = LL_ERR_ASSET_REQUEST_FAILED; +            ext_status = LL_EXSTAT_NONE; +        } +    } + +    // Clean up pending downloads and trigger callbacks +    removeAndCallbackPendingDownloads(uuid, atype, uuid, atype, result_code, ext_status); +} + +std::string LLViewerAssetStorage::getAssetURL(const std::string& cap_url, const LLUUID& uuid, LLAssetType::EType atype) +{ +    std::string type_name = LLAssetType::lookup(atype); +    std::string url = cap_url + "/?" + type_name + "_id=" + uuid.asString(); +    return url; +} + +void LLViewerAssetStorage::logAssetStorageInfo() +{ +    LLMemory::logMemoryInfo(true); +    LL_INFOS("AssetStorage") << "Active coros " << mAssetCoroCount << LL_ENDL; +    LL_INFOS("AssetStorage") << "mPendingDownloads size " << mPendingDownloads.size() << LL_ENDL; +    LL_INFOS("AssetStorage") << "mCountStarted " << mCountStarted << LL_ENDL; +    LL_INFOS("AssetStorage") << "mCountCompleted " << mCountCompleted << LL_ENDL; +    LL_INFOS("AssetStorage") << "mCountSucceeded " << mCountSucceeded << LL_ENDL; +    LL_INFOS("AssetStorage") << "mTotalBytesFetched " << mTotalBytesFetched << LL_ENDL; +} diff --git a/indra/newview/llviewerassetstorage.h b/indra/newview/llviewerassetstorage.h index 6baec647e6..50131682e7 100644 --- a/indra/newview/llviewerassetstorage.h +++ b/indra/newview/llviewerassetstorage.h @@ -28,10 +28,12 @@  #define LLVIEWERASSETSTORAGE_H  #include "llassetstorage.h" -//#include "curl/curl.h" +#include "llcorehttputil.h"  class LLVFile; +class LLViewerAssetRequest; +  class LLViewerAssetStorage : public LLAssetStorage  {  public: @@ -41,7 +43,6 @@ public:  	LLViewerAssetStorage(LLMessageSystem *msg, LLXferManager *xfer,  				   LLVFS *vfs, LLVFS *static_vfs); -	using LLAssetStorage::storeAssetData;  	virtual void storeAssetData(  		const LLTransactionID& tid,  		LLAssetType::EType atype, @@ -65,8 +66,6 @@ public:  		F64Seconds timeout=LL_ASSET_STORAGE_TIMEOUT);  protected: -	using LLAssetStorage::_queueDataRequest; -  	// virtual  	void _queueDataRequest(const LLUUID& uuid,  						   LLAssetType::EType type, @@ -74,6 +73,33 @@ protected:  						   void *user_data,  						   BOOL duplicate,  						   BOOL is_priority); + +    void queueRequestHttp(const LLUUID& uuid, +                          LLAssetType::EType type, +                          void (*callback) (LLVFS *vfs, const LLUUID&, LLAssetType::EType, void *, S32, LLExtStat), +                          void *user_data, +                          BOOL duplicate, +                          BOOL is_priority); + +    void capsRecvForRegion(const LLUUID& region_id, std::string pumpname); +     +    void assetRequestCoro(LLViewerAssetRequest *req, +                          const LLUUID uuid, +                          LLAssetType::EType atype, +                          void (*callback) (LLVFS *vfs, const LLUUID&, LLAssetType::EType, void *, S32, LLExtStat), +                          void *user_data); + +    std::string getAssetURL(const std::string& cap_url, const LLUUID& uuid, LLAssetType::EType atype); + +    void logAssetStorageInfo(); +     +    std::string mViewerAssetUrl; +    S32 mAssetCoroCount; +    S32 mCountRequests; +    S32 mCountStarted; +    S32 mCountCompleted; +    S32 mCountSucceeded; +    S64 mTotalBytesFetched;  };  #endif diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index afa00e3e6e..bfa9fa03fa 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -106,6 +106,7 @@ const F32 TELEPORT_EXPIRY_PER_ATTACHMENT = 3.f;  U32 gRecentFrameCount = 0; // number of 'recent' frames  LLFrameTimer gRecentFPSTime;  LLFrameTimer gRecentMemoryTime; +LLFrameTimer gAssetStorageLogTime;  // Rendering stuff  void pre_show_depth_buffer(); @@ -226,6 +227,12 @@ void display_stats()  		LLMemory::logMemoryInfo(TRUE) ;  		gRecentMemoryTime.reset();  	} +    F32 asset_storage_log_freq = gSavedSettings.getF32("AssetStorageLogFrequency"); +    if (asset_storage_log_freq > 0.f && gAssetStorageLogTime.getElapsedTimeF32() >= asset_storage_log_freq) +    { +        gAssetStorageLogTime.reset(); +        gAssetStorage->logAssetStorageInfo(); +    }  }  static LLTrace::BlockTimerStatHandle FTM_PICK("Picking"); diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 899ab3a371..eb37613c95 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -521,7 +521,7 @@ LLViewerRegion::LLViewerRegion(const U64 &handle,  	mColoName("unknown"),  	mProductSKU("unknown"),  	mProductName("unknown"), -	mHttpUrl(""), +	mViewerAssetUrl(""),  	mCacheLoaded(FALSE),  	mCacheDirty(FALSE),  	mReleaseNotesRequested(FALSE), @@ -2843,12 +2843,9 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)  	capabilityNames.append("IsExperienceAdmin");  	capabilityNames.append("IsExperienceContributor");  	capabilityNames.append("RegionExperiences"); -	capabilityNames.append("GetMesh"); -	capabilityNames.append("GetMesh2");  	capabilityNames.append("GetMetadata");  	capabilityNames.append("GetObjectCost");  	capabilityNames.append("GetObjectPhysicsData"); -	capabilityNames.append("GetTexture");  	capabilityNames.append("GroupAPIv1");  	capabilityNames.append("GroupMemberData");  	capabilityNames.append("GroupProposalBallot"); @@ -2895,6 +2892,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)  	capabilityNames.append("UpdateScriptAgent");  	capabilityNames.append("UpdateScriptTask");  	capabilityNames.append("UploadBakedTexture"); +	capabilityNames.append("ViewerAsset");   	capabilityNames.append("ViewerMetrics");  	capabilityNames.append("ViewerStartAuction");  	capabilityNames.append("ViewerStats"); @@ -2961,9 +2959,9 @@ void LLViewerRegion::setCapability(const std::string& name, const std::string& u  	else  	{  		mImpl->mCapabilities[name] = url; -		if(name == "GetTexture") +		if(name == "ViewerAsset")  		{ -			mHttpUrl = url ; +			mViewerAssetUrl = url;  		}  	}  } @@ -2974,9 +2972,9 @@ void LLViewerRegion::setCapabilityDebug(const std::string& name, const std::stri  	if ( ! ( name == "EventQueueGet" || name == "UntrustedSimulatorMessage" || name == "SimulatorFeatures" ) )  	{  		mImpl->mSecondCapabilitiesTracker[name] = url; -		if(name == "GetTexture") +		if(name == "ViewerAsset")  		{ -			mHttpUrl = url ; +			mViewerAssetUrl = url;  		}  	}  } diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index a7bb546d2c..61ce5b454d 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -354,7 +354,7 @@ public:  	friend std::ostream& operator<<(std::ostream &s, const LLViewerRegion ®ion);      /// implements LLCapabilityProvider      virtual std::string getDescription() const; -	std::string getHttpUrl() const { return mHttpUrl ;} +    std::string getViewerAssetUrl() const { return mViewerAssetUrl; }  	U32 getNumOfVisibleGroups() const;  	U32 getNumOfActiveCachedObjects() const; @@ -506,7 +506,7 @@ private:  	std::string mColoName;  	std::string mProductSKU;  	std::string mProductName; -	std::string mHttpUrl ; +	std::string mViewerAssetUrl ;  	// Maps local ids to cache entries.  	// Regions can have order 10,000 objects, so assume diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 3968266c27..80c6805ead 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -9387,6 +9387,3 @@ BOOL LLVOAvatar::isTextureVisible(LLAvatarAppearanceDefines::ETextureIndex type,  	// non-self avatars don't have wearables  	return FALSE;  } - - - diff --git a/indra/newview/tests/llviewerassetstats_test.cpp b/indra/newview/tests/llviewerassetstats_test.cpp index a08e32cb49..e2e7f09c3b 100644 --- a/indra/newview/tests/llviewerassetstats_test.cpp +++ b/indra/newview/tests/llviewerassetstats_test.cpp @@ -71,25 +71,33 @@ static const char * all_keys[] =  {  	"duration",  	"fps", -	"get_other", +	"get_other_http", +	"get_other_udp",  	"get_texture_temp_http",  	"get_texture_temp_udp",  	"get_texture_non_temp_http",  	"get_texture_non_temp_udp", +	"get_wearable_http",  	"get_wearable_udp", +	"get_sound_http",  	"get_sound_udp", +	"get_gesture_http",  	"get_gesture_udp"  };  static const char * resp_keys[] =   { -	"get_other", +	"get_other_http", +	"get_other_udp",  	"get_texture_temp_http",  	"get_texture_temp_udp",  	"get_texture_non_temp_http",  	"get_texture_non_temp_udp", +	"get_wearable_http",  	"get_wearable_udp", +	"get_sound_http",  	"get_sound_udp", +	"get_gesture_http",  	"get_gesture_udp"  }; @@ -540,11 +548,17 @@ namespace tut  		ensure("sd[get_gesture_udp][enqueued] is 0", (0 == sd["get_gesture_udp"]["enqueued"].asInteger()));  		ensure("sd[get_gesture_udp][dequeued] is 0", (0 == sd["get_gesture_udp"]["dequeued"].asInteger())); -		ensure("sd[get_wearable_udp][enqueued] is 4", (4 == sd["get_wearable_udp"]["enqueued"].asInteger())); -		ensure("sd[get_wearable_udp][dequeued] is 4", (4 == sd["get_wearable_udp"]["dequeued"].asInteger())); +		ensure("sd[get_wearable_http][enqueued] is 2", (2 == sd["get_wearable_http"]["enqueued"].asInteger())); +		ensure("sd[get_wearable_http][dequeued] is 2", (2 == sd["get_wearable_http"]["dequeued"].asInteger())); -		ensure("sd[get_other][enqueued] is 4", (4 == sd["get_other"]["enqueued"].asInteger())); -		ensure("sd[get_other][dequeued] is 0", (0 == sd["get_other"]["dequeued"].asInteger())); +		ensure("sd[get_wearable_udp][enqueued] is 2", (2 == sd["get_wearable_udp"]["enqueued"].asInteger())); +		ensure("sd[get_wearable_udp][dequeued] is 2", (2 == sd["get_wearable_udp"]["dequeued"].asInteger())); + +		ensure("sd[get_other_http][enqueued] is 2", (2 == sd["get_other_http"]["enqueued"].asInteger())); +		ensure("sd[get_other_http][dequeued] is 0", (0 == sd["get_other_http"]["dequeued"].asInteger())); + +		ensure("sd[get_other_udp][enqueued] is 2", (2 == sd["get_other_udp"]["enqueued"].asInteger())); +		ensure("sd[get_other_udp][dequeued] is 0", (0 == sd["get_other_udp"]["dequeued"].asInteger()));  		// Reset and check zeros...  		// Reset leaves current region in place diff --git a/indra/test/test.cpp b/indra/test/test.cpp index e42374d56b..630af2b73b 100644 --- a/indra/test/test.cpp +++ b/indra/test/test.cpp @@ -34,6 +34,7 @@   *   */ +  #include "linden_common.h"  #include "llerrorcontrol.h"  #include "lltut.h" @@ -684,4 +685,5 @@ int main(int argc, char **argv)  	return retval;  	//delete mycallback; +  } | 
