summaryrefslogtreecommitdiff
path: root/indra/llmessage
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llmessage')
-rw-r--r--indra/llmessage/llassetstorage.cpp2381
-rw-r--r--indra/llmessage/llassetstorage.h112
-rw-r--r--indra/llmessage/llavatarname.cpp10
-rw-r--r--indra/llmessage/llavatarname.h4
-rw-r--r--indra/llmessage/llavatarnamecache.cpp22
-rw-r--r--indra/llmessage/llavatarnamecache.h10
-rw-r--r--indra/llmessage/llcoproceduremanager.h6
-rw-r--r--indra/llmessage/llexperiencecache.cpp26
-rw-r--r--indra/llmessage/llexperiencecache.h6
-rw-r--r--indra/llmessage/llproxy.h8
-rw-r--r--indra/llmessage/llregionflags.h3
-rw-r--r--indra/llmessage/lltemplatemessagereader.cpp7
-rw-r--r--indra/llmessage/llxfer_file.cpp6
-rw-r--r--indra/llmessage/llxfermanager.cpp2
-rw-r--r--indra/llmessage/message.cpp7
-rw-r--r--indra/llmessage/message.h7
-rw-r--r--indra/llmessage/message_prehash.cpp4
-rw-r--r--indra/llmessage/message_prehash.h3
-rw-r--r--indra/llmessage/tests/llhttpclient_test.cpp3
-rw-r--r--indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp3
-rw-r--r--indra/llmessage/tests/lltrustedmessageservice_test.cpp3
-rw-r--r--indra/llmessage/tests/networkio.h3
-rwxr-xr-xindra/llmessage/tests/test_llsdmessage_peer.py27
-rwxr-xr-xindra/llmessage/tests/testrunner.py87
24 files changed, 1348 insertions, 1402 deletions
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(&timestamp);
- 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(&timestamp);
+ 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/llmessage/llavatarname.cpp b/indra/llmessage/llavatarname.cpp
index d2115ee499..7e1246f885 100644
--- a/indra/llmessage/llavatarname.cpp
+++ b/indra/llmessage/llavatarname.cpp
@@ -166,10 +166,10 @@ void LLAvatarName::setExpires(F64 expires)
mExpires = LLFrameTimer::getTotalSeconds() + expires;
}
-std::string LLAvatarName::getCompleteName(bool use_parentheses) const
+std::string LLAvatarName::getCompleteName(bool use_parentheses, bool force_use_complete_name) const
{
std::string name;
- if (sUseDisplayNames)
+ if (sUseDisplayNames || force_use_complete_name)
{
if (mUsername.empty() || mIsDisplayNameDefault)
{
@@ -180,7 +180,7 @@ std::string LLAvatarName::getCompleteName(bool use_parentheses) const
else
{
name = mDisplayName;
- if(sUseUsernames)
+ if(sUseUsernames || force_use_complete_name)
{
if(use_parentheses)
{
@@ -215,9 +215,9 @@ std::string LLAvatarName::getLegacyName() const
return name;
}
-std::string LLAvatarName::getDisplayName() const
+std::string LLAvatarName::getDisplayName(bool force_use_display_name) const
{
- if (sUseDisplayNames)
+ if (sUseDisplayNames || force_use_display_name)
{
return mDisplayName;
}
diff --git a/indra/llmessage/llavatarname.h b/indra/llmessage/llavatarname.h
index 192f43f07c..20f7140797 100644
--- a/indra/llmessage/llavatarname.h
+++ b/indra/llmessage/llavatarname.h
@@ -65,7 +65,7 @@ public:
// For normal names, returns "James Linden (james.linden)"
// When display names are disabled returns just "James Linden"
- std::string getCompleteName(bool use_parentheses = true) const;
+ std::string getCompleteName(bool use_parentheses = true, bool force_use_complete_name = false) const;
// Returns "James Linden" or "bobsmith123 Resident" for backwards
// compatibility with systems like voice and muting
@@ -75,7 +75,7 @@ public:
// "José Sanchez" or "James Linden", UTF-8 encoded Unicode
// Takes the display name preference into account. This is truly the name that should
// be used for all UI where an avatar name has to be used unless we truly want something else (rare)
- std::string getDisplayName() const;
+ std::string getDisplayName(bool force_use_display_name = false) const;
// Returns "James Linden" or "bobsmith123 Resident"
// Used where we explicitely prefer or need a non UTF-8 legacy (ASCII) name
diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp
index 004db546b7..5a112b5432 100644
--- a/indra/llmessage/llavatarnamecache.cpp
+++ b/indra/llmessage/llavatarnamecache.cpp
@@ -755,6 +755,28 @@ void LLAvatarNameCache::insert(const LLUUID& agent_id, const LLAvatarName& av_na
sCache[agent_id] = av_name;
}
+LLUUID LLAvatarNameCache::findIdByName(const std::string& name)
+{
+ std::map<LLUUID, LLAvatarName>::iterator it;
+ std::map<LLUUID, LLAvatarName>::iterator end = sCache.end();
+ for (it = sCache.begin(); it != end; ++it)
+ {
+ if (it->second.getUserName() == name)
+ {
+ return it->first;
+ }
+ }
+
+ // Legacy method
+ LLUUID id;
+ if (gCacheName->getUUID(name, id))
+ {
+ return id;
+ }
+
+ return LLUUID::null;
+}
+
#if 0
F64 LLAvatarNameCache::nameExpirationFromHeaders(LLCore::HttpHeaders *headers)
{
diff --git a/indra/llmessage/llavatarnamecache.h b/indra/llmessage/llavatarnamecache.h
index bd2715e956..63e067c939 100644
--- a/indra/llmessage/llavatarnamecache.h
+++ b/indra/llmessage/llavatarnamecache.h
@@ -84,7 +84,15 @@ namespace LLAvatarNameCache
void insert(const LLUUID& agent_id, const LLAvatarName& av_name);
void erase(const LLUUID& agent_id);
- /// Provide some fallback for agents that return errors.
+ // A way to find agent id by UUID, very slow, also unreliable
+ // since it doesn't request names, just serch exsisting ones
+ // that are likely not in cache.
+ //
+ // Todo: Find a way to remove this.
+ // Curently this method is used for chat history and in some cases notices.
+ LLUUID findIdByName(const std::string& name);
+
+ /// Provide some fallback for agents that return errors.
void handleAgentError(const LLUUID& agent_id);
// Compute name expiration time from HTTP Cache-Control header,
diff --git a/indra/llmessage/llcoproceduremanager.h b/indra/llmessage/llcoproceduremanager.h
index 497367b80c..7d0e83180c 100644
--- a/indra/llmessage/llcoproceduremanager.h
+++ b/indra/llmessage/llcoproceduremanager.h
@@ -37,7 +37,8 @@ class LLCoprocedurePool;
class LLCoprocedureManager : public LLSingleton < LLCoprocedureManager >
{
- friend class LLSingleton < LLCoprocedureManager > ;
+ LLSINGLETON(LLCoprocedureManager);
+ virtual ~LLCoprocedureManager();
public:
typedef boost::function<U32(const std::string &)> SettingQuery_t;
@@ -45,9 +46,6 @@ public:
typedef boost::function<void(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &, const LLUUID &id)> CoProcedure_t;
- LLCoprocedureManager();
- virtual ~LLCoprocedureManager();
-
/// Places the coprocedure on the queue for processing.
///
/// @param name Is used for debugging and should identify this coroutine.
diff --git a/indra/llmessage/llexperiencecache.cpp b/indra/llmessage/llexperiencecache.cpp
index 779d1d9d99..aa7b3c1260 100644
--- a/indra/llmessage/llexperiencecache.cpp
+++ b/indra/llmessage/llexperiencecache.cpp
@@ -540,18 +540,34 @@ void LLExperienceCache::fetchAssociatedExperience(const LLUUID& objectId, const
}
LLCoprocedureManager::instance().enqueueCoprocedure("ExpCache", "Fetch Associated",
- boost::bind(&LLExperienceCache::fetchAssociatedExperienceCoro, this, _1, objectId, itemId, fn));
+ boost::bind(&LLExperienceCache::fetchAssociatedExperienceCoro, this, _1, objectId, itemId, std::string(), fn));
}
-void LLExperienceCache::fetchAssociatedExperienceCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &httpAdapter, LLUUID objectId, LLUUID itemId, ExperienceGetFn_t fn)
+void LLExperienceCache::fetchAssociatedExperience(const LLUUID& objectId, const LLUUID& itemId, std::string url, ExperienceGetFn_t fn)
+{
+ if (mCapability.empty())
+ {
+ LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL;
+ return;
+ }
+
+ LLCoprocedureManager::instance().enqueueCoprocedure("ExpCache", "Fetch Associated",
+ boost::bind(&LLExperienceCache::fetchAssociatedExperienceCoro, this, _1, objectId, itemId, url, fn));
+}
+
+void LLExperienceCache::fetchAssociatedExperienceCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &httpAdapter, LLUUID objectId, LLUUID itemId, std::string url, ExperienceGetFn_t fn)
{
LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest());
- std::string url = mCapability("GetMetadata");
if (url.empty())
{
- LL_WARNS("ExperienceCache") << "No Metadata capability." << LL_ENDL;
- return;
+ url = mCapability("GetMetadata");
+
+ if (url.empty())
+ {
+ LL_WARNS("ExperienceCache") << "No Metadata capability." << LL_ENDL;
+ return;
+ }
}
LLSD fields;
diff --git a/indra/llmessage/llexperiencecache.h b/indra/llmessage/llexperiencecache.h
index 1002b33f80..f9ff69c2b6 100644
--- a/indra/llmessage/llexperiencecache.h
+++ b/indra/llmessage/llexperiencecache.h
@@ -43,7 +43,7 @@ class LLUUID;
class LLExperienceCache: public LLSingleton < LLExperienceCache >
{
- friend class LLSingleton < LLExperienceCache > ;
+ LLSINGLETON(LLExperienceCache);
public:
typedef boost::function<std::string(const std::string &)> CapabilityQuery_t;
@@ -64,6 +64,7 @@ public:
//-------------------------------------------
void fetchAssociatedExperience(const LLUUID& objectId, const LLUUID& itemId, ExperienceGetFn_t fn);
+ void fetchAssociatedExperience(const LLUUID& objectId, const LLUUID& itemId, std::string url, ExperienceGetFn_t fn);
void findExperienceByName(const std::string text, int page, ExperienceGetFn_t fn);
void getGroupExperiences(const LLUUID &groupId, ExperienceGetFn_t fn);
@@ -103,7 +104,6 @@ public:
static const int PROPERTY_SUSPENDED; // 1 << 7
private:
- LLExperienceCache();
virtual ~LLExperienceCache();
virtual void initSingleton();
@@ -149,7 +149,7 @@ private:
void requestExperiencesCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &, std::string, RequestQueue_t);
void requestExperiences();
- void fetchAssociatedExperienceCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &, LLUUID, LLUUID, ExperienceGetFn_t);
+ void fetchAssociatedExperienceCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &, LLUUID, LLUUID, std::string, ExperienceGetFn_t);
void findExperienceByNameCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &, std::string, int, ExperienceGetFn_t);
void getGroupExperiencesCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &, LLUUID , ExperienceGetFn_t);
void regionExperiencesCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &httpAdapter, CapabilityQuery_t regioncaps, bool update, LLSD experiences, ExperienceGetFn_t fn);
diff --git a/indra/llmessage/llproxy.h b/indra/llmessage/llproxy.h
index bd23dd39de..688dff7c83 100644
--- a/indra/llmessage/llproxy.h
+++ b/indra/llmessage/llproxy.h
@@ -218,14 +218,14 @@ enum LLSocks5AuthType
*/
class LLProxy: public LLSingleton<LLProxy>
{
- LOG_CLASS(LLProxy);
-public:
/*###########################################################################################
METHODS THAT DO NOT LOCK mProxyMutex!
###########################################################################################*/
// Constructor, cannot have parameters due to LLSingleton parent class. Call from main thread only.
- LLProxy();
+ LLSINGLETON(LLProxy);
+ LOG_CLASS(LLProxy);
+public:
// Static check for enabled status for UDP packets. Call from main thread only.
static bool isSOCKSProxyEnabled() { return sUDPProxyEnabled; }
@@ -239,9 +239,11 @@ public:
/*###########################################################################################
METHODS THAT LOCK mProxyMutex! DO NOT CALL WHILE mProxyMutex IS LOCKED!
###########################################################################################*/
+private:
// Destructor, closes open connections. Do not call directly, use cleanupClass().
~LLProxy();
+public:
// Delete LLProxy singleton. Allows the apr_socket used in the SOCKS 5 control channel to be
// destroyed before the call to apr_terminate. Call from main thread only.
static void cleanupClass();
diff --git a/indra/llmessage/llregionflags.h b/indra/llmessage/llregionflags.h
index eb0c4e6d1e..d3791ef4d1 100644
--- a/indra/llmessage/llregionflags.h
+++ b/indra/llmessage/llregionflags.h
@@ -42,6 +42,9 @@ const U64 REGION_FLAGS_RESET_HOME_ON_TELEPORT = (1 << 3);
// Does the sun move?
const U64 REGION_FLAGS_SUN_FIXED = (1 << 4);
+// Does the estate owner allow private parcels?
+const U64 REGION_FLAGS_ALLOW_ACCESS_OVERRIDE = (1 << 5);
+
// Can't change the terrain heightfield, even on owned parcels,
// but can plant trees and grass.
const U64 REGION_FLAGS_BLOCK_TERRAFORM = (1 << 6);
diff --git a/indra/llmessage/lltemplatemessagereader.cpp b/indra/llmessage/lltemplatemessagereader.cpp
index 406afadd2f..4e0c53c37e 100644
--- a/indra/llmessage/lltemplatemessagereader.cpp
+++ b/indra/llmessage/lltemplatemessagereader.cpp
@@ -499,9 +499,10 @@ BOOL LLTemplateMessageReader::decodeTemplate(
}
else
{
- LL_WARNS() << "Message #" << std::hex << num << std::dec
- << " received but not registered!" << LL_ENDL;
- gMessageSystem->callExceptionFunc(MX_UNREGISTERED_MESSAGE);
+ // MAINT-7482 - make viewer more tolerant of unknown messages.
+ LL_WARNS_ONCE() << "Message #" << std::hex << num << std::dec
+ << " received but not registered!" << LL_ENDL;
+ //gMessageSystem->callExceptionFunc(MX_UNREGISTERED_MESSAGE);
return(FALSE);
}
diff --git a/indra/llmessage/llxfer_file.cpp b/indra/llmessage/llxfer_file.cpp
index 257a13f277..8e2ed890e7 100644
--- a/indra/llmessage/llxfer_file.cpp
+++ b/indra/llmessage/llxfer_file.cpp
@@ -98,12 +98,12 @@ void LLXfer_File::cleanup ()
mFp = NULL;
}
- LLFile::remove(mTempFilename);
+ LLFile::remove(mTempFilename, ENOENT);
if (mDeleteLocalOnCompletion)
{
LL_DEBUGS() << "Removing file: " << mLocalFilename << LL_ENDL;
- LLFile::remove(mLocalFilename);
+ LLFile::remove(mLocalFilename, ENOENT);
}
else
{
@@ -321,7 +321,7 @@ S32 LLXfer_File::processEOF()
mCallbackResult = flushval;
}
- LLFile::remove(mLocalFilename);
+ LLFile::remove(mLocalFilename, ENOENT);
if (!mCallbackResult)
{
diff --git a/indra/llmessage/llxfermanager.cpp b/indra/llmessage/llxfermanager.cpp
index 272dbbc785..2ceb64ce8f 100644
--- a/indra/llmessage/llxfermanager.cpp
+++ b/indra/llmessage/llxfermanager.cpp
@@ -444,7 +444,7 @@ U64 LLXferManager::requestFile(const std::string& local_filename,
&& (remote_filename.substr(remote_filename.length()-4) == ".tmp")
&& gDirUtilp->fileExists(local_filename))
{
- LLFile::remove(local_filename);
+ LLFile::remove(local_filename, ENOENT);
}
xfer_id = getNextID();
((LLXfer_File *)xferp)->initializeRequest(
diff --git a/indra/llmessage/message.cpp b/indra/llmessage/message.cpp
index 290b67feb3..6ef4025ab1 100644
--- a/indra/llmessage/message.cpp
+++ b/indra/llmessage/message.cpp
@@ -76,6 +76,7 @@
#include "v4math.h"
#include "lltransfertargetvfile.h"
#include "llcorehttputil.h"
+#include "llpounceable.h"
// Constants
//const char* MESSAGE_LOG_FILENAME = "message.log";
@@ -1724,7 +1725,9 @@ std::ostream& operator<<(std::ostream& s, LLMessageSystem &msg)
return s;
}
-LLMessageSystem *gMessageSystem = NULL;
+// LLPounceable supports callWhenReady(), to permit clients to queue up (e.g.)
+// callback registrations for when gMessageSystem is first assigned
+LLPounceable<LLMessageSystem*, LLPounceableStatic> gMessageSystem;
// update appropriate ping info
void process_complete_ping_check(LLMessageSystem *msgsystem, void** /*user_data*/)
@@ -2641,7 +2644,7 @@ void end_messaging_system(bool print_summary)
LL_INFOS("Messaging") << str.str().c_str() << LL_ENDL;
}
- delete gMessageSystem;
+ delete static_cast<LLMessageSystem*>(gMessageSystem);
gMessageSystem = NULL;
}
}
diff --git a/indra/llmessage/message.h b/indra/llmessage/message.h
index 133db620e6..f6c5d9e228 100644
--- a/indra/llmessage/message.h
+++ b/indra/llmessage/message.h
@@ -60,6 +60,7 @@
#include "llstoredmessage.h"
#include "boost/function.hpp"
+#include "llpounceable.h"
const U32 MESSAGE_MAX_STRINGS_LENGTH = 64;
const U32 MESSAGE_NUMBER_OF_HASH_BUCKETS = 8192;
@@ -68,10 +69,10 @@ const S32 MESSAGE_MAX_PER_FRAME = 400;
class LLMessageStringTable : public LLSingleton<LLMessageStringTable>
{
-public:
- LLMessageStringTable();
+ LLSINGLETON(LLMessageStringTable);
~LLMessageStringTable();
+public:
char *getString(const char *str);
U32 mUsed;
@@ -832,7 +833,7 @@ private:
// external hook into messaging system
-extern LLMessageSystem *gMessageSystem;
+extern LLPounceable<LLMessageSystem*, LLPounceableStatic> gMessageSystem;
// Must specific overall system version, which is used to determine
// if a patch is available in the message template checksum verification.
diff --git a/indra/llmessage/message_prehash.cpp b/indra/llmessage/message_prehash.cpp
index 5c6b3d5fab..1ae8a6ac15 100644
--- a/indra/llmessage/message_prehash.cpp
+++ b/indra/llmessage/message_prehash.cpp
@@ -618,6 +618,7 @@ char const* const _PREHASH_GroupAccountSummaryRequest = LLMessageStringTable::ge
char const* const _PREHASH_GroupVoteHistoryRequest = LLMessageStringTable::getInstance()->getString("GroupVoteHistoryRequest");
char const* const _PREHASH_ParamValue = LLMessageStringTable::getInstance()->getString("ParamValue");
char const* const _PREHASH_MaxAgents = LLMessageStringTable::getInstance()->getString("MaxAgents");
+char const* const _PREHASH_HardMaxAgents = LLMessageStringTable::getInstance()->getString("HardMaxAgents");
char const* const _PREHASH_CreateNewOutfitAttachments = LLMessageStringTable::getInstance()->getString("CreateNewOutfitAttachments");
char const* const _PREHASH_RegionHandle = LLMessageStringTable::getInstance()->getString("RegionHandle");
char const* const _PREHASH_TeleportProgress = LLMessageStringTable::getInstance()->getString("TeleportProgress");
@@ -1372,6 +1373,9 @@ char const* const _PREHASH_OwnerMask = LLMessageStringTable::getInstance()->getS
char const* const _PREHASH_TransferInventoryAck = LLMessageStringTable::getInstance()->getString("TransferInventoryAck");
char const* const _PREHASH_RegionDenyAgeUnverified = LLMessageStringTable::getInstance()->getString("RegionDenyAgeUnverified");
char const* const _PREHASH_AgeVerificationBlock = LLMessageStringTable::getInstance()->getString("AgeVerificationBlock");
+char const* const _PREHASH_RegionAllowAccessBlock = LLMessageStringTable::getInstance()->getString("RegionAllowAccessBlock");
+char const* const _PREHASH_RegionAllowAccessOverride = LLMessageStringTable::getInstance()->getString("RegionAllowAccessOverride");
+
char const* const _PREHASH_UCoord = LLMessageStringTable::getInstance()->getString("UCoord");
char const* const _PREHASH_VCoord = LLMessageStringTable::getInstance()->getString("VCoord");
char const* const _PREHASH_FaceIndex = LLMessageStringTable::getInstance()->getString("FaceIndex");
diff --git a/indra/llmessage/message_prehash.h b/indra/llmessage/message_prehash.h
index e696c3b0ca..7910fde305 100644
--- a/indra/llmessage/message_prehash.h
+++ b/indra/llmessage/message_prehash.h
@@ -618,6 +618,7 @@ extern char const* const _PREHASH_GroupAccountSummaryRequest;
extern char const* const _PREHASH_GroupVoteHistoryRequest;
extern char const* const _PREHASH_ParamValue;
extern char const* const _PREHASH_MaxAgents;
+extern char const* const _PREHASH_HardMaxAgents;
extern char const* const _PREHASH_CreateNewOutfitAttachments;
extern char const* const _PREHASH_RegionHandle;
extern char const* const _PREHASH_TeleportProgress;
@@ -1372,6 +1373,8 @@ extern char const* const _PREHASH_OwnerMask;
extern char const* const _PREHASH_TransferInventoryAck;
extern char const* const _PREHASH_RegionDenyAgeUnverified;
extern char const* const _PREHASH_AgeVerificationBlock;
+extern char const* const _PREHASH_RegionAllowAccessBlock;
+extern char const* const _PREHASH_RegionAllowAccessOverride;
extern char const* const _PREHASH_UCoord;
extern char const* const _PREHASH_VCoord;
extern char const* const _PREHASH_FaceIndex;
diff --git a/indra/llmessage/tests/llhttpclient_test.cpp b/indra/llmessage/tests/llhttpclient_test.cpp
index a32bfa59ce..9356a14f1f 100644
--- a/indra/llmessage/tests/llhttpclient_test.cpp
+++ b/indra/llmessage/tests/llhttpclient_test.cpp
@@ -42,6 +42,7 @@
#include "lliosocket.h"
#include "stringize.h"
+#include "llcleanup.h"
namespace tut
{
@@ -66,7 +67,7 @@ namespace tut
~HTTPClientTestData()
{
delete mClientPump;
- LLProxy::cleanupClass();
+ SUBSYSTEM_CLEANUP(LLProxy);
apr_pool_destroy(mPool);
}
diff --git a/indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp b/indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp
index 3b04530c1a..e20f61b73f 100644
--- a/indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp
+++ b/indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp
@@ -31,11 +31,12 @@
#include "llhost.h"
#include "message.h"
#include "llsd.h"
+#include "llpounceable.h"
#include "llhost.cpp" // Needed for copy operator
#include "net.cpp" // Needed by LLHost.
-LLMessageSystem * gMessageSystem = NULL;
+LLPounceable<LLMessageSystem*, LLPounceableStatic> gMessageSystem;
// sensor test doubles
bool gClearRecvWasCalled = false;
diff --git a/indra/llmessage/tests/lltrustedmessageservice_test.cpp b/indra/llmessage/tests/lltrustedmessageservice_test.cpp
index 55748ad27e..41f982a7e2 100644
--- a/indra/llmessage/tests/lltrustedmessageservice_test.cpp
+++ b/indra/llmessage/tests/lltrustedmessageservice_test.cpp
@@ -33,8 +33,9 @@
#include "message.h"
#include "llmessageconfig.h"
#include "llhttpnode_stub.cpp"
+#include "llpounceable.h"
-LLMessageSystem* gMessageSystem = NULL;
+LLPounceable<LLMessageSystem*, LLPounceableStatic> gMessageSystem;
LLMessageConfig::SenderTrust
LLMessageConfig::getSenderTrustedness(const std::string& msg_name)
diff --git a/indra/llmessage/tests/networkio.h b/indra/llmessage/tests/networkio.h
index 5eb739393f..5986524342 100644
--- a/indra/llmessage/tests/networkio.h
+++ b/indra/llmessage/tests/networkio.h
@@ -44,7 +44,7 @@
// init time. Use the lazy, on-demand initialization we get from LLSingleton.
class NetworkIO: public LLSingleton<NetworkIO>
{
-public:
+ LLSINGLETON(NetworkIO);
NetworkIO():
mServicePump(NULL),
mDone(false)
@@ -69,6 +69,7 @@ public:
boost::bind(&NetworkIO::done, this, _1));
}
+public:
bool pump(F32 timeout=10)
{
// Reset the done flag so we don't pop out prematurely
diff --git a/indra/llmessage/tests/test_llsdmessage_peer.py b/indra/llmessage/tests/test_llsdmessage_peer.py
index bac18fa374..9cd2959ea1 100755
--- a/indra/llmessage/tests/test_llsdmessage_peer.py
+++ b/indra/llmessage/tests/test_llsdmessage_peer.py
@@ -31,7 +31,6 @@ $/LicenseInfo$
import os
import sys
-from threading import Thread
from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
from llbase.fastest_elementtree import parse as xml_parse
@@ -155,17 +154,23 @@ class Server(HTTPServer):
allow_reuse_address = False
if __name__ == "__main__":
- # Instantiate a Server(TestHTTPRequestHandler) on the first free port
- # in the specified port range. Doing this inline is better than in a
- # daemon thread: if it blows up here, we'll get a traceback. If it blew up
- # in some other thread, the traceback would get eaten and we'd run the
- # subject test program anyway.
- httpd, port = freeport(xrange(8000, 8020),
- lambda port: Server(('127.0.0.1', port), TestHTTPRequestHandler))
+ # function to make a server with specified port
+ make_server = lambda port: Server(('127.0.0.1', port), TestHTTPRequestHandler)
+
+ if not sys.platform.startswith("win"):
+ # Instantiate a Server(TestHTTPRequestHandler) on a port chosen by the
+ # runtime.
+ httpd = make_server(0)
+ else:
+ # "Then there's Windows"
+ # Instantiate a Server(TestHTTPRequestHandler) on the first free port
+ # in the specified port range.
+ httpd, port = freeport(xrange(8000, 8020), make_server)
+
# Pass the selected port number to the subject test program via the
# environment. We don't want to impose requirements on the test program's
# command-line parsing -- and anyway, for C++ integration tests, that's
# performed in TUT code rather than our own.
- os.environ["PORT"] = str(port)
- debug("$PORT = %s", port)
- sys.exit(run(server=Thread(name="httpd", target=httpd.serve_forever), *sys.argv[1:]))
+ os.environ["PORT"] = str(httpd.server_port)
+ debug("$PORT = %s", httpd.server_port)
+ sys.exit(run(server_inst=httpd, *sys.argv[1:]))
diff --git a/indra/llmessage/tests/testrunner.py b/indra/llmessage/tests/testrunner.py
index 5b9beb359b..c25945067e 100755
--- a/indra/llmessage/tests/testrunner.py
+++ b/indra/llmessage/tests/testrunner.py
@@ -27,13 +27,12 @@ Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
$/LicenseInfo$
"""
-from __future__ import with_statement
-
import os
import sys
import re
import errno
import socket
+import subprocess
VERBOSE = os.environ.get("INTEGRATION_TEST_VERBOSE", "0") # default to quiet
# Support usage such as INTEGRATION_TEST_VERBOSE=off -- distressing to user if
@@ -47,6 +46,9 @@ if VERBOSE:
else:
debug = lambda *args: None
+class Error(Exception):
+ pass
+
def freeport(portlist, expr):
"""
Find a free server port to use. Specifically, evaluate 'expr' (a
@@ -141,34 +143,73 @@ def freeport(portlist, expr):
raise
def run(*args, **kwds):
- """All positional arguments collectively form a command line, executed as
- a synchronous child process.
- In addition, pass server=new_thread_instance as an explicit keyword (to
- differentiate it from an additional command-line argument).
- new_thread_instance should be an instantiated but not yet started Thread
- subclass instance, e.g.:
- run("python", "-c", 'print "Hello, world!"', server=TestHTTPServer(name="httpd"))
"""
- # If there's no server= keyword arg, don't start a server thread: simply
- # run a child process.
+ Run a specified command as a synchronous child process, optionally
+ launching a server Thread during the run.
+
+ All positional arguments collectively form a command line. The first
+ positional argument names the program file to execute.
+
+ Returns the termination code of the child process.
+
+ In addition, you may pass keyword-only arguments:
+
+ use_path=True: allow a simple filename as command and search PATH for that
+ filename. (This argument is retained for backwards compatibility but is
+ now the default behavior.)
+
+ server_inst: an instance of a subclass of SocketServer.BaseServer.
+
+ When you pass server_inst, run() calls its handle_request() method in a
+ loop until the child process terminates.
+ """
+ # server= keyword arg is discontinued
try:
thread = kwds.pop("server")
except KeyError:
pass
else:
- # Start server thread. Note that this and all other comm server
- # threads should be daemon threads: we'll let them run "forever,"
- # confident that the whole process will terminate when the main thread
- # terminates, which will be when the child process terminates.
- thread.setDaemon(True)
- thread.start()
- # choice of os.spawnv():
- # - [v vs. l] pass a list of args vs. individual arguments,
- # - [no p] don't use the PATH because we specifically want to invoke the
- # executable passed as our first arg,
- # - [no e] child should inherit this process's environment.
+ raise Error("Obsolete call to testrunner.run(): pass server_inst=, not server=")
+
debug("Running %s...", " ".join(args))
- rc = os.spawnv(os.P_WAIT, args[0], args)
+
+ try:
+ server_inst = kwds.pop("server_inst")
+ except KeyError:
+ # Without server_inst, this is very simple: just run child process.
+ rc = subprocess.call(args)
+ else:
+ # We're being asked to run a local server while the child process
+ # runs. We used to launch a daemon thread calling
+ # server_inst.serve_forever(), then eventually call sys.exit() with
+ # the daemon thread still running -- but in recent versions of Python
+ # 2, even when you call sys.exit(0), apparently killing the thread
+ # causes the Python runtime to force the process termination code
+ # nonzero. So now we avoid the extra thread altogether.
+
+ # SocketServer.BaseServer.handle_request() honors a 'timeout'
+ # attribute, if it's set to something other than None.
+ # We pick 0.5 seconds because that's the default poll timeout for
+ # BaseServer.serve_forever(), which is what we used to use.
+ server_inst.timeout = 0.5
+
+ child = subprocess.Popen(args)
+ while child.poll() is None:
+ # Setting server_inst.timeout is what keeps this handle_request()
+ # call from blocking "forever." Interestingly, looping over
+ # handle_request() with a timeout is very like the implementation
+ # of serve_forever(). We just check a different flag to break out.
+ # It might be interesting if handle_request() returned an
+ # indication of whether it in fact handled a request or timed out.
+ # Oddly, it doesn't. We could discover that by overriding
+ # handle_timeout(), whose default implementation does nothing --
+ # but in fact we really don't care. All that matters is that we
+ # regularly poll both the child process and the server socket.
+ server_inst.handle_request()
+ # We don't bother to capture the rc returned by child.poll() because
+ # poll() is already defined to capture that in its returncode attr.
+ rc = child.returncode
+
debug("%s returned %s", args[0], rc)
return rc