summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorRider Linden <none@none>2015-04-15 11:51:48 -0700
committerRider Linden <none@none>2015-04-15 11:51:48 -0700
commit176d8cd268611e28c07a462df3027f4872456e5a (patch)
tree0c66aad1e606ecb7c656561a84bff3da304756a6 /indra/newview
parentb8805c8964d45ee9141bcc131473bc4e663e93bf (diff)
Region caps and sim features converted to coroutine.
Diffstat (limited to 'indra/newview')
-rwxr-xr-xindra/newview/llagent.cpp2
-rwxr-xr-xindra/newview/llappearancemgr.cpp193
-rwxr-xr-xindra/newview/llviewerregion.cpp569
-rwxr-xr-xindra/newview/llviewerregion.h3
4 files changed, 399 insertions, 368 deletions
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index eeedda5c6d..7f38e4b79f 100755
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -2788,6 +2788,8 @@ void LLAgent::sendMaturityPreferenceToServer(U8 pPreferredMaturity)
}
}
+// *TODO:RIDER Convert this system to using the coroutine scheme for HTTP communications
+//
LLCore::HttpHandle LLAgent::requestPostCapability(const std::string &cap, const std::string &url, LLSD &postData, LLHttpSDHandler *usrhndlr)
{
LLHttpSDHandler * handler = (usrhndlr) ? usrhndlr : new LLHttpSDGenericHandler(cap);
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 4fbcd90baa..42c8c0fb1c 100755
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -1246,6 +1246,38 @@ static void removeDuplicateItems(LLInventoryModel::item_array_t& items)
}
//=========================================================================
+#if 0
+// *TODO:
+class LLAppearanceMgrHttpHandler
+{
+public:
+
+ static void apperanceMgrRequestCoro(LLCoros::self& self, std::string url);
+
+private:
+ LLAppearanceMgrHttpHandler();
+
+ static void debugCOF(const LLSD& content);
+
+
+};
+
+void LLAppearanceMgrHttpHandler::apperanceMgrRequestCoro(LLCoros::self& self, std::string url)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("EnvironmentRequest", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+
+
+}
+
+#else
+
+// *TODO: Convert this and llavatar over to using the coroutine scheme rather
+// than the responder for communications. (see block above for start...)
+
class LLAppearanceMgrHttpHandler : public LLHttpSDHandler
{
public:
@@ -1319,89 +1351,90 @@ void LLAppearanceMgrHttpHandler::onFailure(LLCore::HttpResponse * response, LLCo
<< status.toString() << LL_ENDL;
}
+#endif
+
void LLAppearanceMgrHttpHandler::debugCOF(const LLSD& content)
{
- dump_sequential_xml(gAgentAvatarp->getFullname() + "_appearance_request_error", content);
-
- LL_INFOS("Avatar") << "AIS COF, version received: " << content["expected"].asInteger()
- << " ================================= " << LL_ENDL;
- std::set<LLUUID> ais_items, local_items;
- const LLSD& cof_raw = content["cof_raw"];
- for (LLSD::array_const_iterator it = cof_raw.beginArray();
- it != cof_raw.endArray(); ++it)
- {
- const LLSD& item = *it;
- if (item["parent_id"].asUUID() == LLAppearanceMgr::instance().getCOF())
- {
- ais_items.insert(item["item_id"].asUUID());
- if (item["type"].asInteger() == 24) // link
- {
- LL_INFOS("Avatar") << "AIS Link: item_id: " << item["item_id"].asUUID()
- << " linked_item_id: " << item["asset_id"].asUUID()
- << " name: " << item["name"].asString()
- << LL_ENDL;
- }
- else if (item["type"].asInteger() == 25) // folder link
- {
- LL_INFOS("Avatar") << "AIS Folder link: item_id: " << item["item_id"].asUUID()
- << " linked_item_id: " << item["asset_id"].asUUID()
- << " name: " << item["name"].asString()
- << LL_ENDL;
- }
- else
- {
- LL_INFOS("Avatar") << "AIS Other: item_id: " << item["item_id"].asUUID()
- << " linked_item_id: " << item["asset_id"].asUUID()
- << " name: " << item["name"].asString()
- << " type: " << item["type"].asInteger()
- << LL_ENDL;
- }
- }
- }
- LL_INFOS("Avatar") << LL_ENDL;
- LL_INFOS("Avatar") << "Local COF, version requested: " << content["observed"].asInteger()
- << " ================================= " << LL_ENDL;
- LLInventoryModel::cat_array_t cat_array;
- LLInventoryModel::item_array_t item_array;
- gInventory.collectDescendents(LLAppearanceMgr::instance().getCOF(),
- cat_array, item_array, LLInventoryModel::EXCLUDE_TRASH);
- for (S32 i = 0; i < item_array.size(); i++)
- {
- const LLViewerInventoryItem* inv_item = item_array.at(i).get();
- local_items.insert(inv_item->getUUID());
- LL_INFOS("Avatar") << "LOCAL: item_id: " << inv_item->getUUID()
- << " linked_item_id: " << inv_item->getLinkedUUID()
- << " name: " << inv_item->getName()
- << " parent: " << inv_item->getParentUUID()
- << LL_ENDL;
- }
- LL_INFOS("Avatar") << " ================================= " << LL_ENDL;
- S32 local_only = 0, ais_only = 0;
- for (std::set<LLUUID>::iterator it = local_items.begin(); it != local_items.end(); ++it)
- {
- if (ais_items.find(*it) == ais_items.end())
- {
- LL_INFOS("Avatar") << "LOCAL ONLY: " << *it << LL_ENDL;
- local_only++;
- }
- }
- for (std::set<LLUUID>::iterator it = ais_items.begin(); it != ais_items.end(); ++it)
- {
- if (local_items.find(*it) == local_items.end())
- {
- LL_INFOS("Avatar") << "AIS ONLY: " << *it << LL_ENDL;
- ais_only++;
- }
- }
- if (local_only == 0 && ais_only == 0)
- {
- LL_INFOS("Avatar") << "COF contents identical, only version numbers differ (req "
- << content["observed"].asInteger()
- << " rcv " << content["expected"].asInteger()
- << ")" << LL_ENDL;
- }
+ dump_sequential_xml(gAgentAvatarp->getFullname() + "_appearance_request_error", content);
+
+ LL_INFOS("Avatar") << "AIS COF, version received: " << content["expected"].asInteger()
+ << " ================================= " << LL_ENDL;
+ std::set<LLUUID> ais_items, local_items;
+ const LLSD& cof_raw = content["cof_raw"];
+ for (LLSD::array_const_iterator it = cof_raw.beginArray();
+ it != cof_raw.endArray(); ++it)
+ {
+ const LLSD& item = *it;
+ if (item["parent_id"].asUUID() == LLAppearanceMgr::instance().getCOF())
+ {
+ ais_items.insert(item["item_id"].asUUID());
+ if (item["type"].asInteger() == 24) // link
+ {
+ LL_INFOS("Avatar") << "AIS Link: item_id: " << item["item_id"].asUUID()
+ << " linked_item_id: " << item["asset_id"].asUUID()
+ << " name: " << item["name"].asString()
+ << LL_ENDL;
+ }
+ else if (item["type"].asInteger() == 25) // folder link
+ {
+ LL_INFOS("Avatar") << "AIS Folder link: item_id: " << item["item_id"].asUUID()
+ << " linked_item_id: " << item["asset_id"].asUUID()
+ << " name: " << item["name"].asString()
+ << LL_ENDL;
+ }
+ else
+ {
+ LL_INFOS("Avatar") << "AIS Other: item_id: " << item["item_id"].asUUID()
+ << " linked_item_id: " << item["asset_id"].asUUID()
+ << " name: " << item["name"].asString()
+ << " type: " << item["type"].asInteger()
+ << LL_ENDL;
+ }
+ }
+ }
+ LL_INFOS("Avatar") << LL_ENDL;
+ LL_INFOS("Avatar") << "Local COF, version requested: " << content["observed"].asInteger()
+ << " ================================= " << LL_ENDL;
+ LLInventoryModel::cat_array_t cat_array;
+ LLInventoryModel::item_array_t item_array;
+ gInventory.collectDescendents(LLAppearanceMgr::instance().getCOF(),
+ cat_array, item_array, LLInventoryModel::EXCLUDE_TRASH);
+ for (S32 i = 0; i < item_array.size(); i++)
+ {
+ const LLViewerInventoryItem* inv_item = item_array.at(i).get();
+ local_items.insert(inv_item->getUUID());
+ LL_INFOS("Avatar") << "LOCAL: item_id: " << inv_item->getUUID()
+ << " linked_item_id: " << inv_item->getLinkedUUID()
+ << " name: " << inv_item->getName()
+ << " parent: " << inv_item->getParentUUID()
+ << LL_ENDL;
+ }
+ LL_INFOS("Avatar") << " ================================= " << LL_ENDL;
+ S32 local_only = 0, ais_only = 0;
+ for (std::set<LLUUID>::iterator it = local_items.begin(); it != local_items.end(); ++it)
+ {
+ if (ais_items.find(*it) == ais_items.end())
+ {
+ LL_INFOS("Avatar") << "LOCAL ONLY: " << *it << LL_ENDL;
+ local_only++;
+ }
+ }
+ for (std::set<LLUUID>::iterator it = ais_items.begin(); it != ais_items.end(); ++it)
+ {
+ if (local_items.find(*it) == local_items.end())
+ {
+ LL_INFOS("Avatar") << "AIS ONLY: " << *it << LL_ENDL;
+ ais_only++;
+ }
+ }
+ if (local_only == 0 && ais_only == 0)
+ {
+ LL_INFOS("Avatar") << "COF contents identical, only version numbers differ (req "
+ << content["observed"].asInteger()
+ << " rcv " << content["expected"].asInteger()
+ << ")" << LL_ENDL;
+ }
}
-
//=========================================================================
const LLUUID LLAppearanceMgr::getCOF() const
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 4bfea81182..bebbf4ea56 100755
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -78,6 +78,9 @@
#include "llviewerdisplay.h"
#include "llviewerwindow.h"
#include "llprogressview.h"
+#include "llcoros.h"
+#include "lleventcoro.h"
+#include "llcorehttputil.h"
#ifdef LL_WINDOWS
#pragma warning(disable:4355)
@@ -105,7 +108,8 @@ typedef std::map<std::string, std::string> CapabilityMap;
static void log_capabilities(const CapabilityMap &capmap);
-class LLViewerRegionImpl {
+class LLViewerRegionImpl
+{
public:
LLViewerRegionImpl(LLViewerRegion * region, LLHost const & host)
: mHost(host),
@@ -189,212 +193,281 @@ public:
//spatial partitions for objects in this region
std::vector<LLViewerOctreePartition*> mObjectPartition;
- LLVector3 mLastCameraOrigin;
- U32 mLastCameraUpdate;
-};
-
-// support for secondlife:///app/region/{REGION} SLapps
-// N.B. this is defined to work exactly like the classic secondlife://{REGION}
-// However, the later syntax cannot support spaces in the region name because
-// spaces (and %20 chars) are illegal in the hostname of an http URL. Some
-// browsers let you get away with this, but some do not (such as Qt's Webkit).
-// Hence we introduced the newer secondlife:///app/region alternative.
-class LLRegionHandler : public LLCommandHandler
-{
-public:
- // requests will be throttled from a non-trusted browser
- LLRegionHandler() : LLCommandHandler("region", UNTRUSTED_THROTTLE) {}
-
- bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
- {
- // make sure that we at least have a region name
- int num_params = params.size();
- if (num_params < 1)
- {
- return false;
- }
+ LLVector3 mLastCameraOrigin;
+ U32 mLastCameraUpdate;
- // build a secondlife://{PLACE} SLurl from this SLapp
- std::string url = "secondlife://";
- for (int i = 0; i < num_params; i++)
- {
- if (i > 0)
- {
- url += "/";
- }
- url += params[i].asString();
- }
-
- // Process the SLapp as if it was a secondlife://{PLACE} SLurl
- LLURLDispatcher::dispatch(url, "clicked", web, true);
- return true;
- }
+ void requestBaseCapabilitiesCoro(LLCoros::self& self, U64 regionHandle);
+ void requestBaseCapabilitiesCompleteCoro(LLCoros::self& self, U64 regionHandle);
+ void requestSimulatorFeatureCoro(LLCoros::self& self, std::string url, U64 regionHandle);
};
-LLRegionHandler gRegionHandler;
-class BaseCapabilitiesComplete : public LLHTTPClient::Responder
+void LLViewerRegionImpl::requestBaseCapabilitiesCoro(LLCoros::self& self, U64 regionHandle)
{
- LOG_CLASS(BaseCapabilitiesComplete);
-public:
- BaseCapabilitiesComplete(U64 region_handle, S32 id)
- : mRegionHandle(region_handle), mID(id)
- { }
- virtual ~BaseCapabilitiesComplete()
- { }
-
- static BaseCapabilitiesComplete* build( U64 region_handle, S32 id )
- {
- return new BaseCapabilitiesComplete(region_handle, id);
- }
-
-private:
- /* virtual */void httpFailure()
- {
- LL_WARNS("AppInit", "Capabilities") << dumpResponse() << LL_ENDL;
- LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
- if (regionp)
- {
- regionp->failedSeedCapability();
- }
- }
-
- /* virtual */ void httpSuccess()
- {
- LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
- if(!regionp) //region was removed
- {
- LL_WARNS("AppInit", "Capabilities") << "Received results for region that no longer exists!" << LL_ENDL;
- return ;
- }
- if( mID != regionp->getHttpResponderID() ) // region is no longer referring to this responder
- {
- LL_WARNS("AppInit", "Capabilities") << "Received results for a stale http responder!" << LL_ENDL;
- regionp->failedSeedCapability();
- return ;
- }
-
- const LLSD& content = getContent();
- if (!content.isMap())
- {
- failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
- return;
- }
- LLSD::map_const_iterator iter;
- for(iter = content.beginMap(); iter != content.endMap(); ++iter)
- {
- regionp->setCapability(iter->first, iter->second);
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("BaseCapabilitiesRequest", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- LL_DEBUGS("AppInit", "Capabilities")
- << "Capability '" << iter->first << "' is '" << iter->second << "'" << LL_ENDL;
+ LLSD result;
+ LLViewerRegion *regionp = NULL;
- /* HACK we're waiting for the ServerReleaseNotes */
- if (iter->first == "ServerReleaseNotes" && regionp->getReleaseNotesRequested())
- {
- regionp->showReleaseNotes();
- }
- }
-
- regionp->setCapabilitiesReceived(true);
+ // This loop is used for retrying a capabilities request.
+ do
+ {
+ regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
+ if (!regionp) //region was removed
+ {
+ LL_WARNS("AppInit", "Capabilities") << "Attempting to get capabilities for region that no longer exists!" << LL_ENDL;
+ return; // this error condition is not recoverable.
+ }
+
+ std::string url = regionp->getCapability("Seed");
+ if (url.empty())
+ {
+ LL_WARNS("AppInit", "Capabilities") << "Failed to get seed capabilities, and can not determine url!" << LL_ENDL;
+ return; // this error condition is not recoverable.
+ }
+
+ // After a few attempts, continue login. But keep trying to get the caps:
+ if (mSeedCapAttempts >= mSeedCapMaxAttemptsBeforeLogin &&
+ STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState())
+ {
+ LLStartUp::setStartupState(STATE_SEED_CAP_GRANTED);
+ }
+
+ if (mSeedCapAttempts > mSeedCapMaxAttempts)
+ {
+ // *TODO: Give a user pop-up about this error?
+ LL_WARNS("AppInit", "Capabilities") << "Failed to get seed capabilities from '" << url << "' after " << mSeedCapAttempts << " attempts. Giving up!" << LL_ENDL;
+ return; // this error condition is not recoverable.
+ }
+
+ S32 id = ++mHttpResponderID;
+ ++mSeedCapAttempts;
+
+ LLSD capabilityNames = LLSD::emptyArray();
+ buildCapabilityNames(capabilityNames);
+
+ LL_INFOS("AppInit", "Capabilities") << "Requesting seed from " << url
+ << " (attempt #" << mSeedCapAttempts << ")" << LL_ENDL;
+
+ regionp = NULL;
+ result = httpAdapter->postAndYield(self, httpRequest, url, capabilityNames);
+
+ regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
+ if (!regionp) //region was removed
+ {
+ LL_WARNS("AppInit", "Capabilities") << "Received capabilities for region that no longer exists!" << LL_ENDL;
+ return; // this error condition is not recoverable.
+ }
+
+ if (id != mHttpResponderID) // region is no longer referring to this request
+ {
+ LL_WARNS("AppInit", "Capabilities") << "Received results for a stale capabilities request!" << LL_ENDL;
+ // setup for retry.
+ continue;
+ }
+
+ LLSD httpResults = result["http_result"];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroHandler::getStatusFromLLSD(httpResults);
+ if (!status)
+ {
+ LL_WARNS("AppInit", "Capabilities") << "HttpStatus error " << LL_ENDL;
+ // setup for retry.
+ continue;
+ }
+
+ // remove the http_result from the llsd
+ result.erase("http_result");
+
+ LLSD::map_const_iterator iter;
+ for (iter = result.beginMap(); iter != result.endMap(); ++iter)
+ {
+ regionp->setCapability(iter->first, iter->second);
+
+ LL_DEBUGS("AppInit", "Capabilities")
+ << "Capability '" << iter->first << "' is '" << iter->second << "'" << LL_ENDL;
+ }
+
+ regionp->setCapabilitiesReceived(true);
+
+ if (STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState())
+ {
+ LLStartUp::setStartupState(STATE_SEED_CAP_GRANTED);
+ }
+
+ break;
+ }
+ while (true);
+
+ if (regionp && regionp->isCapabilityAvailable("ServerReleaseNotes") &&
+ regionp->getReleaseNotesRequested())
+ { // *HACK: we're waiting for the ServerReleaseNotes
+ regionp->showReleaseNotes();
+ }
- if (STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState())
- {
- LLStartUp::setStartupState( STATE_SEED_CAP_GRANTED );
- }
- }
+}
-private:
- U64 mRegionHandle;
- S32 mID;
-};
-class BaseCapabilitiesCompleteTracker : public LLHTTPClient::Responder
+void LLViewerRegionImpl::requestBaseCapabilitiesCompleteCoro(LLCoros::self& self, U64 regionHandle)
{
- LOG_CLASS(BaseCapabilitiesCompleteTracker);
-public:
- BaseCapabilitiesCompleteTracker( U64 region_handle)
- : mRegionHandle(region_handle)
- { }
-
- virtual ~BaseCapabilitiesCompleteTracker()
- { }
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("BaseCapabilitiesRequest", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- static BaseCapabilitiesCompleteTracker* build( U64 region_handle )
- {
- return new BaseCapabilitiesCompleteTracker( region_handle );
- }
-
-private:
- /* virtual */ void httpFailure()
- {
- LL_WARNS() << dumpResponse() << LL_ENDL;
- }
-
- /* virtual */ void httpSuccess()
- {
- LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
- if( !regionp )
- {
- LL_WARNS("AppInit", "Capabilities") << "Received results for region that no longer exists!" << LL_ENDL;
- return ;
- }
+ LLSD result;
+ LLViewerRegion *regionp = NULL;
- const LLSD& content = getContent();
- if (!content.isMap())
- {
- failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
- return;
- }
- LLSD::map_const_iterator iter;
- for(iter = content.beginMap(); iter != content.endMap(); ++iter)
- {
- regionp->setCapabilityDebug(iter->first, iter->second);
- //LL_INFOS()<<"BaseCapabilitiesCompleteTracker New Caps "<<iter->first<<" "<< iter->second<<LL_ENDL;
- }
-
- if ( regionp->getRegionImpl()->mCapabilities.size() != regionp->getRegionImpl()->mSecondCapabilitiesTracker.size() )
- {
- LL_WARNS("AppInit", "Capabilities")
- << "Sim sent duplicate base caps that differ in size from what we initially received - most likely content. "
- << "mCapabilities == " << regionp->getRegionImpl()->mCapabilities.size()
- << " mSecondCapabilitiesTracker == " << regionp->getRegionImpl()->mSecondCapabilitiesTracker.size()
- << LL_ENDL;
+ // This loop is used for retrying a capabilities request.
+ do
+ {
+ regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
+ if (!regionp) //region was removed
+ {
+ LL_WARNS("AppInit", "Capabilities") << "Attempting to get capabilities for region that no longer exists!" << LL_ENDL;
+ break; // this error condition is not recoverable.
+ }
+
+ std::string url = regionp->getCapabilityDebug("Seed");
+ if (url.empty())
+ {
+ LL_WARNS("AppInit", "Capabilities") << "Failed to get seed capabilities, and can not determine url!" << LL_ENDL;
+ break; // this error condition is not recoverable.
+ }
+
+ LLSD capabilityNames = LLSD::emptyArray();
+ buildCapabilityNames(capabilityNames);
+
+ LL_INFOS("AppInit", "Capabilities") << "Requesting second Seed from " << url << LL_ENDL;
+
+ regionp = NULL;
+ result = httpAdapter->postAndYield(self, httpRequest, url, capabilityNames);
+
+ LLSD httpResults = result["http_result"];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroHandler::getStatusFromLLSD(httpResults);
+ if (!status)
+ {
+ LL_WARNS("AppInit", "Capabilities") << "HttpStatus error " << LL_ENDL;
+ break; // no retry
+ }
+
+ regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
+ if (!regionp) //region was removed
+ {
+ LL_WARNS("AppInit", "Capabilities") << "Received capabilities for region that no longer exists!" << LL_ENDL;
+ break; // this error condition is not recoverable.
+ }
+
+ // remove the http_result from the llsd
+ result.erase("http_result");
+
+ LLSD::map_const_iterator iter;
+ for (iter = result.beginMap(); iter != result.endMap(); ++iter)
+ {
+ regionp->setCapabilityDebug(iter->first, iter->second);
+ //LL_INFOS()<<"BaseCapabilitiesCompleteTracker New Caps "<<iter->first<<" "<< iter->second<<LL_ENDL;
+ }
+
+ if (mCapabilities.size() != mSecondCapabilitiesTracker.size())
+ {
+ LL_WARNS("AppInit", "Capabilities")
+ << "Sim sent duplicate base caps that differ in size from what we initially received - most likely content. "
+ << "mCapabilities == " << mCapabilities.size()
+ << " mSecondCapabilitiesTracker == " << mSecondCapabilitiesTracker.size()
+ << LL_ENDL;
#ifdef DEBUG_CAPS_GRANTS
- LL_WARNS("AppInit", "Capabilities")
- << "Initial Base capabilities: " << LL_ENDL;
+ LL_WARNS("AppInit", "Capabilities")
+ << "Initial Base capabilities: " << LL_ENDL;
- log_capabilities(regionp->getRegionImpl()->mCapabilities);
+ log_capabilities(mCapabilities);
- LL_WARNS("AppInit", "Capabilities")
- << "Latest base capabilities: " << LL_ENDL;
+ LL_WARNS("AppInit", "Capabilities")
+ << "Latest base capabilities: " << LL_ENDL;
- log_capabilities(regionp->getRegionImpl()->mSecondCapabilitiesTracker);
+ log_capabilities(mSecondCapabilitiesTracker);
#endif
- if (regionp->getRegionImpl()->mSecondCapabilitiesTracker.size() > regionp->getRegionImpl()->mCapabilities.size() )
- {
- // *HACK Since we were granted more base capabilities in this grant request than the initial, replace
- // the old with the new. This shouldn't happen i.e. we should always get the same capabilities from a
- // sim. The simulator fix from SH-3895 should prevent it from happening, at least in the case of the
- // inventory api capability grants.
-
- // Need to clear a std::map before copying into it because old keys take precedence.
- regionp->getRegionImplNC()->mCapabilities.clear();
- regionp->getRegionImplNC()->mCapabilities = regionp->getRegionImpl()->mSecondCapabilitiesTracker;
- }
- }
- else
- {
- LL_DEBUGS("CrossingCaps") << "Sim sent multiple base cap grants with matching sizes." << LL_ENDL;
- }
- regionp->getRegionImplNC()->mSecondCapabilitiesTracker.clear();
- }
+ if (mSecondCapabilitiesTracker.size() > mCapabilities.size())
+ {
+ // *HACK Since we were granted more base capabilities in this grant request than the initial, replace
+ // the old with the new. This shouldn't happen i.e. we should always get the same capabilities from a
+ // sim. The simulator fix from SH-3895 should prevent it from happening, at least in the case of the
+ // inventory api capability grants.
+ // Need to clear a std::map before copying into it because old keys take precedence.
+ mCapabilities.clear();
+ mCapabilities = mSecondCapabilitiesTracker;
+ }
+ }
+ else
+ {
+ LL_DEBUGS("CrossingCaps") << "Sim sent multiple base cap grants with matching sizes." << LL_ENDL;
+ }
+ mSecondCapabilitiesTracker.clear();
+ }
+ while (false);
-private:
- U64 mRegionHandle;
-};
+}
+
+void LLViewerRegionImpl::requestSimulatorFeatureCoro(LLCoros::self& self, std::string url, U64 regionHandle)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("BaseCapabilitiesRequest", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+ LLViewerRegion *regionp = NULL;
+ S32 attemptNumber = 0;
+ // This loop is used for retrying a capabilities request.
+ do
+ {
+ ++attemptNumber;
+
+ if (attemptNumber > MAX_CAP_REQUEST_ATTEMPTS)
+ {
+ LL_WARNS("AppInit", "SimulatorFeatures") << "Retries count exceeded attempting to get Simulator feature from "
+ << url << LL_ENDL;
+ break;
+ }
+
+ regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
+ if (!regionp) //region was removed
+ {
+ LL_WARNS("AppInit", "SimulatorFeatures") << "Attempting to request Sim Feature for region that no longer exists!" << LL_ENDL;
+ break; // this error condition is not recoverable.
+ }
+
+ regionp = NULL;
+ LLSD result = httpAdapter->getAndYield(self, httpRequest, url);
+
+ LLSD httpResults = result["http_result"];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroHandler::getStatusFromLLSD(httpResults);
+ if (!status)
+ {
+ LL_WARNS("AppInit", "SimulatorFeatures") << "HttpStatus error retrying" << LL_ENDL;
+ continue;
+ }
+
+ // remove the http_result from the llsd
+ result.erase("http_result");
+
+ regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
+ if (!regionp) //region was removed
+ {
+ LL_WARNS("AppInit", "SimulatorFeatures") << "Attempting to set Sim Feature for region that no longer exists!" << LL_ENDL;
+ break; // this error condition is not recoverable.
+ }
+
+ regionp->setSimulatorFeatures(result);
+
+ break;
+ }
+ while (true);
+
+}
LLViewerRegion::LLViewerRegion(const U64 &handle,
const LLHost &host,
@@ -2800,15 +2873,14 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
if (getCapability("Seed") == url)
{
setCapabilityDebug("Seed", url);
- LL_DEBUGS("CrossingCaps") << "Received duplicate seed capability, posting to seed " <<
+ LL_WARNS("CrossingCaps") << "Received duplicate seed capability, posting to seed " <<
url << LL_ENDL;
//Instead of just returning we build up a second set of seed caps and compare them
//to the "original" seed cap received and determine why there is problem!
- LLSD capabilityNames = LLSD::emptyArray();
- mImpl->buildCapabilityNames( capabilityNames );
- LLHTTPClient::post( url, capabilityNames, BaseCapabilitiesCompleteTracker::build(getHandle() ),
- LLSD(), CAP_REQUEST_TIMEOUT );
+ std::string coroname =
+ LLCoros::instance().launch("LLEnvironmentRequest::requestBaseCapabilitiesCompleteCoro",
+ boost::bind(&LLViewerRegionImpl::requestBaseCapabilitiesCompleteCoro, mImpl, _1, getHandle()));
return;
}
@@ -2818,15 +2890,11 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
mImpl->mCapabilities.clear();
setCapability("Seed", url);
- LLSD capabilityNames = LLSD::emptyArray();
- mImpl->buildCapabilityNames(capabilityNames);
-
- LL_INFOS() << "posting to seed " << url << LL_ENDL;
+ std::string coroname =
+ LLCoros::instance().launch("LLEnvironmentRequest::environmentRequestCoro",
+ boost::bind(&LLViewerRegionImpl::requestBaseCapabilitiesCoro, mImpl, _1, getHandle()));
- S32 id = ++mImpl->mHttpResponderID;
- LLHTTPClient::post(url, capabilityNames,
- BaseCapabilitiesComplete::build(getHandle(), id),
- LLSD(), CAP_REQUEST_TIMEOUT);
+ LL_INFOS("AppInit", "Capabilities") << "Launching " << coroname << " requesting seed capabilities from " << url << LL_ENDL;
}
S32 LLViewerRegion::getNumSeedCapRetries()
@@ -2834,94 +2902,6 @@ S32 LLViewerRegion::getNumSeedCapRetries()
return mImpl->mSeedCapAttempts;
}
-void LLViewerRegion::failedSeedCapability()
-{
- // Should we retry asking for caps?
- mImpl->mSeedCapAttempts++;
- std::string url = getCapability("Seed");
- if ( url.empty() )
- {
- LL_WARNS("AppInit", "Capabilities") << "Failed to get seed capabilities, and can not determine url for retries!" << LL_ENDL;
- return;
- }
- // After a few attempts, continue login. We will keep trying once in-world:
- if ( mImpl->mSeedCapAttempts >= mImpl->mSeedCapMaxAttemptsBeforeLogin &&
- STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState() )
- {
- LLStartUp::setStartupState( STATE_SEED_CAP_GRANTED );
- }
-
- if ( mImpl->mSeedCapAttempts < mImpl->mSeedCapMaxAttempts)
- {
- LLSD capabilityNames = LLSD::emptyArray();
- mImpl->buildCapabilityNames(capabilityNames);
-
- LL_INFOS() << "posting to seed " << url << " (retry "
- << mImpl->mSeedCapAttempts << ")" << LL_ENDL;
-
- S32 id = ++mImpl->mHttpResponderID;
- LLHTTPClient::post(url, capabilityNames,
- BaseCapabilitiesComplete::build(getHandle(), id),
- LLSD(), CAP_REQUEST_TIMEOUT);
- }
- else
- {
- // *TODO: Give a user pop-up about this error?
- LL_WARNS("AppInit", "Capabilities") << "Failed to get seed capabilities from '" << url << "' after " << mImpl->mSeedCapAttempts << " attempts. Giving up!" << LL_ENDL;
- }
-}
-
-class SimulatorFeaturesReceived : public LLHTTPClient::Responder
-{
- LOG_CLASS(SimulatorFeaturesReceived);
-public:
- SimulatorFeaturesReceived(const std::string& retry_url, U64 region_handle,
- S32 attempt = 0, S32 max_attempts = MAX_CAP_REQUEST_ATTEMPTS)
- : mRetryURL(retry_url), mRegionHandle(region_handle), mAttempt(attempt), mMaxAttempts(max_attempts)
- { }
-
- /* virtual */ void httpFailure()
- {
- LL_WARNS("AppInit", "SimulatorFeatures") << dumpResponse() << LL_ENDL;
- retry();
- }
-
- /* virtual */ void httpSuccess()
- {
- LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
- if(!regionp) //region is removed or responder is not created.
- {
- LL_WARNS("AppInit", "SimulatorFeatures")
- << "Received results for region that no longer exists!" << LL_ENDL;
- return ;
- }
-
- const LLSD& content = getContent();
- if (!content.isMap())
- {
- failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
- return;
- }
- regionp->setSimulatorFeatures(content);
- }
-
- void retry()
- {
- if (mAttempt < mMaxAttempts)
- {
- mAttempt++;
- LL_WARNS("AppInit", "SimulatorFeatures") << "Re-trying '" << mRetryURL << "'. Retry #" << mAttempt << LL_ENDL;
- LLHTTPClient::get(mRetryURL, new SimulatorFeaturesReceived(*this), LLSD(), CAP_REQUEST_TIMEOUT);
- }
- }
-
- std::string mRetryURL;
- U64 mRegionHandle;
- S32 mAttempt;
- S32 mMaxAttempts;
-};
-
-
void LLViewerRegion::setCapability(const std::string& name, const std::string& url)
{
if(name == "EventQueueGet")
@@ -2937,7 +2917,11 @@ void LLViewerRegion::setCapability(const std::string& name, const std::string& u
else if (name == "SimulatorFeatures")
{
// kick off a request for simulator features
- LLHTTPClient::get(url, new SimulatorFeaturesReceived(url, getHandle()), LLSD(), CAP_REQUEST_TIMEOUT);
+ std::string coroname =
+ LLCoros::instance().launch("LLViewerRegionImpl::requestSimulatorFeatureCoro",
+ boost::bind(&LLViewerRegionImpl::requestSimulatorFeatureCoro, mImpl, _1, url, getHandle()));
+
+ LL_INFOS("AppInit", "SimulatorFeatures") << "Launching " << coroname << " requesting simulator features from " << url << LL_ENDL;
}
else
{
@@ -2960,9 +2944,20 @@ void LLViewerRegion::setCapabilityDebug(const std::string& name, const std::stri
mHttpUrl = url ;
}
}
+}
+
+std::string LLViewerRegion::getCapabilityDebug(const std::string& name) const
+{
+ CapabilityMap::const_iterator iter = mImpl->mSecondCapabilitiesTracker.find(name);
+ if (iter == mImpl->mSecondCapabilitiesTracker.end())
+ {
+ return "";
+ }
+ return iter->second;
}
+
bool LLViewerRegion::isSpecialCapabilityName(const std::string &name)
{
return name == "EventQueueGet" || name == "UntrustedSimulatorMessage";
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index c14fa5aee8..d15f2eab20 100755
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -253,13 +253,14 @@ public:
// Get/set named capability URLs for this region.
void setSeedCapability(const std::string& url);
- void failedSeedCapability();
S32 getNumSeedCapRetries();
void setCapability(const std::string& name, const std::string& url);
void setCapabilityDebug(const std::string& name, const std::string& url);
bool isCapabilityAvailable(const std::string& name) const;
// implements LLCapabilityProvider
virtual std::string getCapability(const std::string& name) const;
+ std::string getCapabilityDebug(const std::string& name) const;
+
// has region received its final (not seed) capability list?
bool capabilitiesReceived() const;