diff options
| -rw-r--r-- | indra/llmessage/llavatarnamecache.cpp | 281 | ||||
| -rw-r--r-- | indra/llmessage/llavatarnamecache.h | 98 | ||||
| -rw-r--r-- | indra/newview/llappviewer.cpp | 13 | ||||
| -rw-r--r-- | indra/newview/llavatarlist.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/llfloaterconversationpreview.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/llfloaterimcontainer.cpp | 4 | ||||
| -rw-r--r-- | indra/newview/llfloaterimnearbychat.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/llfloaterpreference.cpp | 4 | ||||
| -rw-r--r-- | indra/newview/llimprocessing.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/llimview.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/llnotificationhandlerutil.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/llstartup.cpp | 9 | ||||
| -rw-r--r-- | indra/newview/llviewermenu.cpp | 1 | 
13 files changed, 220 insertions, 202 deletions
| diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp index ba1a2a035e..6a287f0cc5 100644 --- a/indra/llmessage/llavatarnamecache.cpp +++ b/indra/llmessage/llavatarnamecache.cpp @@ -49,101 +49,22 @@  #include <map>  #include <set> -namespace LLAvatarNameCache -{ -	use_display_name_signal_t mUseDisplayNamesSignal; - -	// Cache starts in a paused state until we can determine if the -	// current region supports display names. -	bool sRunning = false; -	 -	// Use the People API (modern) for fetching name if true. Use the old legacy protocol if false. -	// For testing, there's a UsePeopleAPI setting that can be flipped (must restart viewer). -	bool sUsePeopleAPI = true; -	 -	// Base lookup URL for name service. -	// On simulator, loaded from indra.xml -	// On viewer, usually a simulator capability (at People API team's request) -	// Includes the trailing slash, like "http://pdp60.lindenlab.com:8000/agents/" -	std::string sNameLookupURL; - -	// Accumulated agent IDs for next query against service -	typedef std::set<LLUUID> ask_queue_t; -	ask_queue_t sAskQueue; - -	// Agent IDs that have been requested, but with no reply. -	// Maps agent ID to frame time request was made. -	typedef std::map<LLUUID, F64> pending_queue_t; -	pending_queue_t sPendingQueue; - -	// Callbacks to fire when we received a name. -	// May have multiple callbacks for a single ID, which are -	// represented as multiple slots bound to the signal. -	// Avoid copying signals via pointers. -	typedef std::map<LLUUID, callback_signal_t*> signal_map_t; -	signal_map_t sSignalMap; - -	// The cache at last, i.e. avatar names we know about. -	typedef std::map<LLUUID, LLAvatarName> cache_t; -	cache_t sCache; - -	// Send bulk lookup requests a few times a second at most. -	// Only need per-frame timing resolution. -	LLFrameTimer sRequestTimer; - -    // Maximum time an unrefreshed cache entry is allowed. -    const F64 MAX_UNREFRESHED_TIME = 20.0 * 60.0; - -    // Time when unrefreshed cached names were checked last. -    static F64 sLastExpireCheck; - -	// Time-to-live for a temp cache entry. -	const F64 TEMP_CACHE_ENTRY_LIFETIME = 60.0; - -    LLCore::HttpRequest::ptr_t		sHttpRequest; -    LLCore::HttpHeaders::ptr_t		sHttpHeaders; -    LLCore::HttpOptions::ptr_t		sHttpOptions; -    LLCore::HttpRequest::policy_t	sHttpPolicy; -    LLCore::HttpRequest::priority_t	sHttpPriority; - -	//----------------------------------------------------------------------- -	// Internal methods -	//----------------------------------------------------------------------- - -	// Handle name response off network. -	void processName(const LLUUID& agent_id, -					 const LLAvatarName& av_name); - -	void requestNamesViaCapability(); - -	// Legacy name system callbacks -	void legacyNameCallback(const LLUUID& agent_id, -							const std::string& full_name, -							bool is_group); -	void legacyNameFetch(const LLUUID& agent_id, -						 const std::string& full_name, -						 bool is_group); -	 -	void requestNamesViaLegacy(); - -	// Do a single callback to a given slot -	void fireSignal(const LLUUID& agent_id, -					const callback_slot_t& slot, -					const LLAvatarName& av_name); -	 -	// Is a request in-flight over the network? -	bool isRequestPending(const LLUUID& agent_id); -	// Erase expired names from cache -	void eraseUnrefreshed(); +// Time-to-live for a temp cache entry. +const F64 TEMP_CACHE_ENTRY_LIFETIME = 60.0; +// Maximum time an unrefreshed cache entry is allowed. +const F64 MAX_UNREFRESHED_TIME = 20.0 * 60.0; -    bool expirationFromCacheControl(const LLSD& headers, F64 *expires); +// Send bulk lookup requests a few times a second at most. +// Only need per-frame timing resolution. +static LLFrameTimer sRequestTimer; -    // This is a coroutine. -    void requestAvatarNameCache_(std::string url, std::vector<LLUUID> agentIds); - -    void handleAvNameCacheSuccess(const LLSD &data, const LLSD &httpResult); -} +// static to avoid unnessesary dependencies +LLCore::HttpRequest::ptr_t		sHttpRequest; +LLCore::HttpHeaders::ptr_t		sHttpHeaders; +LLCore::HttpOptions::ptr_t		sHttpOptions; +LLCore::HttpRequest::policy_t	sHttpPolicy; +LLCore::HttpRequest::priority_t	sHttpPriority;  /* Sample response:  <?xml version="1.0"?> @@ -187,6 +108,30 @@ namespace LLAvatarNameCache  // Coroutine for sending and processing avatar name cache requests.    // Do not call directly.  See documentation in lleventcoro.h and llcoro.h for  // further explanation. + +LLAvatarNameCache::LLAvatarNameCache() +{ +    // Will be set to running later +    // For now fail immediate lookups and query async ones. +    mRunning = false; + +    mUsePeopleAPI = true; + +    sHttpRequest = LLCore::HttpRequest::ptr_t(new LLCore::HttpRequest()); +    sHttpHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders()); +    sHttpOptions = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions()); +    sHttpPolicy = LLCore::HttpRequest::DEFAULT_POLICY_ID; +    sHttpPriority = 0; +} + +LLAvatarNameCache::~LLAvatarNameCache() +{ +    sHttpRequest.reset(); +    sHttpHeaders.reset(); +    sHttpOptions.reset(); +    mCache.clear(); +} +  void LLAvatarNameCache::requestAvatarNameCache_(std::string url, std::vector<LLUUID> agentIds)  {      LL_DEBUGS("AvNameCache") << "Entering coroutine " << LLCoros::instance().getName() @@ -205,7 +150,7 @@ void LLAvatarNameCache::requestAvatarNameCache_(std::string url, std::vector<LLU      {          bool success = true; -        LLCoreHttpUtil::HttpCoroutineAdapter httpAdapter("NameCache", LLAvatarNameCache::sHttpPolicy); +        LLCoreHttpUtil::HttpCoroutineAdapter httpAdapter("NameCache", sHttpPolicy);          LLSD results = httpAdapter.getAndSuspend(sHttpRequest, url);          LL_DEBUGS() << results << LL_ENDL; @@ -233,12 +178,12 @@ void LLAvatarNameCache::requestAvatarNameCache_(std::string url, std::vector<LLU              for ( ; it != agentIds.end(); ++it)              {                  const LLUUID& agent_id = *it; -                LLAvatarNameCache::handleAgentError(agent_id); +                LLAvatarNameCache::getInstance()->handleAgentError(agent_id);              }              return;          } -        LLAvatarNameCache::handleAvNameCacheSuccess(results, httpResults); +        LLAvatarNameCache::getInstance()->handleAvNameCacheSuccess(results, httpResults);      }      catch (...) @@ -300,15 +245,15 @@ void LLAvatarNameCache::handleAvNameCacheSuccess(const LLSD &data, const LLSD &h          }      }      LL_DEBUGS("AvNameCache") << "LLAvatarNameResponder::result " -        << LLAvatarNameCache::sCache.size() << " cached names" +        << LLAvatarNameCache::mCache.size() << " cached names"          << LL_ENDL;  }  // Provide some fallback for agents that return errors  void LLAvatarNameCache::handleAgentError(const LLUUID& agent_id)  { -	std::map<LLUUID,LLAvatarName>::iterator existing = sCache.find(agent_id); -	if (existing == sCache.end()) +	std::map<LLUUID,LLAvatarName>::iterator existing = mCache.find(agent_id); +	if (existing == mCache.end())      {          // there is no existing cache entry, so make a temporary name from legacy          LL_WARNS("AvNameCache") << "LLAvatarNameCache get legacy for agent " @@ -322,7 +267,7 @@ void LLAvatarNameCache::handleAgentError(const LLUUID& agent_id)          // been returned by the get method, there is no need to signal anyone          // Clear this agent from the pending list -        LLAvatarNameCache::sPendingQueue.erase(agent_id); +        LLAvatarNameCache::mPendingQueue.erase(agent_id);          LLAvatarName& av_name = existing->second;          LL_DEBUGS("AvNameCache") << "LLAvatarNameCache use cache for agent " << agent_id << LL_ENDL; @@ -341,19 +286,19 @@ void LLAvatarNameCache::processName(const LLUUID& agent_id, const LLAvatarName&  	}  	// Add to the cache -	sCache[agent_id] = av_name; +	mCache[agent_id] = av_name;  	// Suppress request from the queue -	sPendingQueue.erase(agent_id); +	mPendingQueue.erase(agent_id);  	// Signal everyone waiting on this name -	signal_map_t::iterator sig_it =	sSignalMap.find(agent_id); -	if (sig_it != sSignalMap.end()) +	signal_map_t::iterator sig_it =	mSignalMap.find(agent_id); +	if (sig_it != mSignalMap.end())  	{  		callback_signal_t* signal = sig_it->second;  		(*signal)(agent_id, av_name); -		sSignalMap.erase(agent_id); +		mSignalMap.erase(agent_id);  		delete signal;  		signal = NULL; @@ -379,16 +324,16 @@ void LLAvatarNameCache::requestNamesViaCapability()  	U32 ids = 0;  	ask_queue_t::const_iterator it; -	while(!sAskQueue.empty()) +	while(!mAskQueue.empty())  	{ -		it = sAskQueue.begin(); +		it = mAskQueue.begin();  		LLUUID agent_id = *it; -		sAskQueue.erase(it); +		mAskQueue.erase(it);  		if (url.empty())  		{  			// ...starting new request -			url += sNameLookupURL; +			url += mNameLookupURL;  			url += "?ids=";  			ids = 1;  		} @@ -402,7 +347,7 @@ void LLAvatarNameCache::requestNamesViaCapability()  		agent_ids.push_back(agent_id);  		// mark request as pending -		sPendingQueue[agent_id] = now; +		mPendingQueue[agent_id] = now;  		if (url.size() > NAME_URL_SEND_THRESHOLD)  		{ @@ -432,7 +377,7 @@ void LLAvatarNameCache::legacyNameCallback(const LLUUID& agent_id,  	// Retrieve the name and set it to never (or almost never...) expire: when we are using the legacy  	// protocol, we do not get an expiration date for each name and there's no reason to ask the   	// data again and again so we set the expiration time to the largest value admissible. -	std::map<LLUUID,LLAvatarName>::iterator av_record = sCache.find(agent_id); +	std::map<LLUUID,LLAvatarName>::iterator av_record = LLAvatarNameCache::getInstance()->mCache.find(agent_id);  	LLAvatarName& av_name = av_record->second;  	av_name.setExpires(MAX_UNREFRESHED_TIME);  } @@ -451,7 +396,7 @@ void LLAvatarNameCache::legacyNameFetch(const LLUUID& agent_id,  	av_name.fromString(full_name);  	// Add to cache: we're still using the new cache even if we're using the old (legacy) protocol. -	processName(agent_id, av_name); +	LLAvatarNameCache::getInstance()->processName(agent_id, av_name);  }  void LLAvatarNameCache::requestNamesViaLegacy() @@ -460,15 +405,15 @@ void LLAvatarNameCache::requestNamesViaLegacy()  	F64 now = LLFrameTimer::getTotalSeconds();  	std::string full_name;  	ask_queue_t::const_iterator it; -	for (S32 requests = 0; !sAskQueue.empty() && requests < MAX_REQUESTS; ++requests) +	for (S32 requests = 0; !mAskQueue.empty() && requests < MAX_REQUESTS; ++requests)  	{ -		it = sAskQueue.begin(); +		it = mAskQueue.begin();  		LLUUID agent_id = *it; -		sAskQueue.erase(it); +		mAskQueue.erase(it);  		// Mark as pending first, just in case the callback is immediately  		// invoked below.  This should never happen in practice. -		sPendingQueue[agent_id] = now; +		mPendingQueue[agent_id] = now;  		LL_DEBUGS("AvNameCache") << "agent " << agent_id << LL_ENDL; @@ -477,26 +422,6 @@ void LLAvatarNameCache::requestNamesViaLegacy()  	}  } -void LLAvatarNameCache::initClass(bool running, bool usePeopleAPI) -{ -	sRunning = running; -	sUsePeopleAPI = usePeopleAPI; - -    sHttpRequest = LLCore::HttpRequest::ptr_t(new LLCore::HttpRequest()); -    sHttpHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders()); -    sHttpOptions = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions()); -    sHttpPolicy = LLCore::HttpRequest::DEFAULT_POLICY_ID; -    sHttpPriority = 0; -} - -void LLAvatarNameCache::cleanupClass() -{ -    sHttpRequest.reset(); -    sHttpHeaders.reset(); -    sHttpOptions.reset(); -    sCache.clear(); -} -  bool LLAvatarNameCache::importFile(std::istream& istr)  {  	LLSD data; @@ -517,9 +442,9 @@ bool LLAvatarNameCache::importFile(std::istream& istr)  	{  		agent_id.set(it->first);  		av_name.fromLLSD( it->second ); -		sCache[agent_id] = av_name; +		mCache[agent_id] = av_name;  	} -    LL_INFOS("AvNameCache") << "LLAvatarNameCache loaded " << sCache.size() << LL_ENDL; +    LL_INFOS("AvNameCache") << "LLAvatarNameCache loaded " << mCache.size() << LL_ENDL;  	// Some entries may have expired since the cache was stored,      // but they will be flushed in the first call to eraseUnrefreshed      // from LLAvatarNameResponder::idle @@ -531,9 +456,9 @@ void LLAvatarNameCache::exportFile(std::ostream& ostr)  {  	LLSD agents;  	F64 max_unrefreshed = LLFrameTimer::getTotalSeconds() - MAX_UNREFRESHED_TIME; -    LL_INFOS("AvNameCache") << "LLAvatarNameCache at exit cache has " << sCache.size() << LL_ENDL; -	cache_t::const_iterator it = sCache.begin(); -	for ( ; it != sCache.end(); ++it) +    LL_INFOS("AvNameCache") << "LLAvatarNameCache at exit cache has " << mCache.size() << LL_ENDL; +	cache_t::const_iterator it = mCache.begin(); +	for ( ; it != mCache.end(); ++it)  	{  		const LLUUID& agent_id = it->first;  		const LLAvatarName& av_name = it->second; @@ -552,23 +477,28 @@ void LLAvatarNameCache::exportFile(std::ostream& ostr)  void LLAvatarNameCache::setNameLookupURL(const std::string& name_lookup_url)  { -	sNameLookupURL = name_lookup_url; +	mNameLookupURL = name_lookup_url;  }  bool LLAvatarNameCache::hasNameLookupURL()  { -	return !sNameLookupURL.empty(); +	return !mNameLookupURL.empty(); +} + +void LLAvatarNameCache::setUsePeopleAPI(bool use_api) +{ +    mUsePeopleAPI = use_api;  }  bool LLAvatarNameCache::usePeopleAPI()  { -	return hasNameLookupURL() && sUsePeopleAPI; +	return hasNameLookupURL() && mUsePeopleAPI;  }  void LLAvatarNameCache::idle()  {  	// By convention, start running at first idle() call -	sRunning = true; +	mRunning = true;  	// *TODO: Possibly re-enabled this based on People API load measurements  	// 100 ms is the threshold for "user speed" operations, so we can @@ -579,7 +509,7 @@ void LLAvatarNameCache::idle()  		return;  	} -	if (!sAskQueue.empty()) +	if (!mAskQueue.empty())  	{          if (usePeopleAPI())          { @@ -592,7 +522,7 @@ void LLAvatarNameCache::idle()          }  	} -	if (sAskQueue.empty()) +	if (mAskQueue.empty())  	{  		// cleared the list, reset the request timer.  		sRequestTimer.resetWithExpiry(SECS_BETWEEN_REQUESTS); @@ -607,8 +537,8 @@ bool LLAvatarNameCache::isRequestPending(const LLUUID& agent_id)  	bool isPending = false;  	const F64 PENDING_TIMEOUT_SECS = 5.0 * 60.0; -	pending_queue_t::const_iterator it = sPendingQueue.find(agent_id); -	if (it != sPendingQueue.end()) +	pending_queue_t::const_iterator it = mPendingQueue.find(agent_id); +	if (it != mPendingQueue.end())  	{  		// in the list of requests in flight, retry if too old  		F64 expire_time = LLFrameTimer::getTotalSeconds() - PENDING_TIMEOUT_SECS; @@ -622,11 +552,11 @@ void LLAvatarNameCache::eraseUnrefreshed()  	F64 now = LLFrameTimer::getTotalSeconds();  	F64 max_unrefreshed = now - MAX_UNREFRESHED_TIME; -    if (!sLastExpireCheck || sLastExpireCheck < max_unrefreshed) +    if (!mLastExpireCheck || mLastExpireCheck < max_unrefreshed)      { -        sLastExpireCheck = now; +        mLastExpireCheck = now;          S32 expired = 0; -        for (cache_t::iterator it = sCache.begin(); it != sCache.end();) +        for (cache_t::iterator it = mCache.begin(); it != mCache.end();)          {              const LLAvatarName& av_name = it->second;              if (av_name.mExpires < max_unrefreshed) @@ -635,7 +565,7 @@ void LLAvatarNameCache::eraseUnrefreshed()                                           << " user '" << av_name.getAccountName() << "' "                                           << "expired " << now - av_name.mExpires << " secs ago"                                           << LL_ENDL; -                sCache.erase(it++); +                mCache.erase(it++);                  expired++;              }  			else @@ -644,19 +574,24 @@ void LLAvatarNameCache::eraseUnrefreshed()  			}          }          LL_INFOS("AvNameCache") << "LLAvatarNameCache expired " << expired << " cached avatar names, " -                                << sCache.size() << " remaining" << LL_ENDL; +                                << mCache.size() << " remaining" << LL_ENDL;  	}  } +//static, wrapper +bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name) +{ +    return LLAvatarNameCache::getInstance()->getName(agent_id, av_name); +}  // fills in av_name if it has it in the cache, even if expired (can check expiry time)  // returns bool specifying  if av_name was filled, false otherwise -bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name) +bool LLAvatarNameCache::getName(const LLUUID& agent_id, LLAvatarName *av_name)  { -	if (sRunning) +	if (mRunning)  	{  		// ...only do immediate lookups when cache is running -		std::map<LLUUID,LLAvatarName>::iterator it = sCache.find(agent_id); -		if (it != sCache.end()) +		std::map<LLUUID,LLAvatarName>::iterator it = mCache.find(agent_id); +		if (it != mCache.end())  		{  			*av_name = it->second; @@ -667,7 +602,7 @@ bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name)  				{  					LL_DEBUGS("AvNameCache") << "LLAvatarNameCache refresh agent " << agent_id  											 << LL_ENDL; -					sAskQueue.insert(agent_id); +					mAskQueue.insert(agent_id);  				}  			} @@ -678,7 +613,7 @@ bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name)  	if (!isRequestPending(agent_id))  	{  		LL_DEBUGS("AvNameCache") << "LLAvatarNameCache queue request for agent " << agent_id << LL_ENDL; -		sAskQueue.insert(agent_id); +		mAskQueue.insert(agent_id);  	}  	return false; @@ -693,15 +628,21 @@ void LLAvatarNameCache::fireSignal(const LLUUID& agent_id,  	signal(agent_id, av_name);  } +// static, wrapper  LLAvatarNameCache::callback_connection_t LLAvatarNameCache::get(const LLUUID& agent_id, callback_slot_t slot)  { +    return LLAvatarNameCache::getInstance()->getNameCallback(agent_id, slot); +} + +LLAvatarNameCache::callback_connection_t LLAvatarNameCache::getNameCallback(const LLUUID& agent_id, callback_slot_t slot) +{  	callback_connection_t connection; -	if (sRunning) +	if (mRunning)  	{  		// ...only do immediate lookups when cache is running -		std::map<LLUUID,LLAvatarName>::iterator it = sCache.find(agent_id); -		if (it != sCache.end()) +		std::map<LLUUID,LLAvatarName>::iterator it = mCache.find(agent_id); +		if (it != mCache.end())  		{  			const LLAvatarName& av_name = it->second; @@ -717,17 +658,17 @@ LLAvatarNameCache::callback_connection_t LLAvatarNameCache::get(const LLUUID& ag  	// schedule a request  	if (!isRequestPending(agent_id))  	{ -		sAskQueue.insert(agent_id); +		mAskQueue.insert(agent_id);  	}  	// always store additional callback, even if request is pending -	signal_map_t::iterator sig_it = sSignalMap.find(agent_id); -	if (sig_it == sSignalMap.end()) +	signal_map_t::iterator sig_it = mSignalMap.find(agent_id); +	if (sig_it == mSignalMap.end())  	{  		// ...new callback for this id  		callback_signal_t* signal = new callback_signal_t();  		connection = signal->connect(slot); -		sSignalMap[agent_id] = signal; +		mSignalMap[agent_id] = signal;  	}  	else  	{ @@ -760,20 +701,20 @@ void LLAvatarNameCache::setUseUsernames(bool use)  void LLAvatarNameCache::erase(const LLUUID& agent_id)  { -	sCache.erase(agent_id); +	mCache.erase(agent_id);  }  void LLAvatarNameCache::insert(const LLUUID& agent_id, const LLAvatarName& av_name)  {  	// *TODO: update timestamp if zero? -	sCache[agent_id] = av_name; +	mCache[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) +    std::map<LLUUID, LLAvatarName>::iterator end = mCache.end(); +    for (it = mCache.begin(); it != end; ++it)      {          if (it->second.getUserName() == name)          { diff --git a/indra/llmessage/llavatarnamecache.h b/indra/llmessage/llavatarnamecache.h index 63e067c939..ba89d569f3 100644 --- a/indra/llmessage/llavatarnamecache.h +++ b/indra/llmessage/llavatarnamecache.h @@ -29,21 +29,20 @@  #define LLAVATARNAMECACHE_H  #include "llavatarname.h"	// for convenience +#include "llsingleton.h"  #include <boost/signals2.hpp> +#include <set>  class LLSD;  class LLUUID; -namespace LLAvatarNameCache +class LLAvatarNameCache : public LLSingleton<LLAvatarNameCache>  { +	LLSINGLETON(LLAvatarNameCache); +	~LLAvatarNameCache(); +public:  	typedef boost::signals2::signal<void (void)> use_display_name_signal_t; -	// Until the cache is set running, immediate lookups will fail and -	// async lookups will be queued.  This allows us to block requests -	// until we know if the first region supports display names. -	void initClass(bool running, bool usePeopleAPI); -	void cleanupClass(); -  	// Import/export the name cache to file.  	bool importFile(std::istream& istr);  	void exportFile(std::ostream& ostr); @@ -55,6 +54,7 @@ namespace LLAvatarNameCache  	// Do we have a valid lookup URL, i.e. are we trying to use the  	// more recent display name lookup system?  	bool hasNameLookupURL(); +	void setUsePeopleAPI(bool use_api);  	bool usePeopleAPI();  	// Periodically makes a batch request for display names not already in @@ -63,7 +63,8 @@ namespace LLAvatarNameCache  	// If name is in cache, returns true and fills in provided LLAvatarName  	// otherwise returns false. -	bool get(const LLUUID& agent_id, LLAvatarName *av_name); +	static bool get(const LLUUID& agent_id, LLAvatarName *av_name); +	bool getName(const LLUUID& agent_id, LLAvatarName *av_name);  	// Callback types for get() below  	typedef boost::signals2::signal< @@ -74,7 +75,8 @@ namespace LLAvatarNameCache  	// Fetches name information and calls callbacks.  	// If name information is in cache, callbacks will be called immediately. -	callback_connection_t get(const LLUUID& agent_id, callback_slot_t slot); +	static callback_connection_t get(const LLUUID& agent_id, callback_slot_t slot); +	callback_connection_t getNameCallback(const LLUUID& agent_id, callback_slot_t slot);  	// Set display name: flips the switch and triggers the callbacks.  	void setUseDisplayNames(bool use); @@ -100,7 +102,83 @@ namespace LLAvatarNameCache      F64 nameExpirationFromHeaders(const LLSD& headers);  	void addUseDisplayNamesCallback(const use_display_name_signal_t::slot_type& cb); -} + +private: +    // Handle name response off network. +    void processName(const LLUUID& agent_id, +        const LLAvatarName& av_name); + +    void requestNamesViaCapability(); + +    // Legacy name system callbacks +    static void legacyNameCallback(const LLUUID& agent_id, +        const std::string& full_name, +        bool is_group); +    static void legacyNameFetch(const LLUUID& agent_id, +        const std::string& full_name, +        bool is_group); + +    void requestNamesViaLegacy(); + +    // Do a single callback to a given slot +    void fireSignal(const LLUUID& agent_id, +        const callback_slot_t& slot, +        const LLAvatarName& av_name); + +    // Is a request in-flight over the network? +    bool isRequestPending(const LLUUID& agent_id); + +    // Erase expired names from cache +    void eraseUnrefreshed(); + +    bool expirationFromCacheControl(const LLSD& headers, F64 *expires); + +    // This is a coroutine. +    static void requestAvatarNameCache_(std::string url, std::vector<LLUUID> agentIds); + +    void handleAvNameCacheSuccess(const LLSD &data, const LLSD &httpResult); + +private: + +    use_display_name_signal_t mUseDisplayNamesSignal; + +    // Cache starts in a paused state until we can determine if the +    // current region supports display names. +    bool mRunning; + +    // Use the People API (modern) for fetching name if true. Use the old legacy protocol if false. +    // For testing, there's a UsePeopleAPI setting that can be flipped (must restart viewer). +    bool mUsePeopleAPI; + +    // Base lookup URL for name service. +    // On simulator, loaded from indra.xml +    // On viewer, usually a simulator capability (at People API team's request) +    // Includes the trailing slash, like "http://pdp60.lindenlab.com:8000/agents/" +    std::string mNameLookupURL; + +    // Accumulated agent IDs for next query against service +    typedef std::set<LLUUID> ask_queue_t; +    ask_queue_t mAskQueue; + +    // Agent IDs that have been requested, but with no reply. +    // Maps agent ID to frame time request was made. +    typedef std::map<LLUUID, F64> pending_queue_t; +    pending_queue_t mPendingQueue; + +    // Callbacks to fire when we received a name. +    // May have multiple callbacks for a single ID, which are +    // represented as multiple slots bound to the signal. +    // Avoid copying signals via pointers. +    typedef std::map<LLUUID, callback_signal_t*> signal_map_t; +    signal_map_t mSignalMap; + +    // The cache at last, i.e. avatar names we know about. +    typedef std::map<LLUUID, LLAvatarName> cache_t; +    cache_t mCache; + +    // Time when unrefreshed cached names were checked last. +    F64 mLastExpireCheck; +};  // Parse a cache-control header to get the max-age delta-seconds.  // Returns true if header has max-age param and it parses correctly. diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 151039acce..823ded7a50 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -4509,7 +4509,7 @@ void LLAppViewer::loadNameCache()  	llifstream name_cache_stream(filename.c_str());  	if(name_cache_stream.is_open())  	{ -		if ( ! LLAvatarNameCache::importFile(name_cache_stream)) +		if ( ! LLAvatarNameCache::getInstance()->importFile(name_cache_stream))          {              LL_WARNS("AppInit") << "removing invalid '" << filename << "'" << LL_ENDL;              name_cache_stream.close(); @@ -4536,7 +4536,7 @@ void LLAppViewer::saveNameCache()  	llofstream name_cache_stream(filename.c_str());  	if(name_cache_stream.is_open())  	{ -		LLAvatarNameCache::exportFile(name_cache_stream); +		LLAvatarNameCache::getInstance()->exportFile(name_cache_stream);      }      // real names cache @@ -5143,7 +5143,8 @@ void LLAppViewer::idleNameCache()  	// granted to neighbor regions before the main agent gets there.  Can't  	// do it in the move-into-region code because cap not guaranteed to be  	// granted yet, for example on teleport. -	bool had_capability = LLAvatarNameCache::hasNameLookupURL(); +	LLAvatarNameCache *name_cache = LLAvatarNameCache::getInstance(); +	bool had_capability = LLAvatarNameCache::getInstance()->hasNameLookupURL();  	std::string name_lookup_url;  	name_lookup_url.reserve(128); // avoid a memory allocation below  	name_lookup_url = region->getCapability("GetDisplayNames"); @@ -5160,12 +5161,12 @@ void LLAppViewer::idleNameCache()  	    {  		    name_lookup_url += '/';  	    } -		LLAvatarNameCache::setNameLookupURL(name_lookup_url); +		name_cache->setNameLookupURL(name_lookup_url);  	}  	else  	{  		// Display names not available on this region -		LLAvatarNameCache::setNameLookupURL( std::string() ); +		name_cache->setNameLookupURL( std::string() );  	}  	// Error recovery - did we change state? @@ -5175,7 +5176,7 @@ void LLAppViewer::idleNameCache()  		LLVOAvatar::invalidateNameTags();  	} -	LLAvatarNameCache::idle(); +	name_cache->idle();  }  // diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp index 513f25e301..b0715a3afd 100644 --- a/indra/newview/llavatarlist.cpp +++ b/indra/newview/llavatarlist.cpp @@ -154,7 +154,7 @@ LLAvatarList::LLAvatarList(const Params& p)  		mLITUpdateTimer->start();  	} -	LLAvatarNameCache::addUseDisplayNamesCallback(boost::bind(&LLAvatarList::handleDisplayNamesOptionChanged, this)); +	LLAvatarNameCache::getInstance()->addUseDisplayNamesCallback(boost::bind(&LLAvatarList::handleDisplayNamesOptionChanged, this));  } diff --git a/indra/newview/llfloaterconversationpreview.cpp b/indra/newview/llfloaterconversationpreview.cpp index 66198b3bf6..4905ce5fc2 100644 --- a/indra/newview/llfloaterconversationpreview.cpp +++ b/indra/newview/llfloaterconversationpreview.cpp @@ -221,7 +221,7 @@ void LLFloaterConversationPreview::showHistory()  		else   		{  			std::string legacy_name = gCacheName->buildLegacyName(from); -			from_id = LLAvatarNameCache::findIdByName(legacy_name); +			from_id = LLAvatarNameCache::getInstance()->findIdByName(legacy_name);   		}  		LLChat chat; diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index 30d05ae287..21420b122b 100644 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -237,7 +237,7 @@ BOOL LLFloaterIMContainer::postBuild()  	collapseMessagesPane(gSavedPerAccountSettings.getBOOL("ConversationsMessagePaneCollapsed"));  	collapseConversationsPane(gSavedPerAccountSettings.getBOOL("ConversationsListPaneCollapsed"), false); -	LLAvatarNameCache::addUseDisplayNamesCallback(boost::bind(&LLFloaterIMSessionTab::processChatHistoryStyleUpdate, false)); +	LLAvatarNameCache::getInstance()->addUseDisplayNamesCallback(boost::bind(&LLFloaterIMSessionTab::processChatHistoryStyleUpdate, false));  	mMicroChangedSignal = LLVoiceClient::getInstance()->MicroChangedCallback(boost::bind(&LLFloaterIMContainer::updateSpeakBtnState, this));  	if (! mMessagesPane->isCollapsed() && ! mConversationsPane->isCollapsed()) @@ -267,7 +267,7 @@ BOOL LLFloaterIMContainer::postBuild()  	// We'll take care of view updates on idle  	gIdleCallbacks.addFunction(idle, this);  	// When display name option change, we need to reload all participant names -	LLAvatarNameCache::addUseDisplayNamesCallback(boost::bind(&LLFloaterIMContainer::processParticipantsStyleUpdate, this)); +	LLAvatarNameCache::getInstance()->addUseDisplayNamesCallback(boost::bind(&LLFloaterIMContainer::processParticipantsStyleUpdate, this));      mParticipantRefreshTimer.setTimerExpirySec(0);      mParticipantRefreshTimer.start(); diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp index f9efd13608..a6531ed7e1 100644 --- a/indra/newview/llfloaterimnearbychat.cpp +++ b/indra/newview/llfloaterimnearbychat.cpp @@ -228,7 +228,7 @@ void LLFloaterIMNearbyChat::loadHistory()  		else   		{  			std::string legacy_name = gCacheName->buildLegacyName(from); -			from_id = LLAvatarNameCache::findIdByName(legacy_name); +			from_id = LLAvatarNameCache::getInstance()->findIdByName(legacy_name);   		}  		LLChat chat; diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 98e4cefebb..64a71c502d 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -278,13 +278,13 @@ bool callback_clear_browser_cache(const LLSD& notification, const LLSD& response  void handleNameTagOptionChanged(const LLSD& newvalue)  { -	LLAvatarNameCache::setUseUsernames(gSavedSettings.getBOOL("NameTagShowUsernames")); +	LLAvatarNameCache::getInstance()->setUseUsernames(gSavedSettings.getBOOL("NameTagShowUsernames"));  	LLVOAvatar::invalidateNameTags();  }  void handleDisplayNamesOptionChanged(const LLSD& newvalue)  { -	LLAvatarNameCache::setUseDisplayNames(newvalue.asBoolean()); +	LLAvatarNameCache::getInstance()->setUseDisplayNames(newvalue.asBoolean());  	LLVOAvatar::invalidateNameTags();  } diff --git a/indra/newview/llimprocessing.cpp b/indra/newview/llimprocessing.cpp index d59c301210..3606a439a6 100644 --- a/indra/newview/llimprocessing.cpp +++ b/indra/newview/llimprocessing.cpp @@ -695,7 +695,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,                  // The group notice packet does not have an AgentID.  Obtain one from the name cache.                  // If last name is "Resident" strip it out so the cache name lookup works.                  std::string legacy_name = gCacheName->buildLegacyName(original_name); -                agent_id = LLAvatarNameCache::findIdByName(legacy_name); +                agent_id = LLAvatarNameCache::getInstance()->findIdByName(legacy_name);                  if (agent_id.isNull())                  { diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 8ec8c0a563..fc2f50b3f6 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -806,7 +806,7 @@ void LLIMModel::LLIMSession::addMessagesFromHistory(const std::list<LLSD>& histo  		{  			// convert it to a legacy name if we have a complete name  			std::string legacy_name = gCacheName->buildLegacyName(from); -			from_id = LLAvatarNameCache::findIdByName(legacy_name); +			from_id = LLAvatarNameCache::getInstance()->findIdByName(legacy_name);  		}  		std::string timestamp = msg[LL_IM_TIME]; diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp index 6a58196760..9a3f1a853a 100644 --- a/indra/newview/llnotificationhandlerutil.cpp +++ b/indra/newview/llnotificationhandlerutil.cpp @@ -177,7 +177,7 @@ void LLHandlerUtil::logGroupNoticeToIMGroup(  	{  		// Legacy support and fallback method  		// if we can't retrieve sender id from group notice system message, try to lookup it from cache -		sender_id = LLAvatarNameCache::findIdByName(sender_name); +		sender_id = LLAvatarNameCache::getInstance()->findIdByName(sender_name);  	}  	logToIM(IM_SESSION_GROUP_START, group_name, sender_name, payload["message"], diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 8be453ad6c..15b3ba75c9 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -2833,9 +2833,10 @@ void LLStartUp::initNameCache()  	// Start cache in not-running state until we figure out if we have  	// capabilities for display name lookup -	LLAvatarNameCache::initClass(false,gSavedSettings.getBOOL("UsePeopleAPI")); -	LLAvatarNameCache::setUseDisplayNames(gSavedSettings.getBOOL("UseDisplayNames")); -	LLAvatarNameCache::setUseUsernames(gSavedSettings.getBOOL("NameTagShowUsernames")); +	LLAvatarNameCache* cache_inst = LLAvatarNameCache::getInstance(); +	cache_inst->setUsePeopleAPI(gSavedSettings.getBOOL("UsePeopleAPI")); +	cache_inst->setUseDisplayNames(gSavedSettings.getBOOL("UseDisplayNames")); +	cache_inst->setUseUsernames(gSavedSettings.getBOOL("NameTagShowUsernames"));  } @@ -2850,8 +2851,6 @@ void LLStartUp::initExperiences()  void LLStartUp::cleanupNameCache()  { -	SUBSYSTEM_CLEANUP(LLAvatarNameCache); -  	delete gCacheName;  	gCacheName = NULL;  } diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 8f90225359..f1c073ed84 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -8653,7 +8653,6 @@ class LLWorldPostProcess : public view_listener_t  void handle_flush_name_caches()  { -	SUBSYSTEM_CLEANUP(LLAvatarNameCache);  	if (gCacheName) gCacheName->clear();  } | 
