From aa3042ea331479128a65d890d44314cc7c630e2c Mon Sep 17 00:00:00 2001
From: Rider Linden
Date: Fri, 14 Aug 2015 16:45:26 -0700
Subject: MAINT-5506: Converted llmessage untrusted sim message responder to
coroutine. Removed HTTPSender, HTTPNullSender, HTTPCapSender. Moved
UntrustedMessageCap storage into LLHost Added boost libraries to
PROJECT_x_TEST linkage.
---
indra/newview/llstartup.cpp | 17 -----------------
1 file changed, 17 deletions(-)
(limited to 'indra/newview/llstartup.cpp')
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 6622fa7d9c..8f856b1300 100755
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -56,7 +56,6 @@
#include "llerrorcontrol.h"
#include "llfloaterreg.h"
#include "llfocusmgr.h"
-#include "llhttpsender.h"
#include "llfloaterimsession.h"
#include "lllocationhistory.h"
#include "llimageworker.h"
@@ -291,20 +290,6 @@ void callback_cache_name(const LLUUID& id, const std::string& full_name, bool is
// local classes
//
-namespace
-{
- class LLNullHTTPSender : public LLHTTPSender
- {
- virtual void send(const LLHost& host,
- const std::string& message, const LLSD& body,
- LLHTTPClient::ResponderPtr response) const
- {
- LL_WARNS("AppInit") << " attemped to send " << message << " to " << host
- << " with null sender" << LL_ENDL;
- }
- };
-}
-
void update_texture_fetch()
{
LLAppViewer::getTextureCache()->update(1); // unpauses the texture cache thread
@@ -510,8 +495,6 @@ bool idle_startup()
port = gSavedSettings.getU32("ConnectionPort");
}
- LLHTTPSender::setDefaultSender(new LLNullHTTPSender());
-
// TODO parameterize
const F32 circuit_heartbeat_interval = 5;
const F32 circuit_timeout = 100;
--
cgit v1.3
From 99e56eedabfe34dbfbfd8105759403173de72d44 Mon Sep 17 00:00:00 2001
From: Rider Linden
Date: Fri, 28 Aug 2015 16:55:33 -0700
Subject: MAINT-5575: Begin conversion to Singleton<> for Experience Cache.
Commited on branch so that I don't trigger a build of it until I'm ready.
--HG--
branch : MAINT-5575
---
indra/llmessage/llexperiencecache.cpp | 925 +++++++++++++++++-----------------
indra/llmessage/llexperiencecache.h | 67 ++-
indra/newview/llstartup.cpp | 5 +-
3 files changed, 515 insertions(+), 482 deletions(-)
(limited to 'indra/newview/llstartup.cpp')
diff --git a/indra/llmessage/llexperiencecache.cpp b/indra/llmessage/llexperiencecache.cpp
index 52b60a176e..d196d7da93 100644
--- a/indra/llmessage/llexperiencecache.cpp
+++ b/indra/llmessage/llexperiencecache.cpp
@@ -34,608 +34,613 @@
#include "boost/tokenizer.hpp"
-namespace LLExperienceCache
-{
+typedef std::map KeyMap;
+KeyMap privateToPublicKeyMap;
- typedef std::map KeyMap;
- KeyMap privateToPublicKeyMap;
+void mapKeys(const LLSD& legacyKeys);
- void mapKeys(const LLSD& legacyKeys);
+std::string sLookupURL;
- std::string sLookupURL;
+typedef std::map ask_queue_t;
+ask_queue_t sAskQueue;
- typedef std::map ask_queue_t;
- ask_queue_t sAskQueue;
+typedef std::map pending_queue_t;
+pending_queue_t sPendingQueue;
- typedef std::map pending_queue_t;
- pending_queue_t sPendingQueue;
+LLExperienceCache::cache_t sCache;
+int sMaximumLookups = 10;
- cache_t sCache;
- int sMaximumLookups = 10;
+LLFrameTimer sRequestTimer;
- LLFrameTimer sRequestTimer;
+// Periodically clean out expired entries from the cache
+LLFrameTimer sEraseExpiredTimer;
- // Periodically clean out expired entries from the cache
- LLFrameTimer sEraseExpiredTimer;
+// 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 signal_map_t;
+signal_map_t sSignalMap;
- // 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 signal_map_t;
- signal_map_t sSignalMap;
+bool max_age_from_cache_control(const std::string& cache_control, S32 *max_age);
+void eraseExpired();
- bool max_age_from_cache_control(const std::string& cache_control, S32 *max_age);
- void eraseExpired();
+//=========================================================================
+LLExperienceCache::LLExperienceCache()
+{
+}
- void processExperience( const LLUUID& public_key, const LLSD& experience )
- {
- sCache[public_key]=experience;
- LLSD & row = sCache[public_key];
+LLExperienceCache::~LLExperienceCache()
+{
+}
- if(row.has(EXPIRES))
- {
- row[EXPIRES] = row[EXPIRES].asReal() + LLFrameTimer::getTotalSeconds();
- }
+//-------------------------------------------------------------------------
+void LLExperienceCache::importFile(std::istream& istr)
+{
+ LLSD data;
+ S32 parse_count = LLSDSerialize::fromXMLDocument(data, istr);
+ if (parse_count < 1) return;
- if(row.has(EXPERIENCE_ID))
- {
- sPendingQueue.erase(row[EXPERIENCE_ID].asUUID());
- }
+ LLSD experiences = data["experiences"];
- //signal
- signal_map_t::iterator sig_it = sSignalMap.find(public_key);
- if (sig_it != sSignalMap.end())
- {
- callback_signal_t* signal = sig_it->second;
- (*signal)(experience);
+ LLUUID public_key;
+ LLSD::map_const_iterator it = experiences.beginMap();
+ for (; it != experiences.endMap(); ++it)
+ {
+ public_key.set(it->first);
+ sCache[public_key] = it->second;
+ }
- sSignalMap.erase(public_key);
+ LL_DEBUGS("ExperienceCache") << "importFile() loaded " << sCache.size() << LL_ENDL;
+}
- delete signal;
- }
- }
+void LLExperienceCache::exportFile(std::ostream& ostr) const
+{
+ LLSD experiences;
- void initClass( )
- {
- }
+ cache_t::const_iterator it = sCache.begin();
+ for (; it != sCache.end(); ++it)
+ {
+ if (!it->second.has(EXPERIENCE_ID) || it->second[EXPERIENCE_ID].asUUID().isNull() ||
+ it->second.has("DoesNotExist") || (it->second.has(PROPERTIES) && it->second[PROPERTIES].asInteger() & PROPERTY_INVALID))
+ continue;
- const cache_t& getCached()
+ experiences[it->first.asString()] = it->second;
+ }
+
+ LLSD data;
+ data["experiences"] = experiences;
+
+ LLSDSerialize::toPrettyXML(data, ostr);
+}
+
+// *TODO$: Rider: These three functions not seem to be used... it may be useful in testing.
+void LLExperienceCache::bootstrap(const LLSD& legacyKeys, int initialExpiration)
+{
+ mapKeys(legacyKeys);
+ LLSD::array_const_iterator it = legacyKeys.beginArray();
+ for (/**/; it != legacyKeys.endArray(); ++it)
+ {
+ LLSD experience = *it;
+ if (experience.has(EXPERIENCE_ID))
+ {
+ if (!experience.has(EXPIRES))
+ {
+ experience[EXPIRES] = initialExpiration;
+ }
+ processExperience(experience[EXPERIENCE_ID].asUUID(), experience);
+ }
+ else
+ {
+ LL_WARNS("ExperienceCache")
+ << "Skipping bootstrap entry which is missing " << EXPERIENCE_ID
+ << LL_ENDL;
+ }
+ }
+}
+
+void LLExperienceCache::mapKeys(const LLSD& legacyKeys)
+{
+ LLSD::array_const_iterator exp = legacyKeys.beginArray();
+ for (/**/; exp != legacyKeys.endArray(); ++exp)
+ {
+ if (exp->has(LLExperienceCache::EXPERIENCE_ID) && exp->has(LLExperienceCache::PRIVATE_KEY))
+ {
+ privateToPublicKeyMap[(*exp)[LLExperienceCache::PRIVATE_KEY].asUUID()] = (*exp)[LLExperienceCache::EXPERIENCE_ID].asUUID();
+ }
+ }
+}
+
+LLUUID LLExperienceCache::getExperienceId(const LLUUID& private_key, bool null_if_not_found)
+{
+ if (private_key.isNull())
+ return LLUUID::null;
+
+ KeyMap::const_iterator it = privateToPublicKeyMap.find(private_key);
+ if (it == privateToPublicKeyMap.end())
+ {
+ if (null_if_not_found)
+ {
+ return LLUUID::null;
+ }
+ return private_key;
+ }
+ LL_WARNS("LLExperience") << "converted private key " << private_key << " to experience_id " << it->second << LL_ENDL;
+ return it->second;
+}
+
+//=========================================================================
+void LLExperienceCache::processExperience(const LLUUID& public_key, const LLSD& experience)
+{
+ sCache[public_key]=experience;
+ LLSD & row = sCache[public_key];
+
+ if(row.has(EXPIRES))
{
- return sCache;
+ row[EXPIRES] = row[EXPIRES].asReal() + LLFrameTimer::getTotalSeconds();
}
- void setMaximumLookups( int maximumLookups)
+ if(row.has(EXPERIENCE_ID))
{
- sMaximumLookups = maximumLookups;
+ sPendingQueue.erase(row[EXPERIENCE_ID].asUUID());
}
- void bootstrap(const LLSD& legacyKeys, int initialExpiration)
+ //signal
+ signal_map_t::iterator sig_it = sSignalMap.find(public_key);
+ if (sig_it != sSignalMap.end())
{
- mapKeys(legacyKeys);
- LLSD::array_const_iterator it = legacyKeys.beginArray();
- for(/**/; it != legacyKeys.endArray(); ++it)
- {
- LLSD experience = *it;
- if(experience.has(EXPERIENCE_ID))
- {
- if(!experience.has(EXPIRES))
- {
- experience[EXPIRES] = initialExpiration;
- }
- processExperience(experience[EXPERIENCE_ID].asUUID(), experience);
- }
- else
- {
- LL_WARNS("ExperienceCache")
- << "Skipping bootstrap entry which is missing " << EXPERIENCE_ID
- << LL_ENDL;
- }
- }
+ callback_signal_t* signal = sig_it->second;
+ (*signal)(experience);
+
+ sSignalMap.erase(public_key);
+
+ delete signal;
}
+}
+const LLExperienceCache::cache_t& LLExperienceCache::getCached()
+{
+ return sCache;
+}
+
+void LLExperienceCache::setMaximumLookups(int maximumLookups)
+{
+ sMaximumLookups = maximumLookups;
+}
- bool expirationFromCacheControl(LLSD headers, F64 *expires)
+bool LLExperienceCache::expirationFromCacheControl(LLSD headers, F64 *expires)
+{
+ // Allow the header to override the default
+ LLSD cache_control_header = headers["cache-control"];
+ if (cache_control_header.isDefined())
{
- // Allow the header to override the default
- LLSD cache_control_header = headers["cache-control"];
- if (cache_control_header.isDefined())
+ S32 max_age = 0;
+ std::string cache_control = cache_control_header.asString();
+ if (max_age_from_cache_control(cache_control, &max_age))
{
- S32 max_age = 0;
- std::string cache_control = cache_control_header.asString();
- if (max_age_from_cache_control(cache_control, &max_age))
- {
- LL_WARNS("ExperienceCache")
- << "got EXPIRES from headers, max_age " << max_age
- << LL_ENDL;
- F64 now = LLFrameTimer::getTotalSeconds();
- *expires = now + (F64)max_age;
- return true;
- }
+ LL_WARNS("ExperienceCache")
+ << "got EXPIRES from headers, max_age " << max_age
+ << LL_ENDL;
+ F64 now = LLFrameTimer::getTotalSeconds();
+ *expires = now + (F64)max_age;
+ return true;
}
- return false;
}
+ return false;
+}
- static const std::string MAX_AGE("max-age");
- static const boost::char_separator EQUALS_SEPARATOR("=");
- static const boost::char_separator COMMA_SEPARATOR(",");
+static const std::string MAX_AGE("max-age");
+static const boost::char_separator EQUALS_SEPARATOR("=");
+static const boost::char_separator COMMA_SEPARATOR(",");
+
+bool max_age_from_cache_control(const std::string& cache_control, S32 *max_age)
+{
+ // Split the string on "," to get a list of directives
+ typedef boost::tokenizer > tokenizer;
+ tokenizer directives(cache_control, COMMA_SEPARATOR);
- bool max_age_from_cache_control(const std::string& cache_control, S32 *max_age)
+ tokenizer::iterator token_it = directives.begin();
+ for ( ; token_it != directives.end(); ++token_it)
{
- // Split the string on "," to get a list of directives
- typedef boost::tokenizer > tokenizer;
- tokenizer directives(cache_control, COMMA_SEPARATOR);
+ // Tokens may have leading or trailing whitespace
+ std::string token = *token_it;
+ LLStringUtil::trim(token);
- tokenizer::iterator token_it = directives.begin();
- for ( ; token_it != directives.end(); ++token_it)
+ if (token.compare(0, MAX_AGE.size(), MAX_AGE) == 0)
{
- // Tokens may have leading or trailing whitespace
- std::string token = *token_it;
- LLStringUtil::trim(token);
-
- if (token.compare(0, MAX_AGE.size(), MAX_AGE) == 0)
+ // ...this token starts with max-age, so let's chop it up by "="
+ tokenizer subtokens(token, EQUALS_SEPARATOR);
+ tokenizer::iterator subtoken_it = subtokens.begin();
+
+ // Must have a token
+ if (subtoken_it == subtokens.end()) return false;
+ std::string subtoken = *subtoken_it;
+
+ // Must exactly equal "max-age"
+ LLStringUtil::trim(subtoken);
+ if (subtoken != MAX_AGE) return false;
+
+ // Must have another token
+ ++subtoken_it;
+ if (subtoken_it == subtokens.end()) return false;
+ subtoken = *subtoken_it;
+
+ // Must be a valid integer
+ // *NOTE: atoi() returns 0 for invalid values, so we have to
+ // check the string first.
+ // *TODO: Do servers ever send "0000" for zero? We don't handle it
+ LLStringUtil::trim(subtoken);
+ if (subtoken == "0")
{
- // ...this token starts with max-age, so let's chop it up by "="
- tokenizer subtokens(token, EQUALS_SEPARATOR);
- tokenizer::iterator subtoken_it = subtokens.begin();
-
- // Must have a token
- if (subtoken_it == subtokens.end()) return false;
- std::string subtoken = *subtoken_it;
-
- // Must exactly equal "max-age"
- LLStringUtil::trim(subtoken);
- if (subtoken != MAX_AGE) return false;
-
- // Must have another token
- ++subtoken_it;
- if (subtoken_it == subtokens.end()) return false;
- subtoken = *subtoken_it;
-
- // Must be a valid integer
- // *NOTE: atoi() returns 0 for invalid values, so we have to
- // check the string first.
- // *TODO: Do servers ever send "0000" for zero? We don't handle it
- LLStringUtil::trim(subtoken);
- if (subtoken == "0")
- {
- *max_age = 0;
- return true;
- }
- S32 val = atoi( subtoken.c_str() );
- if (val > 0 && val < S32_MAX)
- {
- *max_age = val;
- return true;
- }
- return false;
+ *max_age = 0;
+ return true;
}
+ S32 val = atoi( subtoken.c_str() );
+ if (val > 0 && val < S32_MAX)
+ {
+ *max_age = val;
+ return true;
+ }
+ return false;
}
- return false;
}
+ return false;
+}
- void importFile(std::istream& istr)
+class LLExperienceResponder : public LLHTTPClient::Responder
+{
+public:
+ LLExperienceResponder(const ask_queue_t& keys)
+ :mKeys(keys)
{
- LLSD data;
- S32 parse_count = LLSDSerialize::fromXMLDocument(data, istr);
- if(parse_count < 1) return;
-
- LLSD experiences = data["experiences"];
- LLUUID public_key;
- LLSD::map_const_iterator it = experiences.beginMap();
- for(; it != experiences.endMap() ; ++it)
- {
- public_key.set(it->first);
- sCache[public_key]=it->second;
- }
-
- LL_DEBUGS("ExperienceCache") << "importFile() loaded " << sCache.size() << LL_ENDL;
}
- void exportFile(std::ostream& ostr)
+ /*virtual*/ void httpCompleted()
{
- LLSD experiences;
-
- cache_t::const_iterator it =sCache.begin();
- for( ; it != sCache.end() ; ++it)
+ LLSD experiences = getContent()["experience_keys"];
+ LLSD::array_const_iterator it = experiences.beginArray();
+ for( /**/ ; it != experiences.endArray(); ++it)
{
- if(!it->second.has(EXPERIENCE_ID) || it->second[EXPERIENCE_ID].asUUID().isNull() ||
- it->second.has("DoesNotExist") || (it->second.has(PROPERTIES) && it->second[PROPERTIES].asInteger() & PROPERTY_INVALID))
- continue;
+ const LLSD& row = *it;
+ LLUUID public_key = row[EXPERIENCE_ID].asUUID();
- experiences[it->first.asString()] = it->second;
- }
- LLSD data;
- data["experiences"] = experiences;
+ LL_DEBUGS("ExperienceCache") << "Received result for " << public_key
+ << " display '" << row[LLExperienceCache::NAME].asString() << "'" << LL_ENDL ;
- LLSDSerialize::toPrettyXML(data, ostr);
- }
+ processExperience(public_key, row);
+ }
- class LLExperienceResponder : public LLHTTPClient::Responder
- {
- public:
- LLExperienceResponder(const ask_queue_t& keys)
- :mKeys(keys)
+ LLSD error_ids = getContent()["error_ids"];
+ LLSD::array_const_iterator errIt = error_ids.beginArray();
+ for( /**/ ; errIt != error_ids.endArray() ; ++errIt )
{
-
+ LLUUID id = errIt->asUUID();
+ LLSD exp;
+ exp[EXPIRES]=DEFAULT_EXPIRATION;
+ exp[EXPERIENCE_ID] = id;
+ exp[PROPERTIES]=PROPERTY_INVALID;
+ exp[MISSING]=true;
+ exp[QUOTA] = DEFAULT_QUOTA;
+
+ processExperience(id, exp);
+ LL_WARNS("ExperienceCache") << "LLExperienceResponder::result() error result for " << id << LL_ENDL ;
}
- /*virtual*/ void httpCompleted()
+ LL_DEBUGS("ExperienceCache") << sCache.size() << " cached experiences" << LL_ENDL;
+ }
+
+ /*virtual*/ void httpFailure()
+ {
+ LL_WARNS("ExperienceCache") << "Request failed "<first);
+ //leave the properties alone if we already have a cache entry for this xp
+ if(exp.isUndefined())
+ {
+ exp[PROPERTIES]=PROPERTY_INVALID;
+ }
+ exp[EXPIRES]=retry_timestamp;
+ exp[EXPERIENCE_ID] = it->first;
+ exp["key_type"] = it->second;
+ exp["uuid"] = it->first;
+ exp["error"] = (LLSD::Integer)getStatus();
+ exp[QUOTA] = DEFAULT_QUOTA;
+
+ LLExperienceCache::processExperience(it->first, exp);
+ }
- LL_DEBUGS("ExperienceCache") << "Received result for " << public_key
- << " display '" << row[LLExperienceCache::NAME].asString() << "'" << LL_ENDL ;
+ }
- processExperience(public_key, row);
- }
+ // Return time to retry a request that generated an error, based on
+ // error type and headers. Return value is seconds-since-epoch.
+ F64 errorRetryTimestamp(S32 status)
+ {
- LLSD error_ids = getContent()["error_ids"];
- LLSD::array_const_iterator errIt = error_ids.beginArray();
- for( /**/ ; errIt != error_ids.endArray() ; ++errIt )
+ // Retry-After takes priority
+ LLSD retry_after = getResponseHeaders()["retry-after"];
+ if (retry_after.isDefined())
+ {
+ // We only support the delta-seconds type
+ S32 delta_seconds = retry_after.asInteger();
+ if (delta_seconds > 0)
{
- LLUUID id = errIt->asUUID();
- LLSD exp;
- exp[EXPIRES]=DEFAULT_EXPIRATION;
- exp[EXPERIENCE_ID] = id;
- exp[PROPERTIES]=PROPERTY_INVALID;
- exp[MISSING]=true;
- exp[QUOTA] = DEFAULT_QUOTA;
-
- processExperience(id, exp);
- LL_WARNS("ExperienceCache") << "LLExperienceResponder::result() error result for " << id << LL_ENDL ;
+ // ...valid delta-seconds
+ return F64(delta_seconds);
}
-
- LL_DEBUGS("ExperienceCache") << sCache.size() << " cached experiences" << LL_ENDL;
}
- /*virtual*/ void httpFailure()
+ // If no Retry-After, look for Cache-Control max-age
+ F64 expires = 0.0;
+ if (LLExperienceCache::expirationFromCacheControl(getResponseHeaders(), &expires))
{
- LL_WARNS("ExperienceCache") << "Request failed "<first);
- //leave the properties alone if we already have a cache entry for this xp
- if(exp.isUndefined())
- {
- exp[PROPERTIES]=PROPERTY_INVALID;
- }
- exp[EXPIRES]=retry_timestamp;
- exp[EXPERIENCE_ID] = it->first;
- exp["key_type"] = it->second;
- exp["uuid"] = it->first;
- exp["error"] = (LLSD::Integer)getStatus();
- exp[QUOTA] = DEFAULT_QUOTA;
-
- LLExperienceCache::processExperience(it->first, exp);
- }
-
+ return expires;
}
- // Return time to retry a request that generated an error, based on
- // error type and headers. Return value is seconds-since-epoch.
- F64 errorRetryTimestamp(S32 status)
+ // No information in header, make a guess
+ if (status == 503)
{
+ // ...service unavailable, retry soon
+ const F64 SERVICE_UNAVAILABLE_DELAY = 600.0; // 10 min
+ return SERVICE_UNAVAILABLE_DELAY;
+ }
+ else if (status == 499)
+ {
+ // ...we were probably too busy, retry quickly
+ const F64 BUSY_DELAY = 10.0; // 10 seconds
+ return BUSY_DELAY;
- // Retry-After takes priority
- LLSD retry_after = getResponseHeaders()["retry-after"];
- if (retry_after.isDefined())
- {
- // We only support the delta-seconds type
- S32 delta_seconds = retry_after.asInteger();
- if (delta_seconds > 0)
- {
- // ...valid delta-seconds
- return F64(delta_seconds);
- }
- }
-
- // If no Retry-After, look for Cache-Control max-age
- F64 expires = 0.0;
- if (LLExperienceCache::expirationFromCacheControl(getResponseHeaders(), &expires))
- {
- return expires;
- }
-
- // No information in header, make a guess
- if (status == 503)
- {
- // ...service unavailable, retry soon
- const F64 SERVICE_UNAVAILABLE_DELAY = 600.0; // 10 min
- return SERVICE_UNAVAILABLE_DELAY;
- }
- else if (status == 499)
- {
- // ...we were probably too busy, retry quickly
- const F64 BUSY_DELAY = 10.0; // 10 seconds
- return BUSY_DELAY;
-
- }
- else
- {
- // ...other unexpected error
- const F64 DEFAULT_DELAY = 3600.0; // 1 hour
- return DEFAULT_DELAY;
- }
}
+ else
+ {
+ // ...other unexpected error
+ const F64 DEFAULT_DELAY = 3600.0; // 1 hour
+ return DEFAULT_DELAY;
+ }
+ }
- private:
- ask_queue_t mKeys;
- };
+private:
+ ask_queue_t mKeys;
+};
- void requestExperiences()
- {
- if(sAskQueue.empty() || sLookupURL.empty())
- return;
- F64 now = LLFrameTimer::getTotalSeconds();
+void LLExperienceCache::requestExperiences()
+{
+ if(sAskQueue.empty() || sLookupURL.empty())
+ return;
- const U32 EXP_URL_SEND_THRESHOLD = 3000;
- const U32 PAGE_SIZE = EXP_URL_SEND_THRESHOLD/UUID_STR_LENGTH;
+ F64 now = LLFrameTimer::getTotalSeconds();
- std::ostringstream ostr;
+ const U32 EXP_URL_SEND_THRESHOLD = 3000;
+ const U32 PAGE_SIZE = EXP_URL_SEND_THRESHOLD/UUID_STR_LENGTH;
- ask_queue_t keys;
+ std::ostringstream ostr;
- ostr << sLookupURL << "?page_size=" << PAGE_SIZE;
+ ask_queue_t keys;
+ ostr << sLookupURL << "?page_size=" << PAGE_SIZE;
- int request_count = 0;
- while(!sAskQueue.empty() && request_count < sMaximumLookups)
- {
- ask_queue_t::iterator it = sAskQueue.begin();
- const LLUUID& key = it->first;
- const std::string& key_type = it->second;
- ostr << '&' << key_type << '=' << key.asString() ;
+ int request_count = 0;
+ while(!sAskQueue.empty() && request_count < sMaximumLookups)
+ {
+ ask_queue_t::iterator it = sAskQueue.begin();
+ const LLUUID& key = it->first;
+ const std::string& key_type = it->second;
+
+ ostr << '&' << key_type << '=' << key.asString() ;
- keys[key]=key_type;
- request_count++;
+ keys[key]=key_type;
+ request_count++;
- sPendingQueue[key] = now;
+ sPendingQueue[key] = now;
- if(ostr.tellp() > EXP_URL_SEND_THRESHOLD)
- {
- LL_DEBUGS("ExperienceCache") << "requestExperiences() query: " << ostr.str() << LL_ENDL;
- LLHTTPClient::get(ostr.str(), new LLExperienceResponder(keys));
- ostr.clear();
- ostr.str(sLookupURL);
- ostr << "?page_size=" << PAGE_SIZE;
- keys.clear();
- }
- sAskQueue.erase(it);
- }
-
- if(ostr.tellp() > sLookupURL.size())
+ if(ostr.tellp() > EXP_URL_SEND_THRESHOLD)
{
- LL_DEBUGS("ExperienceCache") << "requestExperiences() query 2: " << ostr.str() << LL_ENDL;
+ LL_DEBUGS("ExperienceCache") << "requestExperiences() query: " << ostr.str() << LL_ENDL;
LLHTTPClient::get(ostr.str(), new LLExperienceResponder(keys));
+ ostr.clear();
+ ostr.str(sLookupURL);
+ ostr << "?page_size=" << PAGE_SIZE;
+ keys.clear();
}
+ sAskQueue.erase(it);
}
- bool isRequestPending(const LLUUID& public_key)
+ if(ostr.tellp() > sLookupURL.size())
{
- bool isPending = false;
- const F64 PENDING_TIMEOUT_SECS = 5.0 * 60.0;
+ LL_DEBUGS("ExperienceCache") << "requestExperiences() query 2: " << ostr.str() << LL_ENDL;
+ LLHTTPClient::get(ostr.str(), new LLExperienceResponder(keys));
+ }
+}
- pending_queue_t::const_iterator it = sPendingQueue.find(public_key);
- if(it != sPendingQueue.end())
- {
- F64 expire_time = LLFrameTimer::getTotalSeconds() - PENDING_TIMEOUT_SECS;
- isPending = (it->second > expire_time);
- }
+bool LLExperienceCache::isRequestPending(const LLUUID& public_key)
+{
+ bool isPending = false;
+ const F64 PENDING_TIMEOUT_SECS = 5.0 * 60.0;
+
+ pending_queue_t::const_iterator it = sPendingQueue.find(public_key);
- return isPending;
+ if(it != sPendingQueue.end())
+ {
+ F64 expire_time = LLFrameTimer::getTotalSeconds() - PENDING_TIMEOUT_SECS;
+ isPending = (it->second > expire_time);
}
+ return isPending;
+}
+
- void setLookupURL( const std::string& lookup_url )
+void LLExperienceCache::setLookupURL(const std::string& lookup_url)
+{
+ sLookupURL = lookup_url;
+ if(!sLookupURL.empty())
{
- sLookupURL = lookup_url;
- if(!sLookupURL.empty())
- {
- sLookupURL += "id/";
- }
+ sLookupURL += "id/";
}
+}
+
+bool LLExperienceCache::hasLookupURL()
+{
+ return !sLookupURL.empty();
+}
- bool hasLookupURL()
+void LLExperienceCache::idle()
+{
+
+ const F32 SECS_BETWEEN_REQUESTS = 0.1f;
+ if (!sRequestTimer.checkExpirationAndReset(SECS_BETWEEN_REQUESTS))
{
- return !sLookupURL.empty();
+ return;
}
- void idle()
+ // Must be large relative to above
+ const F32 ERASE_EXPIRED_TIMEOUT = 60.f; // seconds
+ if (sEraseExpiredTimer.checkExpirationAndReset(ERASE_EXPIRED_TIMEOUT))
{
-
- const F32 SECS_BETWEEN_REQUESTS = 0.1f;
- if (!sRequestTimer.checkExpirationAndReset(SECS_BETWEEN_REQUESTS))
- {
- return;
- }
-
- // Must be large relative to above
- const F32 ERASE_EXPIRED_TIMEOUT = 60.f; // seconds
- if (sEraseExpiredTimer.checkExpirationAndReset(ERASE_EXPIRED_TIMEOUT))
- {
- eraseExpired();
- }
+ eraseExpired();
+ }
- if(!sAskQueue.empty())
- {
- requestExperiences();
- }
+ if(!sAskQueue.empty())
+ {
+ requestExperiences();
}
+}
- void erase( const LLUUID& key )
- {
- cache_t::iterator it = sCache.find(key);
+void LLExperienceCache::erase(const LLUUID& key)
+{
+ cache_t::iterator it = sCache.find(key);
- if(it != sCache.end())
- {
- sCache.erase(it);
- }
+ if(it != sCache.end())
+ {
+ sCache.erase(it);
}
+}
- void eraseExpired()
+void LLExperienceCache::eraseExpired()
+{
+ F64 now = LLFrameTimer::getTotalSeconds();
+ cache_t::iterator it = sCache.begin();
+ while (it != sCache.end())
{
- F64 now = LLFrameTimer::getTotalSeconds();
- cache_t::iterator it = sCache.begin();
- while (it != sCache.end())
- {
- cache_t::iterator cur = it;
- LLSD& exp = cur->second;
- ++it;
+ cache_t::iterator cur = it;
+ LLSD& exp = cur->second;
+ ++it;
- if(exp.has(EXPIRES) && exp[EXPIRES].asReal() < now)
+ if(exp.has(EXPIRES) && exp[EXPIRES].asReal() < now)
+ {
+ if(!exp.has(EXPERIENCE_ID))
{
- if(!exp.has(EXPERIENCE_ID))
+ LL_WARNS("ExperienceCache") << "Removing experience with no id " << LL_ENDL ;
+ sCache.erase(cur);
+ }
+ else
+ {
+ LLUUID id = exp[EXPERIENCE_ID].asUUID();
+ LLUUID private_key = exp.has(LLExperienceCache::PRIVATE_KEY) ? exp[LLExperienceCache::PRIVATE_KEY].asUUID():LLUUID::null;
+ if(private_key.notNull() || !exp.has("DoesNotExist"))
{
- LL_WARNS("ExperienceCache") << "Removing experience with no id " << LL_ENDL ;
- sCache.erase(cur);
- }
- else
- {
- LLUUID id = exp[EXPERIENCE_ID].asUUID();
- LLUUID private_key = exp.has(LLExperienceCache::PRIVATE_KEY) ? exp[LLExperienceCache::PRIVATE_KEY].asUUID():LLUUID::null;
- if(private_key.notNull() || !exp.has("DoesNotExist"))
- {
- fetch(id, true);
- }
- else
- {
- LL_WARNS("ExperienceCache") << "Removing invalid experience " << id << LL_ENDL ;
- sCache.erase(cur);
- }
+ fetch(id, true);
+ }
+ else
+ {
+ LL_WARNS("ExperienceCache") << "Removing invalid experience " << id << LL_ENDL ;
+ sCache.erase(cur);
}
}
}
}
+}
- bool fetch( const LLUUID& key, bool refresh/* = true*/ )
+bool LLExperienceCache::fetch(const LLUUID& key, bool refresh/* = true*/)
+{
+ if(!key.isNull() && !isRequestPending(key) && (refresh || sCache.find(key)==sCache.end()))
{
- if(!key.isNull() && !isRequestPending(key) && (refresh || sCache.find(key)==sCache.end()))
- {
- LL_DEBUGS("ExperienceCache") << " queue request for " << EXPERIENCE_ID << " " << key << LL_ENDL ;
- sAskQueue[key]=EXPERIENCE_ID;
+ LL_DEBUGS("ExperienceCache") << " queue request for " << EXPERIENCE_ID << " " << key << LL_ENDL ;
+ sAskQueue[key]=EXPERIENCE_ID;
- return true;
- }
- return false;
+ return true;
}
+ return false;
+}
- void insert(const LLSD& experience_data )
+void LLExperienceCache::insert(const LLSD& experience_data)
+{
+ if(experience_data.has(EXPERIENCE_ID))
{
- if(experience_data.has(EXPERIENCE_ID))
- {
- processExperience(experience_data[EXPERIENCE_ID].asUUID(), experience_data);
- }
- else
- {
- LL_WARNS("ExperienceCache") << ": Ignoring cache insert of experience which is missing " << EXPERIENCE_ID << LL_ENDL;
- }
+ processExperience(experience_data[EXPERIENCE_ID].asUUID(), experience_data);
}
- static LLSD empty;
- const LLSD& get(const LLUUID& key)
+ else
{
- if(key.isNull()) return empty;
- cache_t::const_iterator it = sCache.find(key);
-
- if (it != sCache.end())
- {
- return it->second;
- }
-
- fetch(key);
-
- return empty;
+ LL_WARNS("ExperienceCache") << ": Ignoring cache insert of experience which is missing " << EXPERIENCE_ID << LL_ENDL;
}
- void get( const LLUUID& key, callback_slot_t slot )
- {
- if(key.isNull()) return;
-
- cache_t::const_iterator it = sCache.find(key);
- if (it != sCache.end())
- {
- // ...name already exists in cache, fire callback now
- callback_signal_t signal;
- signal.connect(slot);
-
- signal(it->second);
- return;
- }
+}
- fetch(key);
+static LLSD empty;
+const LLSD& LLExperienceCache::get(const LLUUID& key)
+{
+ if(key.isNull()) return empty;
+ cache_t::const_iterator it = sCache.find(key);
- // always store additional callback, even if request is pending
- signal_map_t::iterator sig_it = sSignalMap.find(key);
- if (sig_it == sSignalMap.end())
- {
- // ...new callback for this id
- callback_signal_t* signal = new callback_signal_t();
- signal->connect(slot);
- sSignalMap[key] = signal;
- }
- else
- {
- // ...existing callback, bind additional slot
- callback_signal_t* signal = sig_it->second;
- signal->connect(slot);
- }
+ if (it != sCache.end())
+ {
+ return it->second;
}
-}
-
+ fetch(key);
-void LLExperienceCache::mapKeys( const LLSD& legacyKeys )
+ return empty;
+}
+void LLExperienceCache::get(const LLUUID& key, callback_slot_t slot)
{
- LLSD::array_const_iterator exp = legacyKeys.beginArray();
- for(/**/ ; exp != legacyKeys.endArray() ; ++exp)
+ if(key.isNull()) return;
+
+ cache_t::const_iterator it = sCache.find(key);
+ if (it != sCache.end())
{
- if(exp->has(LLExperienceCache::EXPERIENCE_ID) && exp->has(LLExperienceCache::PRIVATE_KEY))
- {
- privateToPublicKeyMap[(*exp)[LLExperienceCache::PRIVATE_KEY].asUUID()]=(*exp)[LLExperienceCache::EXPERIENCE_ID].asUUID();
- }
+ // ...name already exists in cache, fire callback now
+ callback_signal_t signal;
+ signal.connect(slot);
+
+ signal(it->second);
+ return;
}
-}
+ fetch(key);
-LLUUID LLExperienceCache::getExperienceId(const LLUUID& private_key, bool null_if_not_found)
-{
- if (private_key.isNull())
- return LLUUID::null;
-
- KeyMap::const_iterator it=privateToPublicKeyMap.find(private_key);
- if(it == privateToPublicKeyMap.end())
+ // always store additional callback, even if request is pending
+ signal_map_t::iterator sig_it = sSignalMap.find(key);
+ if (sig_it == sSignalMap.end())
{
- if(null_if_not_found)
- {
- return LLUUID::null;
- }
- return private_key;
+ // ...new callback for this id
+ callback_signal_t* signal = new callback_signal_t();
+ signal->connect(slot);
+ sSignalMap[key] = signal;
+ }
+ else
+ {
+ // ...existing callback, bind additional slot
+ callback_signal_t* signal = sig_it->second;
+ signal->connect(slot);
}
- LL_WARNS("LLExperience") << "converted private key " << private_key << " to experience_id " << it->second << LL_ENDL;
- return it->second;
}
+
+
diff --git a/indra/llmessage/llexperiencecache.h b/indra/llmessage/llexperiencecache.h
index e669ee888e..8a55719443 100644
--- a/indra/llmessage/llexperiencecache.h
+++ b/indra/llmessage/llexperiencecache.h
@@ -30,15 +30,47 @@
#define LL_LLEXPERIENCECACHE_H
#include "linden_common.h"
+#include "llsingleton.h"
+#include "llsd.h"
#include
+#include
class LLSD;
class LLUUID;
-
-namespace LLExperienceCache
+class LLExperienceCache: public LLSingleton < LLExperienceCache >
{
+ friend class LLSingleton < LLExperienceCache > ;
+
+public:
+ typedef boost::function Callback_t;
+
+ void erase(const LLUUID& key);
+ bool fetch(const LLUUID& key, bool refresh = false);
+ void insert(const LLSD& experience_data);
+ const LLSD& get(const LLUUID& key);
+
+ // If name information is in cache, callback will be called immediately.
+ void get(const LLUUID& key, Callback_t slot);
+
+private:
+ // Callback types for get()
+// typedef boost::signals2::signal < void(const LLSD &) > callback_signal_t;
+ typedef boost::signals2::signal < Callback_t > callback_signal_t;
+ typedef std::map cache_t;
+
+//--------------------------------------------
+ LLExperienceCache();
+ virtual ~LLExperienceCache();
+
+ void exportFile(std::ostream& ostr) const;
+ void importFile(std::istream& istr);
+
+//--------------------------------------------
+ void processExperience(const LLUUID& public_key, const LLSD& experience);
+
+
const std::string PRIVATE_KEY = "private_id";
const std::string MISSING = "DoesNotExist";
@@ -61,19 +93,12 @@ namespace LLExperienceCache
const int PROPERTY_GRID = 1 << 4;
const int PROPERTY_PRIVATE = 1 << 5;
const int PROPERTY_DISABLED = 1 << 6;
- const int PROPERTY_SUSPENDED = 1 << 7;
-
+ const int PROPERTY_SUSPENDED = 1 << 7;
// default values
const static F64 DEFAULT_EXPIRATION = 600.0;
const static S32 DEFAULT_QUOTA = 128; // this is megabytes
- // Callback types for get() below
- typedef boost::signals2::signal
- callback_signal_t;
- typedef callback_signal_t::slot_type callback_slot_t;
- typedef std::map cache_t;
-
void setLookupURL(const std::string& lookup_url);
bool hasLookupURL();
@@ -81,24 +106,26 @@ namespace LLExperienceCache
void setMaximumLookups(int maximumLookups);
void idle();
- void exportFile(std::ostream& ostr);
- void importFile(std::istream& istr);
- void initClass();
void bootstrap(const LLSD& legacyKeys, int initialExpiration);
- void erase(const LLUUID& key);
- bool fetch(const LLUUID& key, bool refresh=false);
- void insert(const LLSD& experience_data);
- const LLSD& get(const LLUUID& key);
-
- // If name information is in cache, callback will be called immediately.
- void get(const LLUUID& key, callback_slot_t slot);
const cache_t& getCached();
// maps an experience private key to the experience id
LLUUID getExperienceId(const LLUUID& private_key, bool null_if_not_found=false);
+ //=====================================================================
+ inline friend std::ostream &operator << (std::ostream &os, const LLExperienceCache &cache)
+ {
+ cache.exportFile(os);
+ return os;
+ }
+
+ inline friend std::istream &operator >> (std::istream &is, LLExperienceCache &cache)
+ {
+ cache.importFile(is);
+ return is;
+ }
};
#endif // LL_LLEXPERIENCECACHE_H
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index c74890a4e9..46f75c4f57 100755
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -2820,9 +2820,10 @@ void LLStartUp::initNameCache()
void LLStartUp::initExperiences()
-{
+{
+ // just a get instance here. Should trigger loading the cache.
+ LLExperienceCache::getInstance();
LLAppViewer::instance()->loadExperienceCache();
- LLExperienceCache::initClass();
LLExperienceLog::instance().initialize();
}
--
cgit v1.3
From 96e343b49b0b5a0951ffab0beb2e1d09c37bbdc5 Mon Sep 17 00:00:00 2001
From: Rider Linden
Date: Tue, 1 Sep 2015 16:13:52 -0700
Subject: MAINT-5575: Convert the Experience cache into a coro based singleton.
--HG--
branch : MAINT-5575
---
indra/llmessage/CMakeLists.txt | 2 +
indra/llmessage/llcoproceduremanager.cpp | 414 +++++++++++++++
indra/llmessage/llcoproceduremanager.h | 98 ++++
indra/llmessage/llexperiencecache.cpp | 569 ++++++++++-----------
indra/llmessage/llexperiencecache.h | 99 ++--
indra/llui/CMakeLists.txt | 2 +
indra/llui/llurlentry.cpp | 4 +-
indra/newview/CMakeLists.txt | 2 -
indra/newview/llagent.cpp | 9 +
indra/newview/llagent.h | 3 +
indra/newview/llappviewer.cpp | 57 +--
indra/newview/llappviewer.h | 4 -
indra/newview/llcoproceduremanager.cpp | 406 ---------------
indra/newview/llcoproceduremanager.h | 87 ----
indra/newview/llexperienceassociationresponder.cpp | 2 +-
indra/newview/llfloaterexperienceprofile.cpp | 10 +-
indra/newview/llfloaterreporter.cpp | 2 +-
indra/newview/llpanelexperiencelisteditor.cpp | 2 +-
indra/newview/llpanelexperiencelog.cpp | 4 +-
indra/newview/llpanelexperiencepicker.cpp | 2 +-
indra/newview/llpreviewscript.cpp | 6 +-
indra/newview/llstartup.cpp | 7 +-
indra/newview/llviewermessage.cpp | 2 +-
23 files changed, 897 insertions(+), 896 deletions(-)
create mode 100644 indra/llmessage/llcoproceduremanager.cpp
create mode 100644 indra/llmessage/llcoproceduremanager.h
delete mode 100644 indra/newview/llcoproceduremanager.cpp
delete mode 100644 indra/newview/llcoproceduremanager.h
(limited to 'indra/newview/llstartup.cpp')
diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt
index 9739f7c607..12fc1bbcfc 100755
--- a/indra/llmessage/CMakeLists.txt
+++ b/indra/llmessage/CMakeLists.txt
@@ -40,6 +40,7 @@ set(llmessage_SOURCE_FILES
llchainio.cpp
llcircuit.cpp
llclassifiedflags.cpp
+ llcoproceduremanager.cpp
llcorehttputil.cpp
llcurl.cpp
lldatapacker.cpp
@@ -128,6 +129,7 @@ set(llmessage_HEADER_FILES
llcipher.h
llcircuit.h
llclassifiedflags.h
+ llcoproceduremanager.h
llcorehttputil.h
llcurl.h
lldatapacker.h
diff --git a/indra/llmessage/llcoproceduremanager.cpp b/indra/llmessage/llcoproceduremanager.cpp
new file mode 100644
index 0000000000..062f2e6e42
--- /dev/null
+++ b/indra/llmessage/llcoproceduremanager.cpp
@@ -0,0 +1,414 @@
+/**
+* @file LLCoprocedurePool.cpp
+* @author Rider Linden
+* @brief Singleton class for managing asset uploads to the sim.
+*
+* $LicenseInfo:firstyear=2015&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2015, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+* $/LicenseInfo$
+*/
+
+#include "linden_common.h"
+#include "llcoproceduremanager.h"
+
+//=========================================================================
+// Map of pool sizes for known pools
+static std::map DefaultPoolSizes;
+
+// *TODO$: When C++11 this can be initialized here as follows:
+// = {{"AIS", 25}, {"Upload", 1}}
+
+#define DEFAULT_POOL_SIZE 5
+
+//=========================================================================
+class LLCoprocedurePool: private boost::noncopyable
+{
+public:
+ typedef LLCoprocedureManager::CoProcedure_t CoProcedure_t;
+
+ LLCoprocedurePool(const std::string &name, size_t size);
+ virtual ~LLCoprocedurePool();
+
+ /// Places the coprocedure on the queue for processing.
+ ///
+ /// @param name Is used for debugging and should identify this coroutine.
+ /// @param proc Is a bound function to be executed
+ ///
+ /// @return This method returns a UUID that can be used later to cancel execution.
+ LLUUID enqueueCoprocedure(const std::string &name, CoProcedure_t proc);
+
+ /// Cancel a coprocedure. If the coprocedure is already being actively executed
+ /// this method calls cancelYieldingOperation() on the associated HttpAdapter
+ /// If it has not yet been dequeued it is simply removed from the queue.
+ bool cancelCoprocedure(const LLUUID &id);
+
+ /// Requests a shutdown of the upload manager. Passing 'true' will perform
+ /// an immediate kill on the upload coroutine.
+ void shutdown(bool hardShutdown = false);
+
+ /// Returns the number of coprocedures in the queue awaiting processing.
+ ///
+ inline size_t countPending() const
+ {
+ return mPendingCoprocs.size();
+ }
+
+ /// Returns the number of coprocedures actively being processed.
+ ///
+ inline size_t countActive() const
+ {
+ return mActiveCoprocs.size();
+ }
+
+ /// Returns the total number of coprocedures either queued or in active processing.
+ ///
+ inline size_t count() const
+ {
+ return countPending() + countActive();
+ }
+
+private:
+ struct QueuedCoproc
+ {
+ typedef boost::shared_ptr ptr_t;
+
+ QueuedCoproc(const std::string &name, const LLUUID &id, CoProcedure_t proc) :
+ mName(name),
+ mId(id),
+ mProc(proc)
+ {}
+
+ std::string mName;
+ LLUUID mId;
+ CoProcedure_t mProc;
+ };
+
+ // we use a deque here rather than std::queue since we want to be able to
+ // iterate through the queue and potentially erase an entry from the middle.
+ typedef std::deque CoprocQueue_t;
+ typedef std::map ActiveCoproc_t;
+
+ std::string mPoolName;
+ size_t mPoolSize;
+ CoprocQueue_t mPendingCoprocs;
+ ActiveCoproc_t mActiveCoprocs;
+ bool mShutdown;
+ LLEventStream mWakeupTrigger;
+
+ typedef std::map CoroAdapterMap_t;
+ LLCore::HttpRequest::policy_t mHTTPPolicy;
+
+ CoroAdapterMap_t mCoroMapping;
+
+ void coprocedureInvokerCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter);
+
+};
+
+//=========================================================================
+LLCoprocedureManager::LLCoprocedureManager()
+{
+ DefaultPoolSizes.insert(std::map::value_type("Upload", 1));
+ DefaultPoolSizes.insert(std::map::value_type("AIS", 25));
+}
+
+LLCoprocedureManager::~LLCoprocedureManager()
+{
+
+}
+
+LLCoprocedureManager::poolPtr_t LLCoprocedureManager::initializePool(const std::string &poolName)
+{
+ // Attempt to look up a pool size in the configuration. If found use that
+ std::string keyName = "PoolSize" + poolName;
+ int size = 0;
+
+ if (mPropertyQueryFn && !mPropertyQueryFn.empty())
+ {
+ size = mPropertyQueryFn(keyName);
+ }
+
+ if (size == 0)
+ { // if not found grab the know default... if there is no known
+ // default use a reasonable number like 5.
+ std::map::iterator it = DefaultPoolSizes.find(poolName);
+ if (it == DefaultPoolSizes.end())
+ size = DEFAULT_POOL_SIZE;
+ else
+ size = (*it).second;
+
+ if (mPropertyDefineFn && !mPropertyDefineFn.empty())
+ mPropertyDefineFn(keyName, size, "Coroutine Pool size for " + poolName);
+ LL_WARNS() << "LLCoprocedureManager: No setting for \"" << keyName << "\" setting pool size to default of " << size << LL_ENDL;
+ }
+
+ poolPtr_t pool = poolPtr_t(new LLCoprocedurePool(poolName, size));
+ mPoolMap.insert(poolMap_t::value_type(poolName, pool));
+
+ return pool;
+}
+
+//-------------------------------------------------------------------------
+LLUUID LLCoprocedureManager::enqueueCoprocedure(const std::string &pool, const std::string &name, CoProcedure_t proc)
+{
+ // Attempt to find the pool and enqueue the procedure. If the pool does
+ // not exist, create it.
+ poolPtr_t targetPool;
+ poolMap_t::iterator it = mPoolMap.find(pool);
+
+ if (it == mPoolMap.end())
+ {
+ targetPool = initializePool(pool);
+ }
+ else
+ {
+ targetPool = (*it).second;
+ }
+
+ if (!targetPool)
+ {
+ LL_WARNS() << "LLCoprocedureManager unable to create coprocedure pool named \"" << pool << "\"" << LL_ENDL;
+ return LLUUID::null;
+ }
+
+ return targetPool->enqueueCoprocedure(name, proc);
+}
+
+void LLCoprocedureManager::cancelCoprocedure(const LLUUID &id)
+{
+ for (poolMap_t::const_iterator it = mPoolMap.begin(); it != mPoolMap.end(); ++it)
+ {
+ if ((*it).second->cancelCoprocedure(id))
+ return;
+ }
+ LL_INFOS() << "Coprocedure not found." << LL_ENDL;
+}
+
+void LLCoprocedureManager::shutdown(bool hardShutdown)
+{
+ for (poolMap_t::const_iterator it = mPoolMap.begin(); it != mPoolMap.end(); ++it)
+ {
+ (*it).second->shutdown(hardShutdown);
+ }
+ mPoolMap.clear();
+}
+
+void LLCoprocedureManager::setPropertyMethods(SettingQuery_t queryfn, SettingUpdate_t updatefn)
+{
+ mPropertyQueryFn = queryfn;
+ mPropertyDefineFn = updatefn;
+}
+
+//-------------------------------------------------------------------------
+size_t LLCoprocedureManager::countPending() const
+{
+ size_t count = 0;
+ for (poolMap_t::const_iterator it = mPoolMap.begin(); it != mPoolMap.end(); ++it)
+ {
+ count += (*it).second->countPending();
+ }
+ return count;
+}
+
+size_t LLCoprocedureManager::countPending(const std::string &pool) const
+{
+ poolMap_t::const_iterator it = mPoolMap.find(pool);
+
+ if (it == mPoolMap.end())
+ return 0;
+ return (*it).second->countPending();
+}
+
+size_t LLCoprocedureManager::countActive() const
+{
+ size_t count = 0;
+ for (poolMap_t::const_iterator it = mPoolMap.begin(); it != mPoolMap.end(); ++it)
+ {
+ count += (*it).second->countActive();
+ }
+ return count;
+}
+
+size_t LLCoprocedureManager::countActive(const std::string &pool) const
+{
+ poolMap_t::const_iterator it = mPoolMap.find(pool);
+
+ if (it == mPoolMap.end())
+ return 0;
+ return (*it).second->countActive();
+}
+
+size_t LLCoprocedureManager::count() const
+{
+ size_t count = 0;
+ for (poolMap_t::const_iterator it = mPoolMap.begin(); it != mPoolMap.end(); ++it)
+ {
+ count += (*it).second->count();
+ }
+ return count;
+}
+
+size_t LLCoprocedureManager::count(const std::string &pool) const
+{
+ poolMap_t::const_iterator it = mPoolMap.find(pool);
+
+ if (it == mPoolMap.end())
+ return 0;
+ return (*it).second->count();
+}
+
+//=========================================================================
+LLCoprocedurePool::LLCoprocedurePool(const std::string &poolName, size_t size):
+ mPoolName(poolName),
+ mPoolSize(size),
+ mPendingCoprocs(),
+ mShutdown(false),
+ mWakeupTrigger("CoprocedurePool" + poolName, true),
+ mCoroMapping(),
+ mHTTPPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID)
+{
+ for (size_t count = 0; count < mPoolSize; ++count)
+ {
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter =
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t(
+ new LLCoreHttpUtil::HttpCoroutineAdapter( mPoolName + "Adapter", mHTTPPolicy));
+
+ std::string uploadCoro = LLCoros::instance().launch("LLCoprocedurePool("+mPoolName+")::coprocedureInvokerCoro",
+ boost::bind(&LLCoprocedurePool::coprocedureInvokerCoro, this, httpAdapter));
+
+ mCoroMapping.insert(CoroAdapterMap_t::value_type(uploadCoro, httpAdapter));
+ }
+
+ LL_INFOS() << "Created coprocedure pool named \"" << mPoolName << "\" with " << size << " items." << LL_ENDL;
+
+ mWakeupTrigger.post(LLSD());
+}
+
+LLCoprocedurePool::~LLCoprocedurePool()
+{
+ shutdown();
+}
+
+//-------------------------------------------------------------------------
+void LLCoprocedurePool::shutdown(bool hardShutdown)
+{
+ CoroAdapterMap_t::iterator it;
+
+ for (it = mCoroMapping.begin(); it != mCoroMapping.end(); ++it)
+ {
+ if (!(*it).first.empty())
+ {
+ if (hardShutdown)
+ {
+ LLCoros::instance().kill((*it).first);
+ }
+ }
+ if ((*it).second)
+ {
+ (*it).second->cancelYieldingOperation();
+ }
+ }
+
+ mShutdown = true;
+ mCoroMapping.clear();
+ mPendingCoprocs.clear();
+}
+
+//-------------------------------------------------------------------------
+LLUUID LLCoprocedurePool::enqueueCoprocedure(const std::string &name, LLCoprocedurePool::CoProcedure_t proc)
+{
+ LLUUID id(LLUUID::generateNewID());
+
+ mPendingCoprocs.push_back(QueuedCoproc::ptr_t(new QueuedCoproc(name, id, proc)));
+ LL_INFOS() << "Coprocedure(" << name << ") enqueued with id=" << id.asString() << " in pool \"" << mPoolName << "\"" << LL_ENDL;
+
+ mWakeupTrigger.post(LLSD());
+
+ return id;
+}
+
+bool LLCoprocedurePool::cancelCoprocedure(const LLUUID &id)
+{
+ // first check the active coroutines. If there, remove it and return.
+ ActiveCoproc_t::iterator itActive = mActiveCoprocs.find(id);
+ if (itActive != mActiveCoprocs.end())
+ {
+ LL_INFOS() << "Found and canceling active coprocedure with id=" << id.asString() << " in pool \"" << mPoolName << "\"" << LL_ENDL;
+ (*itActive).second->cancelYieldingOperation();
+ mActiveCoprocs.erase(itActive);
+ return true;
+ }
+
+ for (CoprocQueue_t::iterator it = mPendingCoprocs.begin(); it != mPendingCoprocs.end(); ++it)
+ {
+ if ((*it)->mId == id)
+ {
+ LL_INFOS() << "Found and removing queued coroutine(" << (*it)->mName << ") with Id=" << id.asString() << " in pool \"" << mPoolName << "\"" << LL_ENDL;
+ mPendingCoprocs.erase(it);
+ return true;
+ }
+ }
+
+ LL_INFOS() << "Coprocedure with Id=" << id.asString() << " was not found." << " in pool \"" << mPoolName << "\"" << LL_ENDL;
+ return false;
+}
+
+//-------------------------------------------------------------------------
+void LLCoprocedurePool::coprocedureInvokerCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter)
+{
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+ while (!mShutdown)
+ {
+ llcoro::waitForEventOn(mWakeupTrigger);
+ if (mShutdown)
+ break;
+
+ while (!mPendingCoprocs.empty())
+ {
+ QueuedCoproc::ptr_t coproc = mPendingCoprocs.front();
+ mPendingCoprocs.pop_front();
+ mActiveCoprocs.insert(ActiveCoproc_t::value_type(coproc->mId, httpAdapter));
+
+ LL_INFOS() << "Dequeued and invoking coprocedure(" << coproc->mName << ") with id=" << coproc->mId.asString() << " in pool \"" << mPoolName << "\"" << LL_ENDL;
+
+ try
+ {
+ coproc->mProc(httpAdapter, coproc->mId);
+ }
+ catch (std::exception &e)
+ {
+ LL_WARNS() << "Coprocedure(" << coproc->mName << ") id=" << coproc->mId.asString() <<
+ " threw an exception! Message=\"" << e.what() << "\"" << LL_ENDL;
+ }
+ catch (...)
+ {
+ LL_WARNS() << "A non std::exception was thrown from " << coproc->mName << " with id=" << coproc->mId << "." << " in pool \"" << mPoolName << "\"" << LL_ENDL;
+ }
+
+ LL_INFOS() << "Finished coprocedure(" << coproc->mName << ")" << " in pool \"" << mPoolName << "\"" << LL_ENDL;
+
+ ActiveCoproc_t::iterator itActive = mActiveCoprocs.find(coproc->mId);
+ if (itActive != mActiveCoprocs.end())
+ {
+ mActiveCoprocs.erase(itActive);
+ }
+ }
+ }
+}
diff --git a/indra/llmessage/llcoproceduremanager.h b/indra/llmessage/llcoproceduremanager.h
new file mode 100644
index 0000000000..497367b80c
--- /dev/null
+++ b/indra/llmessage/llcoproceduremanager.h
@@ -0,0 +1,98 @@
+/**
+* @file llcoproceduremanager.h
+* @author Rider Linden
+* @brief Singleton class for managing asset uploads to the sim.
+*
+* $LicenseInfo:firstyear=2015&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2015, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+* $/LicenseInfo$
+*/
+
+#ifndef LL_COPROCEDURE_MANAGER_H
+#define LL_COPROCEDURE_MANAGER_H
+
+#include "lleventcoro.h"
+#include "llcoros.h"
+#include "llcorehttputil.h"
+#include "lluuid.h"
+
+class LLCoprocedurePool;
+
+class LLCoprocedureManager : public LLSingleton < LLCoprocedureManager >
+{
+ friend class LLSingleton < LLCoprocedureManager > ;
+
+public:
+ typedef boost::function SettingQuery_t;
+ typedef boost::function SettingUpdate_t;
+
+ typedef boost::function CoProcedure_t;
+
+ LLCoprocedureManager();
+ virtual ~LLCoprocedureManager();
+
+ /// Places the coprocedure on the queue for processing.
+ ///
+ /// @param name Is used for debugging and should identify this coroutine.
+ /// @param proc Is a bound function to be executed
+ ///
+ /// @return This method returns a UUID that can be used later to cancel execution.
+ LLUUID enqueueCoprocedure(const std::string &pool, const std::string &name, CoProcedure_t proc);
+
+ /// Cancel a coprocedure. If the coprocedure is already being actively executed
+ /// this method calls cancelYieldingOperation() on the associated HttpAdapter
+ /// If it has not yet been dequeued it is simply removed from the queue.
+ void cancelCoprocedure(const LLUUID &id);
+
+ /// Requests a shutdown of the upload manager. Passing 'true' will perform
+ /// an immediate kill on the upload coroutine.
+ void shutdown(bool hardShutdown = false);
+
+ void setPropertyMethods(SettingQuery_t queryfn, SettingUpdate_t updatefn);
+
+ /// Returns the number of coprocedures in the queue awaiting processing.
+ ///
+ size_t countPending() const;
+ size_t countPending(const std::string &pool) const;
+
+ /// Returns the number of coprocedures actively being processed.
+ ///
+ size_t countActive() const;
+ size_t countActive(const std::string &pool) const;
+
+ /// Returns the total number of coprocedures either queued or in active processing.
+ ///
+ size_t count() const;
+ size_t count(const std::string &pool) const;
+
+private:
+
+ typedef boost::shared_ptr poolPtr_t;
+ typedef std::map poolMap_t;
+
+ poolMap_t mPoolMap;
+
+ poolPtr_t initializePool(const std::string &poolName);
+
+ SettingQuery_t mPropertyQueryFn;
+ SettingUpdate_t mPropertyDefineFn;
+};
+
+#endif
diff --git a/indra/llmessage/llexperiencecache.cpp b/indra/llmessage/llexperiencecache.cpp
index 34c4210359..36a4fc8823 100644
--- a/indra/llmessage/llexperiencecache.cpp
+++ b/indra/llmessage/llexperiencecache.cpp
@@ -26,53 +26,51 @@
#include "llexperiencecache.h"
#include "llavatarname.h"
-#include "llframetimer.h"
#include "llhttpclient.h"
#include "llsdserialize.h"
+#include "llcoros.h"
+#include "lleventcoro.h"
+#include "lleventfilter.h"
+#include "llcoproceduremanager.h"
+#include "lldir.h"
#include
#include
",
- "", "", "some error");
- }
-
- template<> template<>
- void translate_test_object_t::test<17>()
- {
- test_translation(mBing, 400,
- "Message: some error",
- "", "", "some error");
- }
-
- template<> template<>
- void translate_test_object_t::test<18>()
- {
- test_translation(mBing, 400,
- "some error",
- "", "", "some error");
- }
-
- template<> template<>
- void translate_test_object_t::test<19>()
- {
- test_translation(mBing, 400,
- "some error",
- "", "", "some error");
- }
-
- template<> template<>
- void translate_test_object_t::test<20>()
- {
- std::string url;
- mBing.getTranslateURL(url, "en", "es", "hi");
- ensure_equals("bing URL", url,
- "http://api.microsofttranslator.com/v2/Http.svc/Translate?appId=dummy&text=hi&to=es&from=en");
- }
-
- template<> template<>
- void translate_test_object_t::test<21>()
- {
- std::string url;
- mBing.getTranslateURL(url, "", "es", "hi");
- ensure_equals("bing URL", url,
- "http://api.microsofttranslator.com/v2/Http.svc/Translate?appId=dummy&text=hi&to=es");
- }
-
- template<> template<>
- void translate_test_object_t::test<22>()
- {
- std::string url;
- mGoogle.getTranslateURL(url, "en", "es", "hi");
- ensure_equals("google URL", url,
- "https://www.googleapis.com/language/translate/v2?key=dummy&q=hi&target=es&source=en");
- }
-
- template<> template<>
- void translate_test_object_t::test<23>()
- {
- std::string url;
- mGoogle.getTranslateURL(url, "", "es", "hi");
- ensure_equals("google URL", url,
- "https://www.googleapis.com/language/translate/v2?key=dummy&q=hi&target=es");
- }
-}
-
-//== Misc stubs ===============================================================
-LLControlGroup gSavedSettings("test");
-
-std::string LLUI::getLanguage() { return "en"; }
-std::string LLTrans::getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args) { return "dummy"; }
-
-LLControlGroup::LLControlGroup(const std::string& name) : LLInstanceTracker(name) {}
-std::string LLControlGroup::getString(const std::string& name) { return "dummy"; }
-LLControlGroup::~LLControlGroup() {}
-
-LLCurl::Responder::Responder() {}
-void LLCurl::Responder::httpFailure() { }
-void LLCurl::Responder::httpSuccess() { }
-void LLCurl::Responder::httpCompleted() { }
-void LLCurl::Responder::completedRaw(LLChannelDescriptors const &,boost::shared_ptr const &) { }
-LLCurl::Responder::~Responder() {}
-
-void LLHTTPClient::get(const std::string&, const LLSD&, ResponderPtr, const LLSD&, const F32, bool) {}
-void LLHTTPClient::get(const std::string&, LLPointer, const LLSD&, const F32, bool) {}
-
-LLBufferStream::LLBufferStream(const LLChannelDescriptors& channels, LLBufferArray* buffer)
-: std::iostream(&mStreamBuf), mStreamBuf(channels, buffer) {}
-LLBufferStream::~LLBufferStream() {}
-
-LLBufferStreamBuf::LLBufferStreamBuf(const LLChannelDescriptors&, LLBufferArray*) {}
-#if( LL_WINDOWS || __GNUC__ > 2)
-LLBufferStreamBuf::pos_type LLBufferStreamBuf::seekoff(
- off_type off,
- std::ios::seekdir way,
- std::ios::openmode which)
-#else
-streampos LLBufferStreamBuf::seekoff(
- streamoff off,
- std::ios::seekdir way,
- std::ios::openmode which)
-#endif
-{ return 0; }
-int LLBufferStreamBuf::sync() {return 0;}
-int LLBufferStreamBuf::underflow() {return 0;}
-int LLBufferStreamBuf::overflow(int) {return 0;}
-LLBufferStreamBuf::~LLBufferStreamBuf() {}
-
-S32 LLVersionInfo::getBuild() { return 0; }
-const std::string& LLVersionInfo::getChannel() {static std::string dummy; return dummy;}
-S32 LLVersionInfo::getMajor() { return 0; }
-S32 LLVersionInfo::getMinor() { return 0; }
-S32 LLVersionInfo::getPatch() { return 0; }
--
cgit v1.3
From 1eed334e7ff1ce261f740f5da7207a65c3f4ef57 Mon Sep 17 00:00:00 2001
From: Rider Linden
Date: Mon, 21 Sep 2015 10:59:58 -0700
Subject: MAINT-5629: Remove llares and llareslistener. Login now does not
attempt to do a lookup on the server names and rewrite the URL. MAINT-5614:
Bad password status correctly detected.
---
indra/llmessage/CMakeLists.txt | 4 -
indra/llmessage/llares.cpp | 839 ---------------------
indra/llmessage/llares.h | 583 --------------
indra/llmessage/llareslistener.cpp | 104 ---
indra/llmessage/llareslistener.h | 53 --
indra/newview/llappviewer.cpp | 25 -
indra/newview/llstartup.cpp | 8 -
indra/viewer_components/login/lllogin.cpp | 221 +++---
.../viewer_components/login/tests/lllogin_test.cpp | 191 +----
9 files changed, 94 insertions(+), 1934 deletions(-)
delete mode 100755 indra/llmessage/llares.cpp
delete mode 100755 indra/llmessage/llares.h
delete mode 100755 indra/llmessage/llareslistener.cpp
delete mode 100755 indra/llmessage/llareslistener.h
(limited to 'indra/newview/llstartup.cpp')
diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt
index 3bcee13d28..5877c4a8e4 100755
--- a/indra/llmessage/CMakeLists.txt
+++ b/indra/llmessage/CMakeLists.txt
@@ -28,8 +28,6 @@ include_directories(
)
set(llmessage_SOURCE_FILES
- llares.cpp
- llareslistener.cpp
llassetstorage.cpp
llavatarname.cpp
llavatarnamecache.cpp
@@ -109,8 +107,6 @@ set(llmessage_SOURCE_FILES
set(llmessage_HEADER_FILES
CMakeLists.txt
- llares.h
- llareslistener.h
llassetstorage.h
llavatarname.h
llavatarnamecache.h
diff --git a/indra/llmessage/llares.cpp b/indra/llmessage/llares.cpp
deleted file mode 100755
index 9f90ae1544..0000000000
--- a/indra/llmessage/llares.cpp
+++ /dev/null
@@ -1,839 +0,0 @@
-/**
- * @file llares.cpp
- * @author Bryan O'Sullivan
- * @date 2007-08-15
- * @brief Wrapper for asynchronous DNS lookups.
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "linden_common.h"
-#include "llares.h"
-
-#include
-#include
-
-#include "apr_portable.h"
-#include "apr_network_io.h"
-#include "apr_poll.h"
-
-#include "llapr.h"
-#include "llareslistener.h"
-
-#if defined(LL_WINDOWS)
-#pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally
-# define ns_c_in 1
-# define NS_HFIXEDSZ 12 /* #/bytes of fixed data in header */
-# define NS_QFIXEDSZ 4 /* #/bytes of fixed data in query */
-# define NS_RRFIXEDSZ 10 /* #/bytes of fixed data in r record */
-#else
-# include
-#endif
-
-LLAres::HostResponder::~HostResponder()
-{
-}
-
-void LLAres::HostResponder::hostResult(const hostent *ent)
-{
- LL_INFOS() << "LLAres::HostResponder::hostResult not implemented" << LL_ENDL;
-}
-
-void LLAres::HostResponder::hostError(int code)
-{
- LL_INFOS() << "LLAres::HostResponder::hostError " << code << ": "
- << LLAres::strerror(code) << LL_ENDL;
-}
-
-LLAres::NameInfoResponder::~NameInfoResponder()
-{
-}
-
-void LLAres::NameInfoResponder::nameInfoResult(const char *node,
- const char *service)
-{
- LL_INFOS() << "LLAres::NameInfoResponder::nameInfoResult not implemented"
- << LL_ENDL;
-}
-
-void LLAres::NameInfoResponder::nameInfoError(int code)
-{
- LL_INFOS() << "LLAres::NameInfoResponder::nameInfoError " << code << ": "
- << LLAres::strerror(code) << LL_ENDL;
-}
-
-LLAres::QueryResponder::~QueryResponder()
-{
-}
-
-void LLAres::QueryResponder::queryResult(const char *buf, size_t len)
-{
- LL_INFOS() << "LLAres::QueryResponder::queryResult not implemented"
- << LL_ENDL;
-}
-
-void LLAres::QueryResponder::queryError(int code)
-{
- LL_INFOS() << "LLAres::QueryResponder::queryError " << code << ": "
- << LLAres::strerror(code) << LL_ENDL;
-}
-
-LLAres::LLAres() :
- chan_(NULL),
- mInitSuccess(false)
-{
- if (ares_library_init( ARES_LIB_INIT_ALL ) != ARES_SUCCESS ||
- ares_init(&chan_) != ARES_SUCCESS)
- {
- LL_WARNS() << "Could not succesfully initialize ares!" << LL_ENDL;
- return;
- }
-
- mListener = boost::shared_ptr< LLAresListener >(new LLAresListener(this));
-
- mInitSuccess = true;
-}
-
-LLAres::~LLAres()
-{
- ares_destroy(chan_);
- ares_library_cleanup();
-}
-
-void LLAres::cancel()
-{
- ares_cancel(chan_);
-}
-
-static void host_callback_1_5(void *arg, int status, int timeouts,
- struct hostent *ent)
-{
- LLPointer *resp =
- (LLPointer *) arg;
-
- if (status == ARES_SUCCESS)
- {
- (*resp)->hostResult(ent);
- } else {
- (*resp)->hostError(status);
- }
-
- delete resp;
-}
-
-#if ARES_VERSION_MAJOR == 1 && ARES_VERSION_MINOR == 4
-static void host_callback(void *arg, int status, struct hostent *ent)
-{
- host_callback_1_5(arg, status, 0, ent);
-}
-#else
-# define host_callback host_callback_1_5
-#endif
-
-void LLAres::getHostByName(const char *name, HostResponder *resp,
- int family)
-{
- ares_gethostbyname(chan_, name, family, host_callback,
- new LLPointer(resp));
-}
-
-void LLAres::getSrvRecords(const std::string &name, SrvResponder *resp)
-{
- search(name, RES_SRV, resp);
-}
-
-void LLAres::rewriteURI(const std::string &uri, UriRewriteResponder *resp)
-{
- if (resp && uri.size())
- {
- LLURI* pURI = new LLURI(uri);
-
- resp->mUri = *pURI;
-
- delete pURI;
-
- if (!resp->mUri.scheme().size() || !resp->mUri.hostName().size())
- {
- return;
- }
-
- //LL_INFOS() << "LLAres::rewriteURI (" << uri << ") search: '" << "_" + resp->mUri.scheme() + "._tcp." + resp->mUri.hostName() << "'" << LL_ENDL;
-
- search("_" + resp->mUri.scheme() + "._tcp." + resp->mUri.hostName(), RES_SRV, resp);
-
-
- }
-}
-
-LLQueryResponder::LLQueryResponder()
- : LLAres::QueryResponder(),
- mResult(ARES_ENODATA),
- mType(RES_INVALID)
-{
-}
-
-int LLQueryResponder::parseRR(const char *buf, size_t len, const char *&pos,
- LLPointer &r)
-{
- std::string rrname;
- size_t enclen;
- int ret;
-
- // RR name.
-
- ret = LLAres::expandName(pos, buf, len, rrname, enclen);
- if (ret != ARES_SUCCESS)
- {
- return ret;
- }
-
- pos += enclen;
-
- if (pos + NS_RRFIXEDSZ > buf + len)
- {
- return ARES_EBADRESP;
- }
-
- int rrtype = DNS_RR_TYPE(pos);
- int rrclass = DNS_RR_CLASS(pos);
- int rrttl = DNS_RR_TTL(pos);
- int rrlen = DNS_RR_LEN(pos);
-
- if (rrclass != ns_c_in)
- {
- return ARES_EBADRESP;
- }
-
- pos += NS_RRFIXEDSZ;
-
- if (pos + rrlen > buf + len)
- {
- return ARES_EBADRESP;
- }
-
- switch (rrtype)
- {
- case RES_A:
- r = new LLARecord(rrname, rrttl);
- break;
- case RES_NS:
- r = new LLNsRecord(rrname, rrttl);
- break;
- case RES_CNAME:
- r = new LLCnameRecord(rrname, rrttl);
- break;
- case RES_PTR:
- r = new LLPtrRecord(rrname, rrttl);
- break;
- case RES_AAAA:
- r = new LLAaaaRecord(rrname, rrttl);
- break;
- case RES_SRV:
- r = new LLSrvRecord(rrname, rrttl);
- break;
- default:
- LL_INFOS() << "LLQueryResponder::parseRR got unknown RR type " << rrtype
- << LL_ENDL;
- return ARES_EBADRESP;
- }
-
- ret = r->parse(buf, len, pos, rrlen);
-
- if (ret == ARES_SUCCESS)
- {
- pos += rrlen;
- } else {
- r = NULL;
- }
-
- return ret;
-}
-
-int LLQueryResponder::parseSection(const char *buf, size_t len,
- size_t count, const char *&pos,
- dns_rrs_t &rrs)
-{
- int ret = ARES_SUCCESS;
-
- for (size_t i = 0; i < count; i++)
- {
- LLPointer r;
- ret = parseRR(buf, len, pos, r);
- if (ret != ARES_SUCCESS)
- {
- break;
- }
- rrs.push_back(r);
- }
-
- return ret;
-}
-
-void LLQueryResponder::queryResult(const char *buf, size_t len)
-{
- const char *pos = buf;
- int qdcount = DNS_HEADER_QDCOUNT(pos);
- int ancount = DNS_HEADER_ANCOUNT(pos);
- int nscount = DNS_HEADER_NSCOUNT(pos);
- int arcount = DNS_HEADER_ARCOUNT(pos);
- int ret;
-
- if (qdcount == 0 || ancount + nscount + arcount == 0)
- {
- ret = ARES_ENODATA;
- goto bail;
- }
-
- pos += NS_HFIXEDSZ;
-
- for (int i = 0; i < qdcount; i++)
- {
- std::string ignore;
- size_t enclen;
-
- ret = LLAres::expandName(pos, buf, len, i == 0 ? mQuery : ignore,
- enclen);
- if (ret != ARES_SUCCESS)
- {
- goto bail;
- }
-
- pos += enclen;
-
- if (i == 0)
- {
- int t = DNS_QUESTION_TYPE(pos);
- switch (t)
- {
- case RES_A:
- case RES_NS:
- case RES_CNAME:
- case RES_PTR:
- case RES_AAAA:
- case RES_SRV:
- mType = (LLResType) t;
- break;
- default:
- LL_INFOS() << "Cannot grok query type " << t << LL_ENDL;
- ret = ARES_EBADQUERY;
- goto bail;
- }
- }
-
- pos += NS_QFIXEDSZ;
- if (pos > buf + len)
- {
- ret = ARES_EBADRESP;
- goto bail;
- }
- }
-
- ret = parseSection(buf, len, ancount, pos, mAnswers);
- if (ret != ARES_SUCCESS)
- {
- goto bail;
- }
-
- ret = parseSection(buf, len, nscount, pos, mAuthorities);
- if (ret != ARES_SUCCESS)
- {
- goto bail;
- }
-
- ret = parseSection(buf, len, arcount, pos, mAdditional);
-
-bail:
- mResult = ret;
- if (mResult == ARES_SUCCESS)
- {
- querySuccess();
- } else {
- queryError(mResult);
- }
-}
-
-void LLQueryResponder::querySuccess()
-{
- LL_INFOS() << "LLQueryResponder::queryResult not implemented" << LL_ENDL;
-}
-
-void LLAres::SrvResponder::querySuccess()
-{
- if (mType == RES_SRV)
- {
- srvResult(mAnswers);
- } else {
- srvError(ARES_EBADRESP);
- }
-}
-
-void LLAres::SrvResponder::queryError(int code)
-{
- srvError(code);
-}
-
-void LLAres::SrvResponder::srvResult(const dns_rrs_t &ents)
-{
- LL_INFOS() << "LLAres::SrvResponder::srvResult not implemented" << LL_ENDL;
-
- for (size_t i = 0; i < ents.size(); i++)
- {
- const LLSrvRecord *s = (const LLSrvRecord *) ents[i].get();
-
- LL_INFOS() << "[" << i << "] " << s->host() << ":" << s->port()
- << " priority " << s->priority()
- << " weight " << s->weight()
- << LL_ENDL;
- }
-}
-
-void LLAres::SrvResponder::srvError(int code)
-{
- LL_INFOS() << "LLAres::SrvResponder::srvError " << code << ": "
- << LLAres::strerror(code) << LL_ENDL;
-}
-
-static void nameinfo_callback_1_5(void *arg, int status, int timeouts,
- char *node, char *service)
-{
- LLPointer *resp =
- (LLPointer *) arg;
-
- if (status == ARES_SUCCESS)
- {
- (*resp)->nameInfoResult(node, service);
- } else {
- (*resp)->nameInfoError(status);
- }
-
- delete resp;
-}
-
-#if ARES_VERSION_MAJOR == 1 && ARES_VERSION_MINOR == 4
-static void nameinfo_callback(void *arg, int status, char *node, char *service)
-{
- nameinfo_callback_1_5(arg, status, 0, node, service);
-}
-#else
-# define nameinfo_callback nameinfo_callback_1_5
-#endif
-
-void LLAres::getNameInfo(const struct sockaddr &sa, socklen_t salen, int flags,
- NameInfoResponder *resp)
-{
- ares_getnameinfo(chan_, &sa, salen, flags, nameinfo_callback,
- new LLPointer(resp));
-}
-
-static void search_callback_1_5(void *arg, int status, int timeouts,
- unsigned char *abuf, int alen)
-{
- LLPointer *resp =
- (LLPointer *) arg;
-
- if (status == ARES_SUCCESS)
- {
- (*resp)->queryResult((const char *) abuf, alen);
- } else {
- (*resp)->queryError(status);
- }
-
- delete resp;
-}
-
-#if ARES_VERSION_MAJOR == 1 && ARES_VERSION_MINOR == 4
-static void search_callback(void *arg, int status, unsigned char *abuf,
- int alen)
-{
- search_callback_1_5(arg, status, 0, abuf, alen);
-}
-#else
-# define search_callback search_callback_1_5
-#endif
-
-void LLAres::search(const std::string &query, LLResType type,
- QueryResponder *resp)
-{
- ares_search(chan_, query.c_str(), ns_c_in, type, search_callback,
- new LLPointer(resp));
-}
-
-bool LLAres::process(U64 timeout)
-{
- if (!gAPRPoolp)
- {
- ll_init_apr();
- }
-
- ares_socket_t socks[ARES_GETSOCK_MAXNUM];
- apr_pollfd_t aprFds[ARES_GETSOCK_MAXNUM];
- apr_int32_t nsds = 0;
- int nactive = 0;
- int bitmask;
-
- bitmask = ares_getsock(chan_, socks, ARES_GETSOCK_MAXNUM);
-
- if (bitmask == 0)
- {
- return nsds > 0;
- }
-
- apr_status_t status;
- LLAPRPool pool;
- status = pool.getStatus() ;
- ll_apr_assert_status(status);
-
- for (int i = 0; i < ARES_GETSOCK_MAXNUM; i++)
- {
- if (ARES_GETSOCK_READABLE(bitmask, i))
- {
- aprFds[nactive].reqevents = APR_POLLIN | APR_POLLERR;
- }
- else if (ARES_GETSOCK_WRITABLE(bitmask, i))
- {
- aprFds[nactive].reqevents = APR_POLLOUT | APR_POLLERR;
- } else {
- continue;
- }
-
- apr_socket_t *aprSock = NULL;
-
- status = apr_os_sock_put(&aprSock, (apr_os_sock_t *) &socks[i], pool.getAPRPool());
- if (status != APR_SUCCESS)
- {
- ll_apr_warn_status(status);
- return nsds > 0;
- }
-
- aprFds[nactive].desc.s = aprSock;
- aprFds[nactive].desc_type = APR_POLL_SOCKET;
- aprFds[nactive].p = pool.getAPRPool();
- aprFds[nactive].rtnevents = 0;
- aprFds[nactive].client_data = &socks[i];
-
- nactive++;
- }
-
- if (nactive > 0)
- {
- status = apr_poll(aprFds, nactive, &nsds, timeout);
-
- if (status != APR_SUCCESS && status != APR_TIMEUP)
- {
- ll_apr_warn_status(status);
- }
-
- for (int i = 0; i < nactive; i++)
- {
- int evts = aprFds[i].rtnevents;
- int ifd = (evts & (APR_POLLIN | APR_POLLERR))
- ? *((int *) aprFds[i].client_data) : ARES_SOCKET_BAD;
- int ofd = (evts & (APR_POLLOUT | APR_POLLERR))
- ? *((int *) aprFds[i].client_data) : ARES_SOCKET_BAD;
-
- ares_process_fd(chan_, ifd, ofd);
- }
- }
-
- return nsds > 0;
-}
-
-bool LLAres::processAll()
-{
- bool anyProcessed = false, ret;
-
- do {
- timeval tv;
-
- ret = ares_timeout(chan_, NULL, &tv) != NULL;
-
- if (ret)
- {
- ret = process(tv.tv_sec * 1000000LL + tv.tv_usec);
- anyProcessed |= ret;
- }
- } while (ret);
-
- return anyProcessed;
-}
-
-int LLAres::expandName(const char *encoded, const char *abuf, size_t alen,
- std::string &s, size_t &enclen)
-{
- char *t;
- int ret;
- long e;
-
- ret = ares_expand_name((const unsigned char *) encoded,
- (const unsigned char *) abuf, alen, &t, &e);
- if (ret == ARES_SUCCESS)
- {
- s.assign(t);
- enclen = e;
- ares_free_string(t);
- }
- return ret;
-}
-
-const char *LLAres::strerror(int code)
-{
- return ares_strerror(code);
-}
-
-LLAres *gAres;
-
-LLAres *ll_init_ares()
-{
- if (gAres == NULL)
- {
- gAres = new LLAres();
- }
- return gAres;
-}
-
-void ll_cleanup_ares()
-{
- if (gAres != NULL)
- {
- delete gAres;
- gAres = NULL;
- }
-}
-
-LLDnsRecord::LLDnsRecord(LLResType type, const std::string &name,
- unsigned ttl)
- : LLRefCount(),
- mType(type),
- mName(name),
- mTTL(ttl)
-{
-}
-
-LLHostRecord::LLHostRecord(LLResType type, const std::string &name,
- unsigned ttl)
- : LLDnsRecord(type, name, ttl)
-{
-}
-
-int LLHostRecord::parse(const char *buf, size_t len, const char *pos,
- size_t rrlen)
-{
- int ret;
-
- ret = LLAres::expandName(pos, buf, len, mHost);
- if (ret != ARES_SUCCESS)
- {
- goto bail;
- }
-
- ret = ARES_SUCCESS;
-
-bail:
- return ret;
-}
-
-LLCnameRecord::LLCnameRecord(const std::string &name, unsigned ttl)
- : LLHostRecord(RES_CNAME, name, ttl)
-{
-}
-
-LLPtrRecord::LLPtrRecord(const std::string &name, unsigned ttl)
- : LLHostRecord(RES_PTR, name, ttl)
-{
-}
-
-LLAddrRecord::LLAddrRecord(LLResType type, const std::string &name,
- unsigned ttl)
- : LLDnsRecord(type, name, ttl),
-
- mSize(0)
-{
-}
-
-LLARecord::LLARecord(const std::string &name, unsigned ttl)
- : LLAddrRecord(RES_A, name, ttl)
-{
-}
-
-int LLARecord::parse(const char *buf, size_t len, const char *pos,
- size_t rrlen)
-{
- int ret;
-
- if (rrlen != sizeof(mSA.sin.sin_addr.s_addr))
- {
- ret = ARES_EBADRESP;
- goto bail;
- }
-
- memset(&mSA, 0, sizeof(mSA));
- memcpy(&mSA.sin.sin_addr.s_addr, pos, rrlen);
- mSA.sin.sin_family = AF_INET6;
- mSize = sizeof(mSA.sin);
-
- ret = ARES_SUCCESS;
-
-bail:
- return ret;
-}
-
-LLAaaaRecord::LLAaaaRecord(const std::string &name, unsigned ttl)
- : LLAddrRecord(RES_AAAA, name, ttl)
-{
-}
-
-int LLAaaaRecord::parse(const char *buf, size_t len, const char *pos,
- size_t rrlen)
-{
- int ret;
-
- if (rrlen != sizeof(mSA.sin6.sin6_addr))
- {
- ret = ARES_EBADRESP;
- goto bail;
- }
-
- memset(&mSA, 0, sizeof(mSA));
- memcpy(&mSA.sin6.sin6_addr.s6_addr, pos, rrlen);
- mSA.sin6.sin6_family = AF_INET6;
- mSize = sizeof(mSA.sin6);
-
- ret = ARES_SUCCESS;
-
-bail:
- return ret;
-}
-
-LLSrvRecord::LLSrvRecord(const std::string &name, unsigned ttl)
- : LLHostRecord(RES_SRV, name, ttl),
-
- mPriority(0),
- mWeight(0),
- mPort(0)
-{
-}
-
-int LLSrvRecord::parse(const char *buf, size_t len, const char *pos,
- size_t rrlen)
-{
- int ret;
-
- if (rrlen < 6)
- {
- ret = ARES_EBADRESP;
- goto bail;
- }
-
- memcpy(&mPriority, pos, 2);
- memcpy(&mWeight, pos + 2, 2);
- memcpy(&mPort, pos + 4, 2);
-
- mPriority = ntohs(mPriority);
- mWeight = ntohs(mWeight);
- mPort = ntohs(mPort);
-
- ret = LLHostRecord::parse(buf, len, pos + 6, rrlen - 6);
-
-bail:
- return ret;
-}
-
-LLNsRecord::LLNsRecord(const std::string &name, unsigned ttl)
- : LLHostRecord(RES_NS, name, ttl)
-{
-}
-
-void LLAres::UriRewriteResponder::queryError(int code)
-{
- std::vector uris;
- uris.push_back(mUri.asString());
- rewriteResult(uris);
-}
-
-void LLAres::UriRewriteResponder::querySuccess()
-{
- std::vector uris;
-
- if (mType != RES_SRV)
- {
- goto bail;
- }
-
- for (size_t i = 0; i < mAnswers.size(); i++)
- {
- const LLSrvRecord *r = (const LLSrvRecord *) mAnswers[i].get();
-
- if (r->type() == RES_SRV)
- {
- // Check the domain in the response to ensure that it's
- // the same as the domain in the request, so that bad guys
- // can't forge responses that point to their own login
- // servers with their own certificates.
-
- // Hard-coding the domain to check here is a bit of a
- // hack. Hoist it to an outer caller if anyone ever needs
- // this functionality on other domains.
-
- static const std::string domain(".lindenlab.com");
- const std::string &host = r->host();
-
- std::string::size_type s = host.find(domain) + domain.length();
-
- if (s != host.length() && s != host.length() - 1)
- {
- continue;
- }
-
- LLURI uri(mUri.scheme(),
- mUri.userName(),
- mUri.password(),
- r->host(),
- mUri.defaultPort() ? r->port() : mUri.hostPort(),
- mUri.escapedPath(),
- mUri.escapedQuery());
- uris.push_back(uri.asString());
- }
- }
-
- if (!uris.empty())
- {
- goto done;
- }
-
-bail:
- uris.push_back(mUri.asString());
-
-done:
- rewriteResult(uris);
-}
-
-void LLAres::UriRewriteResponder::rewriteResult(
- const std::vector &uris)
-{
- LL_INFOS() << "LLAres::UriRewriteResponder::rewriteResult not implemented"
- << LL_ENDL;
-
- for (size_t i = 0; i < uris.size(); i++)
- {
- LL_INFOS() << "[" << i << "] " << uris[i] << LL_ENDL;
- }
-}
diff --git a/indra/llmessage/llares.h b/indra/llmessage/llares.h
deleted file mode 100755
index c727363b60..0000000000
--- a/indra/llmessage/llares.h
+++ /dev/null
@@ -1,583 +0,0 @@
-/**
- * @file llares.h
- * @author Bryan O'Sullivan
- * @date 2007-08-15
- * @brief Wrapper for asynchronous DNS lookups.
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLARES_H
-#define LL_LLARES_H
-
-#ifdef LL_WINDOWS
-// ares.h is broken on windows in that it depends on types defined in ws2tcpip.h
-// we need to include them first to work around it, but the headers issue warnings
-# pragma warning(push)
-# pragma warning(disable:4996)
-# include
-# include
-# pragma warning(pop)
-#endif
-
-#ifdef LL_USESYSTEMLIBS
-# include
-#else
-# include
-#endif
-
-#include "llpointer.h"
-#include "llrefcount.h"
-#include "lluri.h"
-
-#include
-
-class LLQueryResponder;
-class LLAresListener;
-
-/**
- * @brief Supported DNS RR types.
- */
-enum LLResType
-{
- RES_INVALID = 0, /**< Cookie. */
- RES_A = 1, /**< "A" record. IPv4 address. */
- RES_NS = 2, /**< "NS" record. Authoritative server. */
- RES_CNAME = 5, /**< "CNAME" record. Canonical name. */
- RES_PTR = 12, /**< "PTR" record. Domain name pointer. */
- RES_AAAA = 28, /**< "AAAA" record. IPv6 Address. */
- RES_SRV = 33, /**< "SRV" record. Server Selection. */
- RES_MAX = 65536 /**< Sentinel; RR types are 16 bits wide. */
-};
-
-/**
- * @class LLDnsRecord
- * @brief Base class for all DNS RR types.
- */
-class LLDnsRecord : public LLRefCount
-{
-protected:
- friend class LLQueryResponder;
-
- LLResType mType;
- std::string mName;
- unsigned mTTL;
-
- virtual int parse(const char *buf, size_t len, const char *pos,
- size_t rrlen) = 0;
-
- LLDnsRecord(LLResType type, const std::string &name, unsigned ttl);
-
-public:
- /**
- * @brief Record name.
- */
- const std::string &name() const { return mName; }
-
- /**
- * @brief Time-to-live value, in seconds.
- */
- unsigned ttl() const { return mTTL; }
-
- /**
- * @brief RR type.
- */
- LLResType type() const { return mType; }
-};
-
-/**
- * @class LLAddrRecord
- * @brief Base class for address-related RRs.
- */
-class LLAddrRecord : public LLDnsRecord
-{
-protected:
- friend class LLQueryResponder;
-
- LLAddrRecord(LLResType type, const std::string &name, unsigned ttl);
-
- union
- {
- sockaddr sa;
- sockaddr_in sin;
- sockaddr_in6 sin6;
- } mSA;
-
- socklen_t mSize;
-
-public:
- /**
- * @brief Generic socket address.
- */
- const sockaddr &addr() const { return mSA.sa; }
-
- /**
- * @brief Size of the socket structure.
- */
- socklen_t size() const { return mSize; }
-};
-
-/**
- * @class LLARecord
- * @brief A RR, for IPv4 addresses.
- */
-class LLARecord : public LLAddrRecord
-{
-protected:
- friend class LLQueryResponder;
-
- LLARecord(const std::string &name, unsigned ttl);
-
- int parse(const char *buf, size_t len, const char *pos, size_t rrlen);
-
-public:
- /**
- * @brief Socket address.
- */
- const sockaddr_in &addr_in() const { return mSA.sin; }
-};
-
-/**
- * @class LLAaaaRecord
- * @brief AAAA RR, for IPv6 addresses.
- */
-class LLAaaaRecord : public LLAddrRecord
-{
-protected:
- friend class LLQueryResponder;
-
- LLAaaaRecord(const std::string &name, unsigned ttl);
-
- int parse(const char *buf, size_t len, const char *pos, size_t rrlen);
-
-public:
- /**
- * @brief Socket address.
- */
- const sockaddr_in6 &addr_in6() const { return mSA.sin6; }
-};
-
-/**
- * @class LLHostRecord
- * @brief Base class for host-related RRs.
- */
-class LLHostRecord : public LLDnsRecord
-{
-protected:
- LLHostRecord(LLResType type, const std::string &name, unsigned ttl);
-
- int parse(const char *buf, size_t len, const char *pos, size_t rrlen);
-
- std::string mHost;
-
-public:
- /**
- * @brief Host name.
- */
- const std::string &host() const { return mHost; }
-};
-
-/**
- * @class LLCnameRecord
- * @brief CNAME RR.
- */
-class LLCnameRecord : public LLHostRecord
-{
-protected:
- friend class LLQueryResponder;
-
- LLCnameRecord(const std::string &name, unsigned ttl);
-};
-
-/**
- * @class LLPtrRecord
- * @brief PTR RR.
- */
-class LLPtrRecord : public LLHostRecord
-{
-protected:
- friend class LLQueryResponder;
-
- LLPtrRecord(const std::string &name, unsigned ttl);
-};
-
-/**
- * @class LLSrvRecord
- * @brief SRV RR.
- */
-class LLSrvRecord : public LLHostRecord
-{
-protected:
- U16 mPriority;
- U16 mWeight;
- U16 mPort;
-
- int parse(const char *buf, size_t len, const char *pos, size_t rrlen);
-
-public:
- LLSrvRecord(const std::string &name, unsigned ttl);
-
- /**
- * @brief Service priority.
- */
- U16 priority() const { return mPriority; }
-
- /**
- * @brief Service weight.
- */
- U16 weight() const { return mWeight; }
-
- /**
- * @brief Port number of service.
- */
- U16 port() const { return mPort; }
-
- /**
- * @brief Functor for sorting SRV records by priority.
- */
- struct ComparePriorityLowest
- {
- bool operator()(const LLSrvRecord& lhs, const LLSrvRecord& rhs)
- {
- return lhs.mPriority < rhs.mPriority;
- }
- };
-};
-
-/**
- * @class LLNsRecord
- * @brief NS RR.
- */
-class LLNsRecord : public LLHostRecord
-{
-public:
- LLNsRecord(const std::string &name, unsigned ttl);
-};
-
-class LLQueryResponder;
-
-/**
- * @class LLAres
- * @brief Asynchronous address resolver.
- */
-class LLAres
-{
-public:
- /**
- * @class HostResponder
- * @brief Base class for responding to hostname lookups.
- * @see LLAres::getHostByName
- */
- class HostResponder : public LLRefCount
- {
- public:
- virtual ~HostResponder();
-
- virtual void hostResult(const hostent *ent);
- virtual void hostError(int code);
- };
-
- /**
- * @class NameInfoResponder
- * @brief Base class for responding to address lookups.
- * @see LLAres::getNameInfo
- */
- class NameInfoResponder : public LLRefCount
- {
- public:
- virtual ~NameInfoResponder();
-
- virtual void nameInfoResult(const char *node, const char *service);
- virtual void nameInfoError(int code);
- };
-
- /**
- * @class QueryResponder
- * @brief Base class for responding to custom searches.
- * @see LLAres::search
- */
- class QueryResponder : public LLRefCount
- {
- public:
- virtual ~QueryResponder();
-
- virtual void queryResult(const char *buf, size_t len);
- virtual void queryError(int code);
- };
-
- class SrvResponder;
- class UriRewriteResponder;
-
- LLAres();
-
- ~LLAres();
-
- /**
- * Cancel all outstanding requests. The error methods of the
- * corresponding responders will be called, with ARES_ETIMEOUT.
- */
- void cancel();
-
- /**
- * Look up the address of a host.
- *
- * @param name name of host to look up
- * @param resp responder to call with result
- * @param family AF_INET for IPv4 addresses, AF_INET6 for IPv6
- */
- void getHostByName(const std::string &name, HostResponder *resp,
- int family = AF_INET) {
- getHostByName(name.c_str(), resp, family);
- }
-
- /**
- * Look up the address of a host.
- *
- * @param name name of host to look up
- * @param resp responder to call with result
- * @param family AF_INET for IPv4 addresses, AF_INET6 for IPv6
- */
- void getHostByName(const char *name, HostResponder *resp,
- int family = PF_INET);
-
- /**
- * Look up the name associated with a socket address.
- *
- * @param sa socket address to look up
- * @param salen size of socket address
- * @param flags flags to use
- * @param resp responder to call with result
- */
- void getNameInfo(const struct sockaddr &sa, socklen_t salen, int flags,
- NameInfoResponder *resp);
-
- /**
- * Look up SRV (service location) records for a service name.
- *
- * @param name service name (e.g. "_https._tcp.login.agni.lindenlab.com")
- * @param resp responder to call with result
- */
- void getSrvRecords(const std::string &name, SrvResponder *resp);
-
- /**
- * Rewrite a URI, using SRV (service location) records for its
- * protocol if available. If no SRV records are published, the
- * existing URI is handed to the responder.
- *
- * @param uri URI to rewrite
- * @param resp responder to call with result
- */
- void rewriteURI(const std::string &uri,
- UriRewriteResponder *resp);
-
- /**
- * Start a custom search.
- *
- * @param query query to make
- * @param type type of query to perform
- * @param resp responder to call with result
- */
- void search(const std::string &query, LLResType type,
- QueryResponder *resp);
-
- /**
- * Process any outstanding queries. This method takes an optional
- * timeout parameter (specified in microseconds). If provided, it
- * will block the calling thread for that length of time to await
- * possible responses. A timeout of zero will return immediately
- * if there are no responses or timeouts to process.
- *
- * @param timeoutUsecs number of microseconds to block before timing out
- * @return whether any responses were processed
- */
- bool process(U64 timeoutUsecs = 0);
-
- /**
- * Process all outstanding queries, blocking the calling thread
- * until all have either been responded to or timed out.
- *
- * @return whether any responses were processed
- */
- bool processAll();
-
- /**
- * Expand a DNS-encoded compressed string into a normal string.
- *
- * @param encoded the encoded name (null-terminated)
- * @param abuf the response buffer in which the string is embedded
- * @param alen the length of the response buffer
- * @param s the string into which to place the result
- * @return ARES_SUCCESS on success, otherwise an error indicator
- */
- static int expandName(const char *encoded, const char *abuf, size_t alen,
- std::string &s) {
- size_t ignore;
- return expandName(encoded, abuf, alen, s, ignore);
- }
-
- static int expandName(const char *encoded, const char *abuf, size_t alen,
- std::string &s, size_t &enclen);
-
- /**
- * Return a string describing an error code.
- */
- static const char *strerror(int code);
-
- bool isInitialized(void) { return mInitSuccess; }
-
-protected:
- ares_channel chan_;
- bool mInitSuccess;
- // boost::scoped_ptr would actually fit the requirement better, but it
- // can't handle incomplete types as boost::shared_ptr can.
- boost::shared_ptr mListener;
-};
-
-/**
- * An ordered collection of DNS resource records.
- */
-typedef std::vector > dns_rrs_t;
-
-/**
- * @class LLQueryResponder
- * @brief Base class for friendly handling of DNS query responses.
- *
- * This class parses a DNS response and represents it in a friendly
- * manner.
- *
- * @see LLDnsRecord
- * @see LLARecord
- * @see LLNsRecord
- * @see LLCnameRecord
- * @see LLPtrRecord
- * @see LLAaaaRecord
- * @see LLSrvRecord
- */
-class LLQueryResponder : public LLAres::QueryResponder
-{
-protected:
- int mResult;
- std::string mQuery;
- LLResType mType;
-
- dns_rrs_t mAnswers;
- dns_rrs_t mAuthorities;
- dns_rrs_t mAdditional;
-
- /**
- * Parse a single RR.
- */
- int parseRR(const char *buf, size_t len, const char *&pos,
- LLPointer &r);
- /**
- * Parse one section of a response.
- */
- int parseSection(const char *buf, size_t len,
- size_t count, const char *& pos, dns_rrs_t &rrs);
-
- void queryResult(const char *buf, size_t len);
- virtual void querySuccess();
-
-public:
- LLQueryResponder();
-
- /**
- * Indicate whether the response could be parsed successfully.
- */
- bool valid() const { return mResult == ARES_SUCCESS; }
-
- /**
- * The more detailed result of parsing the response.
- */
- int result() const { return mResult; }
-
- /**
- * Return the query embedded in the response.
- */
- const std::string &query() const { return mQuery; }
-
- /**
- * Return the contents of the "answers" section of the response.
- */
- const dns_rrs_t &answers() const { return mAnswers; }
-
- /**
- * Return the contents of the "authorities" section of the
- * response.
- */
- const dns_rrs_t &authorities() const { return mAuthorities; }
-
- /**
- * Return the contents of the "additional records" section of the
- * response.
- */
- const dns_rrs_t &additional() const { return mAdditional; }
-};
-
-/**
- * @class LLAres::SrvResponder
- * @brief Class for handling SRV query responses.
- */
-class LLAres::SrvResponder : public LLQueryResponder
-{
-public:
- friend void LLAres::getSrvRecords(const std::string &name,
- SrvResponder *resp);
- void querySuccess();
- void queryError(int code);
-
- virtual void srvResult(const dns_rrs_t &ents);
- virtual void srvError(int code);
-};
-
-/**
- * @class LLAres::UriRewriteResponder
- * @brief Class for handling URI rewrites based on SRV records.
- */
-class LLAres::UriRewriteResponder : public LLQueryResponder
-{
-protected:
- LLURI mUri;
-
-public:
- friend void LLAres::rewriteURI(const std::string &uri,
- UriRewriteResponder *resp);
- void querySuccess();
- void queryError(int code);
-
- virtual void rewriteResult(const std::vector &uris);
-};
-
-/**
- * Singleton responder.
- */
-extern LLAres *gAres;
-
-/**
- * Set up the singleton responder. It's safe to call this more than
- * once from within a single thread, but this function is not
- * thread safe.
- */
-extern LLAres *ll_init_ares();
-extern void ll_cleanup_ares();
-
-#endif // LL_LLARES_H
diff --git a/indra/llmessage/llareslistener.cpp b/indra/llmessage/llareslistener.cpp
deleted file mode 100755
index 3d65906b98..0000000000
--- a/indra/llmessage/llareslistener.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-/**
- * @file llareslistener.cpp
- * @author Nat Goodspeed
- * @date 2009-03-18
- * @brief Implementation for llareslistener.
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-// Precompiled header
-#include "linden_common.h"
-// associated header
-#include "llareslistener.h"
-// STL headers
-// std headers
-// external library headers
-// other Linden headers
-#include "llares.h"
-#include "llerror.h"
-#include "llevents.h"
-#include "llsdutil.h"
-
-LLAresListener::LLAresListener(LLAres* llares):
- LLEventAPI("LLAres",
- "LLAres listener to request DNS operations"),
- mAres(llares)
-{
- // add() every method we want to be able to invoke via this event API.
- // Optional last parameter validates expected LLSD request structure.
- add("rewriteURI",
- "Given [\"uri\"], return on [\"reply\"] an array of alternative URIs.\n"
- "On failure, returns an array containing only the original URI, so\n"
- "failure case can be processed like success case.",
- &LLAresListener::rewriteURI,
- LLSD().with("uri", LLSD()).with("reply", LLSD()));
-}
-
-/// This UriRewriteResponder subclass packages returned URIs as an LLSD
-/// array to send back to the requester.
-class UriRewriteResponder: public LLAres::UriRewriteResponder
-{
-public:
- /**
- * Specify the request, containing the event pump name on which to send
- * the reply.
- */
- UriRewriteResponder(const LLSD& request):
- mReqID(request),
- mPumpName(request["reply"])
- {}
-
- /// Called by base class with results. This is called in both the
- /// success and error cases. On error, the calling logic passes the
- /// original URI.
- virtual void rewriteResult(const std::vector& uris)
- {
- LLSD result;
- for (std::vector::const_iterator ui(uris.begin()), uend(uris.end());
- ui != uend; ++ui)
- {
- result.append(*ui);
- }
- // This call knows enough to avoid trying to insert a map key into an
- // LLSD array. It's there so that if, for any reason, we ever decide
- // to change the response from array to map, it will Just Start Working.
- mReqID.stamp(result);
- LLEventPumps::instance().obtain(mPumpName).post(result);
- }
-
-private:
- LLReqID mReqID;
- const std::string mPumpName;
-};
-
-void LLAresListener::rewriteURI(const LLSD& data)
-{
- if (mAres)
- {
- mAres->rewriteURI(data["uri"], new UriRewriteResponder(data));
- }
- else
- {
- LL_INFOS() << "LLAresListener::rewriteURI requested without Ares present. Ignoring: " << data << LL_ENDL;
- }
-}
diff --git a/indra/llmessage/llareslistener.h b/indra/llmessage/llareslistener.h
deleted file mode 100755
index 780dcdd9c5..0000000000
--- a/indra/llmessage/llareslistener.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/**
- * @file llareslistener.h
- * @author Nat Goodspeed
- * @date 2009-03-18
- * @brief LLEventPump API for LLAres. This header doesn't actually define the
- * API; the API is defined by the pump name on which this class
- * listens, and by the expected content of LLSD it receives.
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#if ! defined(LL_LLARESLISTENER_H)
-#define LL_LLARESLISTENER_H
-
-#include "lleventapi.h"
-
-class LLAres;
-class LLSD;
-
-/// Listen on an LLEventPump with specified name for LLAres request events.
-class LLAresListener: public LLEventAPI
-{
-public:
- /// Bind the LLAres instance to use (e.g. gAres)
- LLAresListener(LLAres* llares);
-
-private:
- /// command["op"] == "rewriteURI"
- void rewriteURI(const LLSD& data);
-
- LLAres* mAres;
-};
-
-#endif /* ! defined(LL_LLARESLISTENER_H) */
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index ba76341b69..5cf9efa04e 100755
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -57,7 +57,6 @@
#include "llfocusmgr.h"
#include "llviewerjoystick.h"
#include "llallocator.h"
-#include "llares.h"
#include "llcalc.h"
#include "llconversationlog.h"
#include "lldxhardware.h"
@@ -1283,7 +1282,6 @@ static LLTrace::BlockTimerStatHandle FTM_LFS("LFS Thread");
static LLTrace::BlockTimerStatHandle FTM_PAUSE_THREADS("Pause Threads");
static LLTrace::BlockTimerStatHandle FTM_IDLE("Idle");
static LLTrace::BlockTimerStatHandle FTM_PUMP("Pump");
-static LLTrace::BlockTimerStatHandle FTM_PUMP_ARES("Ares");
static LLTrace::BlockTimerStatHandle FTM_PUMP_SERVICE("Service");
static LLTrace::BlockTimerStatHandle FTM_SERVICE_CALLBACK("Callback");
static LLTrace::BlockTimerStatHandle FTM_AGENT_AUTOPILOT("Autopilot");
@@ -1425,26 +1423,6 @@ bool LLAppViewer::mainLoop()
LL_RECORD_BLOCK_TIME(FTM_IDLE);
idle();
- if (gAres != NULL && gAres->isInitialized())
- {
- pingMainloopTimeout("Main:ServicePump");
- LL_RECORD_BLOCK_TIME(FTM_PUMP);
- {
- LL_RECORD_BLOCK_TIME(FTM_PUMP_ARES);
- gAres->process();
- }
- {
- LL_RECORD_BLOCK_TIME(FTM_PUMP_SERVICE);
- // this pump is necessary to make the login screen show up
- gServicePump->pump();
-
- {
- LL_RECORD_BLOCK_TIME(FTM_SERVICE_CALLBACK);
- gServicePump->callback();
- }
- }
- }
-
resumeMainloopTimeout();
}
@@ -2014,9 +1992,6 @@ bool LLAppViewer::cleanup()
// Non-LLCurl libcurl library
mAppCoreHttp.cleanup();
- // NOTE The following call is not thread safe.
- ll_cleanup_ares();
-
LLFilePickerThread::cleanupClass();
//MUST happen AFTER LLCurl::cleanupClass
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 047e23cefc..7616f65a29 100755
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -46,7 +46,6 @@
#include "llaudioengine_openal.h"
#endif
-#include "llares.h"
#include "llavatarnamecache.h"
#include "llexperiencecache.h"
#include "lllandmark.h"
@@ -444,13 +443,6 @@ bool idle_startup()
// Load the throttle settings
gViewerThrottle.load();
- if (ll_init_ares() == NULL || !gAres->isInitialized())
- {
- std::string diagnostic = "Could not start address resolution system";
- LL_WARNS("AppInit") << diagnostic << LL_ENDL;
- LLAppViewer::instance()->earlyExit("LoginFailedNoNetwork", LLSD().with("DIAGNOSTIC", diagnostic));
- }
-
//
// Initialize messaging system
//
diff --git a/indra/viewer_components/login/lllogin.cpp b/indra/viewer_components/login/lllogin.cpp
index ad3d84b8e5..b361bbb276 100755
--- a/indra/viewer_components/login/lllogin.cpp
+++ b/indra/viewer_components/login/lllogin.cpp
@@ -108,7 +108,7 @@ private:
// In a coroutine's top-level function args, do NOT NOT NOT accept
// references (const or otherwise) to anything! Pass by value only!
- void login_(std::string uri, LLSD credentials);
+ void loginCoro(std::string uri, LLSD credentials);
LLEventStream mPump;
LLSD mAuthResponse, mValidAuthResponse;
@@ -122,11 +122,11 @@ void LLLogin::Impl::connect(const std::string& uri, const LLSD& login_params)
// its first wait; at that point, return here.
std::string coroname =
LLCoros::instance().launch("LLLogin::Impl::login_",
- boost::bind(&Impl::login_, this, uri, login_params));
+ boost::bind(&Impl::loginCoro, this, uri, login_params));
LL_DEBUGS("LLLogin") << " connected with uri '" << uri << "', login_params " << login_params << LL_ENDL;
}
-void LLLogin::Impl::login_(std::string uri, LLSD login_params)
+void LLLogin::Impl::loginCoro(std::string uri, LLSD login_params)
{
try
{
@@ -143,43 +143,6 @@ void LLLogin::Impl::login_(std::string uri, LLSD login_params)
LLEventStream replyPump("SRVreply", true);
// Should be an array of one or more uri strings.
- LLSD rewrittenURIs;
- {
- LLEventTimeout filter(replyPump);
- sendProgressEvent("offline", "srvrequest");
-
- // Request SRV record.
- LL_DEBUGS("LLLogin") << "Requesting SRV record from " << uri << LL_ENDL;
-
- // *NOTE:Mani - Completely arbitrary default timeout value for SRV request.
- F32 seconds_to_timeout = 5.0f;
- if(login_params.has("cfg_srv_timeout"))
- {
- seconds_to_timeout = login_params["cfg_srv_timeout"].asReal();
- }
-
- // If the SRV request times out (e.g. EXT-3934), simulate response: an
- // array containing our original URI.
- LLSD fakeResponse(LLSD::emptyArray());
- fakeResponse.append(uri);
- filter.eventAfter(seconds_to_timeout, fakeResponse);
-
- std::string srv_pump_name = "LLAres";
- if(login_params.has("cfg_srv_pump"))
- {
- srv_pump_name = login_params["cfg_srv_pump"].asString();
- }
-
- // Make request
- LLSD request;
- request["op"] = "rewriteURI";
- request["uri"] = uri;
- request["reply"] = replyPump.getName();
- rewrittenURIs = llcoro::postAndSuspend(request, srv_pump_name, filter);
- // EXP-772: If rewrittenURIs fail, try original URI as a fallback.
- rewrittenURIs.append(uri);
- } // we no longer need the filter
-
LLEventPump& xmlrpcPump(LLEventPumps::instance().obtain("LLXMLRPCTransaction"));
// EXT-4193: use a DIFFERENT reply pump than for the SRV request. We used
// to share them -- but the EXT-3934 fix made it possible for an abandoned
@@ -190,107 +153,103 @@ void LLLogin::Impl::login_(std::string uri, LLSD login_params)
// Because of possible redirect responses, we may make more than one
// attempt per rewrittenURIs entry.
LLSD::Integer attempts = 0;
- for (LLSD::array_const_iterator urit(rewrittenURIs.beginArray()),
- urend(rewrittenURIs.endArray());
- urit != urend; ++urit)
+
+ LLSD request(login_params);
+ request["reply"] = loginReplyPump.getName();
+ request["uri"] = uri;
+ std::string status;
+
+ // Loop back to here if login attempt redirects to a different
+ // request["uri"]
+ for (;;)
{
- LLSD request(login_params);
- request["reply"] = loginReplyPump.getName();
- request["uri"] = *urit;
- std::string status;
-
- // Loop back to here if login attempt redirects to a different
- // request["uri"]
- for (;;)
+ ++attempts;
+ LLSD progress_data;
+ progress_data["attempt"] = attempts;
+ progress_data["request"] = request;
+ if(progress_data["request"].has("params")
+ && progress_data["request"]["params"].has("passwd"))
+ {
+ progress_data["request"]["params"]["passwd"] = "*******";
+ }
+ sendProgressEvent("offline", "authenticating", progress_data);
+
+ // We expect zero or more "Downloading" status events, followed by
+ // exactly one event with some other status. Use postAndSuspend() the
+ // first time, because -- at least in unit-test land -- it's
+ // possible for the reply to arrive before the post() call
+ // returns. Subsequent responses, of course, must be awaited
+ // without posting again.
+ for (mAuthResponse = validateResponse(loginReplyPump.getName(),
+ llcoro::postAndSuspend(request, xmlrpcPump, loginReplyPump, "reply"));
+ mAuthResponse["status"].asString() == "Downloading";
+ mAuthResponse = validateResponse(loginReplyPump.getName(),
+ llcoro::suspendUntilEventOn(loginReplyPump)))
{
- ++attempts;
- LLSD progress_data;
- progress_data["attempt"] = attempts;
- progress_data["request"] = request;
- if(progress_data["request"].has("params")
- && progress_data["request"]["params"].has("passwd"))
- {
- progress_data["request"]["params"]["passwd"] = "*******";
- }
- sendProgressEvent("offline", "authenticating", progress_data);
-
- // We expect zero or more "Downloading" status events, followed by
- // exactly one event with some other status. Use postAndSuspend() the
- // first time, because -- at least in unit-test land -- it's
- // possible for the reply to arrive before the post() call
- // returns. Subsequent responses, of course, must be awaited
- // without posting again.
- for (mAuthResponse = validateResponse(loginReplyPump.getName(),
- llcoro::postAndSuspend(request, xmlrpcPump, loginReplyPump, "reply"));
- mAuthResponse["status"].asString() == "Downloading";
- mAuthResponse = validateResponse(loginReplyPump.getName(),
- llcoro::suspendUntilEventOn(loginReplyPump)))
- {
- // Still Downloading -- send progress update.
- sendProgressEvent("offline", "downloading");
- }
+ // Still Downloading -- send progress update.
+ sendProgressEvent("offline", "downloading");
+ }
- LL_DEBUGS("LLLogin") << "Auth Response: " << mAuthResponse << LL_ENDL;
- status = mAuthResponse["status"].asString();
-
- // Okay, we've received our final status event for this
- // request. Unless we got a redirect response, break the retry
- // loop for the current rewrittenURIs entry.
- if (!(status == "Complete" &&
- mAuthResponse["responses"]["login"].asString() == "indeterminate"))
- {
- break;
- }
-
- sendProgressEvent("offline", "indeterminate", mAuthResponse["responses"]);
-
- // Here the login service at the current URI is redirecting us
- // to some other URI ("indeterminate" -- why not "redirect"?).
- // The response should contain another uri to try, with its
- // own auth method.
- request["uri"] = mAuthResponse["responses"]["next_url"].asString();
- request["method"] = mAuthResponse["responses"]["next_method"].asString();
- } // loop back to try the redirected URI
-
- // Here we're done with redirects for the current rewrittenURIs
- // entry.
- if (status == "Complete")
+ LL_DEBUGS("LLLogin") << "Auth Response: " << mAuthResponse << LL_ENDL;
+ status = mAuthResponse["status"].asString();
+
+ // Okay, we've received our final status event for this
+ // request. Unless we got a redirect response, break the retry
+ // loop for the current rewrittenURIs entry.
+ if (!(status == "Complete" &&
+ mAuthResponse["responses"]["login"].asString() == "indeterminate"))
{
- // StatusComplete does not imply auth success. Check the
- // actual outcome of the request. We've already handled the
- // "indeterminate" case in the loop above.
- if (mAuthResponse["responses"]["login"].asString() == "true")
- {
- sendProgressEvent("online", "connect", mAuthResponse["responses"]);
- }
- else
- {
- sendProgressEvent("offline", "fail.login", mAuthResponse["responses"]);
- }
- return; // Done!
+ break;
}
- /* Sometimes we end with "Started" here. Slightly slow server?
- * Seems to be ok to just skip it. Otherwise we'd error out and crash in the if below.
- */
- if( status == "Started")
- {
- LL_DEBUGS("LLLogin") << mAuthResponse << LL_ENDL;
- continue;
- }
+ sendProgressEvent("offline", "indeterminate", mAuthResponse["responses"]);
+
+ // Here the login service at the current URI is redirecting us
+ // to some other URI ("indeterminate" -- why not "redirect"?).
+ // The response should contain another uri to try, with its
+ // own auth method.
+ request["uri"] = mAuthResponse["responses"]["next_url"].asString();
+ request["method"] = mAuthResponse["responses"]["next_method"].asString();
+ } // loop back to try the redirected URI
- // If we don't recognize status at all, trouble
- if (! (status == "CURLError"
- || status == "XMLRPCError"
- || status == "OtherError"))
+ // Here we're done with redirects for the current rewrittenURIs
+ // entry.
+ if (status == "Complete")
+ {
+ // StatusComplete does not imply auth success. Check the
+ // actual outcome of the request. We've already handled the
+ // "indeterminate" case in the loop above.
+ if (mAuthResponse["responses"]["login"].asString() == "true")
{
- LL_ERRS("LLLogin") << "Unexpected status from " << xmlrpcPump.getName() << " pump: "
- << mAuthResponse << LL_ENDL;
- return;
+ sendProgressEvent("online", "connect", mAuthResponse["responses"]);
}
+ else
+ {
+ sendProgressEvent("offline", "fail.login", mAuthResponse["responses"]);
+ }
+ return; // Done!
+ }
+
+// /* Sometimes we end with "Started" here. Slightly slow server?
+// * Seems to be ok to just skip it. Otherwise we'd error out and crash in the if below.
+// */
+// if( status == "Started")
+// {
+// LL_DEBUGS("LLLogin") << mAuthResponse << LL_ENDL;
+// continue;
+// }
+
+ // If we don't recognize status at all, trouble
+ if (! (status == "CURLError"
+ || status == "XMLRPCError"
+ || status == "OtherError"))
+ {
+ LL_ERRS("LLLogin") << "Unexpected status from " << xmlrpcPump.getName() << " pump: "
+ << mAuthResponse << LL_ENDL;
+ return;
+ }
- // Here status IS one of the errors tested above.
- } // Retry if there are any more rewrittenURIs.
+ // Here status IS one of the errors tested above.
// Here we got through all the rewrittenURIs without succeeding. Tell
// caller this didn't work out so well. Of course, the only failure data
diff --git a/indra/viewer_components/login/tests/lllogin_test.cpp b/indra/viewer_components/login/tests/lllogin_test.cpp
index 58bf371a04..e96c495446 100755
--- a/indra/viewer_components/login/tests/lllogin_test.cpp
+++ b/indra/viewer_components/login/tests/lllogin_test.cpp
@@ -96,61 +96,6 @@ public:
}
};
-class LLAresListener: public LLEventTrackable
-{
- std::string mName;
- LLSD mEvent;
- bool mImmediateResponse;
- bool mMultipleURIResponse;
- Debug mDebug;
-
-public:
- LLAresListener(const std::string& name,
- bool i = false,
- bool m = false
- ) :
- mName(name),
- mImmediateResponse(i),
- mMultipleURIResponse(m),
- mDebug(stringize(*this))
- {}
-
- bool handle_event(const LLSD& event)
- {
- mDebug(STRINGIZE("LLAresListener called!: " << event));
- mEvent = event;
- if(mImmediateResponse)
- {
- sendReply();
- }
- return false;
- }
-
- void sendReply()
- {
- if(mEvent["op"].asString() == "rewriteURI")
- {
- LLSD result;
- if(mMultipleURIResponse)
- {
- result.append(LLSD("login.foo.com"));
- }
- result.append(mEvent["uri"]);
- LLEventPumps::instance().obtain(mEvent["reply"]).post(result);
- }
- }
-
- LLBoundListener listenTo(LLEventPump& pump)
- {
- return pump.listen(mName, boost::bind(&LLAresListener::handle_event, this, _1));
- }
-
- friend std::ostream& operator<<(std::ostream& out, const LLAresListener& listener)
- {
- return out << "LLAresListener(" << listener.mName << ')';
- }
-};
-
class LLXMLRPCListener: public LLEventTrackable
{
std::string mName;
@@ -232,16 +177,12 @@ namespace tut
void llviewerlogin_object::test<1>()
{
DEBUG;
- // Testing login with immediate responses from Ares and XMLPRC
- // The response from both requests will come before the post request exits.
+ // Testing login with an immediate response from XMLPRC
+ // The response will come before the post request exits.
// This tests an edge case of the login state handling.
- LLEventStream llaresPump("LLAres"); // Dummy LLAres pump.
LLEventStream xmlrpcPump("LLXMLRPCTransaction"); // Dummy XMLRPC pump
bool respond_immediately = true;
- // Have 'dummy ares' respond immediately.
- LLAresListener dummyLLAres("dummy_llares", respond_immediately);
- dummyLLAres.listenTo(llaresPump);
// Have dummy XMLRPC respond immediately.
LLXMLRPCListener dummyXMLRPC("dummy_xmlrpc", respond_immediately);
@@ -264,111 +205,14 @@ namespace tut
template<> template<>
void llviewerlogin_object::test<2>()
- {
- DEBUG;
- // Tests a successful login in with delayed responses.
- // Also includes 'failure' that cause the login module
- // to re-attempt connection, once from a basic failure
- // and once from the 'indeterminate' response.
-
- set_test_name("LLLogin multiple srv uris w/ success");
-
- // Testing normal login procedure.
- LLEventStream llaresPump("LLAres"); // Dummy LLAres pump.
- LLEventStream xmlrpcPump("LLXMLRPCTransaction"); // Dummy XMLRPC pump
-
- bool respond_immediately = false;
- bool multiple_addresses = true;
- LLAresListener dummyLLAres("dummy_llares", respond_immediately, multiple_addresses);
- dummyLLAres.listenTo(llaresPump);
-
- LLXMLRPCListener dummyXMLRPC("dummy_xmlrpc");
- dummyXMLRPC.listenTo(xmlrpcPump);
-
- LLLogin login;
-
- LoginListener listener("test_ear");
- listener.listenTo(login.getEventPump());
-
- LLSD credentials;
- credentials["first"] = "foo";
- credentials["last"] = "bar";
- credentials["passwd"] = "secret";
-
- login.connect("login.bar.com", credentials);
-
- ensure_equals("SRV state", listener.lastEvent()["change"].asString(), "srvrequest");
-
- dummyLLAres.sendReply();
-
- // Test Authenticating State prior to first response.
- ensure_equals("Auth state 1", listener.lastEvent()["change"].asString(), "authenticating");
- ensure_equals("Attempt 1", listener.lastEvent()["data"]["attempt"].asInteger(), 1);
- ensure_equals("URI 1", listener.lastEvent()["data"]["request"]["uri"].asString(), "login.foo.com");
-
- // First send emulated LLXMLRPCListener failure,
- // this should return login to the authenticating step and increase the attempt
- // count.
- LLSD data;
- data["status"] = "OtherError";
- data["errorcode"] = 0;
- data["error"] = "dummy response";
- data["transfer_rate"] = 0;
- dummyXMLRPC.setResponse(data);
- dummyXMLRPC.sendReply();
-
- ensure_equals("Fail back to authenticate 1", listener.lastEvent()["change"].asString(), "authenticating");
- ensure_equals("Attempt 2", listener.lastEvent()["data"]["attempt"].asInteger(), 2);
- ensure_equals("URI 2", listener.lastEvent()["data"]["request"]["uri"].asString(), "login.bar.com");
-
- // Now send the 'indeterminate' response.
- data.clear();
- data["status"] = "Complete"; // StatusComplete
- data["errorcode"] = 0;
- data["error"] = "dummy response";
- data["transfer_rate"] = 0;
- data["responses"]["login"] = "indeterminate";
- data["responses"]["next_url"] = "login.indeterminate.com";
- data["responses"]["next_method"] = "test_login_method";
- dummyXMLRPC.setResponse(data);
- dummyXMLRPC.sendReply();
-
- ensure_equals("Fail back to authenticate 2", listener.lastEvent()["change"].asString(), "authenticating");
- ensure_equals("Attempt 3", listener.lastEvent()["data"]["attempt"].asInteger(), 3);
- ensure_equals("URI 3", listener.lastEvent()["data"]["request"]["uri"].asString(), "login.indeterminate.com");
- ensure_equals("Method 3", listener.lastEvent()["data"]["request"]["method"].asString(), "test_login_method");
-
- // Finally let the auth succeed.
- data.clear();
- data["status"] = "Complete"; // StatusComplete
- data["errorcode"] = 0;
- data["error"] = "dummy response";
- data["transfer_rate"] = 0;
- data["responses"]["login"] = "true";
- dummyXMLRPC.setResponse(data);
- dummyXMLRPC.sendReply();
-
- ensure_equals("Success state", listener.lastEvent()["state"].asString(), "online");
-
- login.disconnect();
-
- ensure_equals("Disconnected state", listener.lastEvent()["state"].asString(), "offline");
- }
-
- template<> template<>
- void llviewerlogin_object::test<3>()
{
DEBUG;
// Test completed response, that fails to login.
set_test_name("LLLogin valid response, failure (eg. bad credentials)");
// Testing normal login procedure.
- LLEventStream llaresPump("LLAres"); // Dummy LLAres pump.
LLEventStream xmlrpcPump("LLXMLRPCTransaction"); // Dummy XMLRPC pump
- LLAresListener dummyLLAres("dummy_llares");
- dummyLLAres.listenTo(llaresPump);
-
LLXMLRPCListener dummyXMLRPC("dummy_xmlrpc");
dummyXMLRPC.listenTo(xmlrpcPump);
@@ -383,10 +227,6 @@ namespace tut
login.connect("login.bar.com", credentials);
- ensure_equals("SRV state", listener.lastEvent()["change"].asString(), "srvrequest");
-
- dummyLLAres.sendReply();
-
ensure_equals("Auth state", listener.lastEvent()["change"].asString(), "authenticating");
// Send the failed auth request reponse
@@ -403,19 +243,15 @@ namespace tut
}
template<> template<>
- void llviewerlogin_object::test<4>()
+ void llviewerlogin_object::test<3>()
{
DEBUG;
// Test incomplete response, that end the attempt.
set_test_name("LLLogin valid response, failure (eg. bad credentials)");
// Testing normal login procedure.
- LLEventStream llaresPump("LLAres"); // Dummy LLAres pump.
LLEventStream xmlrpcPump("LLXMLRPCTransaction"); // Dummy XMLRPC pump
- LLAresListener dummyLLAres("dummy_llares");
- dummyLLAres.listenTo(llaresPump);
-
LLXMLRPCListener dummyXMLRPC("dummy_xmlrpc");
dummyXMLRPC.listenTo(xmlrpcPump);
@@ -430,10 +266,6 @@ namespace tut
login.connect("login.bar.com", credentials);
- ensure_equals("SRV state", listener.lastEvent()["change"].asString(), "srvrequest");
-
- dummyLLAres.sendReply();
-
ensure_equals("Auth state", listener.lastEvent()["change"].asString(), "authenticating");
// Send the failed auth request reponse
@@ -449,17 +281,13 @@ namespace tut
}
template<> template<>
- void llviewerlogin_object::test<5>()
+ void llviewerlogin_object::test<4>()
{
DEBUG;
// Test SRV request timeout.
set_test_name("LLLogin SRV timeout testing");
// Testing normal login procedure.
- LLEventStream llaresPump("LLAres"); // Dummy LLAres pump.
-
- LLAresListener dummyLLAres("dummy_llares");
- dummyLLAres.listenTo(llaresPump);
LLLogin login;
LoginListener listener("test_ear");
@@ -473,26 +301,15 @@ namespace tut
login.connect("login.bar.com", credentials);
- ensure_equals("SRV State", listener.lastEvent()["change"].asString(), "srvrequest");
-
// Get the mainloop eventpump, which needs a pinging in order to drive the
// SRV timeout.
LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop"));
LLSD frame_event;
mainloop.post(frame_event);
- // In this state we have NOT sent a reply from LLAresListener -- in
- // fact there's no such object. Nonetheless, we expect the timeout to
- // have stepped the login module forward to try to authenticate with
- // the original URI.
ensure_equals("Auth state", listener.lastEvent()["change"].asString(), "authenticating");
ensure_equals("Attempt", listener.lastEvent()["data"]["attempt"].asInteger(), 1);
ensure_equals("URI", listener.lastEvent()["data"]["request"]["uri"].asString(), "login.bar.com");
- // EXT-4193: if the SRV reply isn't lost but merely late, and if it
- // arrives just at the moment we're expecting the XMLRPC reply, the
- // original code got confused and crashed. Drive that case here. We
- // observe that without the fix, this call DOES repro.
- dummyLLAres.sendReply();
}
}
--
cgit v1.3
From 29596be514d361c71273629677bcb4c7052a6036 Mon Sep 17 00:00:00 2001
From: Rider Linden
Date: Tue, 22 Sep 2015 13:01:30 -0700
Subject: Test disabling a couple of the display_startup() calls as an
experiment.
---
indra/newview/llstartup.cpp | 4 ++--
indra/viewer_components/login/lllogin.cpp | 25 ++-----------------------
2 files changed, 4 insertions(+), 25 deletions(-)
(limited to 'indra/newview/llstartup.cpp')
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 7616f65a29..60d67be9ef 100755
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -752,10 +752,10 @@ bool idle_startup()
// Make sure the process dialog doesn't hide things
display_startup();
gViewerWindow->setShowProgress(FALSE);
- display_startup();
+// display_startup();
// Show the login dialog
login_show();
- display_startup();
+// display_startup();
// connect dialog is already shown, so fill in the names
if (gUserCredential.notNull())
{
diff --git a/indra/viewer_components/login/lllogin.cpp b/indra/viewer_components/login/lllogin.cpp
index b361bbb276..53d4acc9e0 100755
--- a/indra/viewer_components/login/lllogin.cpp
+++ b/indra/viewer_components/login/lllogin.cpp
@@ -310,29 +310,8 @@ LLEventPump& LLLogin::getEventPump()
// The list associates to event with the original idle_startup() 'STATE'.
-// Rewrite URIs
- // State_LOGIN_AUTH_INIT
-// Given a vector of login uris (usually just one), perform a dns lookup for the
-// SRV record from each URI. I think this is used to distribute login requests to
-// a single URI to multiple hosts.
-// This is currently a synchronous action. (See LLSRV::rewriteURI() implementation)
-// On dns lookup error the output uris == the input uris.
-//
-// Input: A vector of login uris
-// Output: A vector of login uris
-//
-// Code:
-// std::vector uris;
-// LLViewerLogin::getInstance()->getLoginURIs(uris);
-// std::vector::const_iterator iter, end;
-// for (iter = uris.begin(), end = uris.end(); iter != end; ++iter)
-// {
-// std::vector rewritten;
-// rewritten = LLSRV::rewriteURI(*iter);
-// sAuthUris.insert(sAuthUris.end(),
-// rewritten.begin(), rewritten.end());
-// }
-// sAuthUriNum = 0;
+// Setup login
+// State_LOGIN_AUTH_INIT
// Authenticate
// STATE_LOGIN_AUTHENTICATE
--
cgit v1.3
From a01ad64c3e701de0586043aebf3229c5f5a4916a Mon Sep 17 00:00:00 2001
From: Rider Linden
Date: Tue, 22 Sep 2015 14:47:42 -0700
Subject: replace the display_startup() removal that didn't work. Try backing
up a step in the signon processing.
---
indra/newview/llstartup.cpp | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
(limited to 'indra/newview/llstartup.cpp')
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 60d67be9ef..b0ea00e6e4 100755
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -752,10 +752,10 @@ bool idle_startup()
// Make sure the process dialog doesn't hide things
display_startup();
gViewerWindow->setShowProgress(FALSE);
-// display_startup();
+ display_startup();
// Show the login dialog
login_show();
-// display_startup();
+ display_startup();
// connect dialog is already shown, so fill in the names
if (gUserCredential.notNull())
{
@@ -2751,8 +2751,6 @@ void reset_login()
gAgent.cleanup();
LLWorld::getInstance()->destroyClass();
- LLStartUp::setStartupState( STATE_LOGIN_SHOW );
-
if ( gViewerWindow )
{ // Hide menus and normal buttons
gViewerWindow->setNormalControlsVisible( FALSE );
@@ -2762,6 +2760,7 @@ void reset_login()
// Hide any other stuff
LLFloaterReg::hideVisibleInstances();
+ LLStartUp::setStartupState( STATE_BROWSER_INIT );
}
//---------------------------------------------------------------------------
--
cgit v1.3
From 245677e941d47963b67d36deffd03535dfc3df3f Mon Sep 17 00:00:00 2001
From: Rider Linden
Date: Thu, 24 Sep 2015 11:19:20 -0700
Subject: MAINT-5614: There are an obscene number of calls to
"display_startup()" in the show login state. Try removing some of them.
---
indra/newview/llstartup.cpp | 37 +++++++++++++++++++------------------
1 file changed, 19 insertions(+), 18 deletions(-)
(limited to 'indra/newview/llstartup.cpp')
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index b0ea00e6e4..ff8b79bc7c 100755
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -728,12 +728,12 @@ bool idle_startup()
if (gLoginMenuBarView == NULL)
{
LL_DEBUGS("AppInit") << "initializing menu bar" << LL_ENDL;
- display_startup();
+// display_startup();
initialize_edit_menu();
initialize_spellcheck_menu();
- display_startup();
+// display_startup();
init_menus();
- display_startup();
+// display_startup();
}
if (show_connect_box)
@@ -745,23 +745,23 @@ bool idle_startup()
if (gUserCredential.isNull())
{
LL_DEBUGS("AppInit") << "loading credentials from gLoginHandler" << LL_ENDL;
- display_startup();
+// display_startup();
gUserCredential = gLoginHandler.initializeLoginInfo();
- display_startup();
+// display_startup();
}
// Make sure the process dialog doesn't hide things
- display_startup();
+// display_startup();
gViewerWindow->setShowProgress(FALSE);
- display_startup();
+// display_startup();
// Show the login dialog
login_show();
- display_startup();
+// display_startup();
// connect dialog is already shown, so fill in the names
if (gUserCredential.notNull())
{
LLPanelLogin::setFields( gUserCredential, gRememberPassword);
}
- display_startup();
+// display_startup();
LLPanelLogin::giveFocus();
// MAINT-3231 Show first run dialog only for Desura viewer
@@ -787,22 +787,22 @@ bool idle_startup()
LLStartUp::setStartupState( STATE_LOGIN_CLEANUP );
}
- display_startup();
+// display_startup();
gViewerWindow->setNormalControlsVisible( FALSE );
- display_startup();
+// display_startup();
gLoginMenuBarView->setVisible( TRUE );
- display_startup();
+// display_startup();
gLoginMenuBarView->setEnabled( TRUE );
- display_startup();
+// display_startup();
show_debug_menus();
- display_startup();
+// display_startup();
// Hide the splash screen
LLSplashScreen::hide();
- display_startup();
+// display_startup();
// Push our window frontmost
gViewerWindow->getWindow()->show();
- display_startup();
+// display_startup();
// DEV-16927. The following code removes errant keystrokes that happen while the window is being
// first made visible.
@@ -810,9 +810,10 @@ bool idle_startup()
MSG msg;
while( PeekMessage( &msg, /*All hWnds owned by this thread */ NULL, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE ) )
{ }
- display_startup();
+// display_startup();
#endif
- timeout.reset();
+ display_startup();
+ timeout.reset();
return FALSE;
}
--
cgit v1.3
From 4334fd27e2215c1bfad3aa7ab7130b8c6b289de5 Mon Sep 17 00:00:00 2001
From: Rider Linden
Date: Tue, 29 Sep 2015 16:05:09 -0700
Subject: Just remove the display_startup() calls.
---
indra/newview/llstartup.cpp | 17 -----------------
1 file changed, 17 deletions(-)
(limited to 'indra/newview/llstartup.cpp')
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index ff8b79bc7c..2c6b9d14bf 100755
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -728,12 +728,9 @@ bool idle_startup()
if (gLoginMenuBarView == NULL)
{
LL_DEBUGS("AppInit") << "initializing menu bar" << LL_ENDL;
-// display_startup();
initialize_edit_menu();
initialize_spellcheck_menu();
-// display_startup();
init_menus();
-// display_startup();
}
if (show_connect_box)
@@ -745,23 +742,17 @@ bool idle_startup()
if (gUserCredential.isNull())
{
LL_DEBUGS("AppInit") << "loading credentials from gLoginHandler" << LL_ENDL;
-// display_startup();
gUserCredential = gLoginHandler.initializeLoginInfo();
-// display_startup();
}
// Make sure the process dialog doesn't hide things
-// display_startup();
gViewerWindow->setShowProgress(FALSE);
-// display_startup();
// Show the login dialog
login_show();
-// display_startup();
// connect dialog is already shown, so fill in the names
if (gUserCredential.notNull())
{
LLPanelLogin::setFields( gUserCredential, gRememberPassword);
}
-// display_startup();
LLPanelLogin::giveFocus();
// MAINT-3231 Show first run dialog only for Desura viewer
@@ -787,22 +778,15 @@ bool idle_startup()
LLStartUp::setStartupState( STATE_LOGIN_CLEANUP );
}
-// display_startup();
gViewerWindow->setNormalControlsVisible( FALSE );
-// display_startup();
gLoginMenuBarView->setVisible( TRUE );
-// display_startup();
gLoginMenuBarView->setEnabled( TRUE );
-// display_startup();
show_debug_menus();
-// display_startup();
// Hide the splash screen
LLSplashScreen::hide();
-// display_startup();
// Push our window frontmost
gViewerWindow->getWindow()->show();
-// display_startup();
// DEV-16927. The following code removes errant keystrokes that happen while the window is being
// first made visible.
@@ -810,7 +794,6 @@ bool idle_startup()
MSG msg;
while( PeekMessage( &msg, /*All hWnds owned by this thread */ NULL, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE ) )
{ }
-// display_startup();
#endif
display_startup();
timeout.reset();
--
cgit v1.3