diff options
| author | Rider Linden <none@none> | 2015-04-15 11:51:48 -0700 | 
|---|---|---|
| committer | Rider Linden <none@none> | 2015-04-15 11:51:48 -0700 | 
| commit | 176d8cd268611e28c07a462df3027f4872456e5a (patch) | |
| tree | 0c66aad1e606ecb7c656561a84bff3da304756a6 | |
| parent | b8805c8964d45ee9141bcc131473bc4e663e93bf (diff) | |
Region caps and sim features converted to coroutine.
| -rwxr-xr-x | indra/newview/llagent.cpp | 2 | ||||
| -rwxr-xr-x | indra/newview/llappearancemgr.cpp | 193 | ||||
| -rwxr-xr-x | indra/newview/llviewerregion.cpp | 569 | ||||
| -rwxr-xr-x | indra/newview/llviewerregion.h | 3 | 
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; | 
