summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/llmessage/llcorehttputil.cpp104
-rw-r--r--indra/llmessage/llcorehttputil.h37
-rwxr-xr-xindra/newview/lleventpoll.cpp50
-rwxr-xr-xindra/newview/lleventpoll.h8
4 files changed, 124 insertions, 75 deletions
diff --git a/indra/llmessage/llcorehttputil.cpp b/indra/llmessage/llcorehttputil.cpp
index d560ec8462..dd9cb2032a 100644
--- a/indra/llmessage/llcorehttputil.cpp
+++ b/indra/llmessage/llcorehttputil.cpp
@@ -199,6 +199,12 @@ void HttpCoroHandler::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRespons
LLCore::HttpStatus status = response->getStatus();
+ if (status == LLCore::HttpStatus(LLCore::HttpStatus::LLCORE, LLCore::HE_HANDLE_NOT_FOUND))
+ { // A response came in for a canceled request and we have not processed the
+ // cancel yet. Patience!
+ return;
+ }
+
if (!status)
{
result = LLSD::emptyMap();
@@ -290,6 +296,14 @@ void HttpCoroHandler::writeStatusCodes(LLCore::HttpStatus status, const std::str
}
+LLCore::HttpStatus HttpCoroHandler::getStatusFromLLSD(const LLSD &httpResults)
+{
+ LLCore::HttpStatus::type_enum_t type = static_cast<LLCore::HttpStatus::type_enum_t>(httpResults["type"].asInteger());
+ short code = static_cast<short>(httpResults["status"].asInteger());
+
+ return LLCore::HttpStatus(type, code);
+}
+
//========================================================================
HttpRequestPumper::HttpRequestPumper(const LLCore::HttpRequest::ptr_t &request) :
mHttpRequest(request)
@@ -308,7 +322,10 @@ HttpRequestPumper::~HttpRequestPumper()
bool HttpRequestPumper::pollRequest(const LLSD&)
{
- mHttpRequest->update(0L);
+ if (mHttpRequest->getStatus() != HttpStatus(HttpStatus::LLCORE, HE_OP_CANCELED))
+ {
+ mHttpRequest->update(0L);
+ }
return false;
}
@@ -319,29 +336,20 @@ HttpCoroutineAdapter::HttpCoroutineAdapter(const std::string &name,
mPolicyId(policyId),
mPriority(priority),
mYieldingHandle(LLCORE_HTTP_HANDLE_INVALID),
- mWeakRequest()
+ mWeakRequest(),
+ mWeakHandler()
{
}
HttpCoroutineAdapter::~HttpCoroutineAdapter()
{
-
+ cancelYieldingOperation();
}
LLSD HttpCoroutineAdapter::postAndYield(LLCoros::self & self, LLCore::HttpRequest::ptr_t request,
const std::string & url, const LLSD & body,
LLCore::HttpOptions::ptr_t options, LLCore::HttpHeaders::ptr_t headers)
{
- if (!options)
- {
- options = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions(), false);
- }
-
- if (!headers)
- {
- headers = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders(), false);
- }
-
LLEventStream replyPump(mAdapterName, true);
LLCoreHttpUtil::HttpCoroHandler::ptr_t httpHandler =
LLCoreHttpUtil::HttpCoroHandler::ptr_t(new LLCoreHttpUtil::HttpCoroHandler(replyPump));
@@ -356,12 +364,13 @@ LLSD HttpCoroutineAdapter::postAndYield(LLCoros::self & self, LLCore::HttpReques
if (hhandle == LLCORE_HTTP_HANDLE_INVALID)
{
- return HttpCoroutineAdapter::buildImmediateErrorResult(request, url, httpHandler);
+ return HttpCoroutineAdapter::buildImmediateErrorResult(request, url);
}
- mYieldingHandle = hhandle;
+ saveState(hhandle, request, httpHandler);
LLSD results = waitForEventOn(self, replyPump);
- mYieldingHandle = LLCORE_HTTP_HANDLE_INVALID;
+ cleanState();
+
//LL_INFOS() << "Results for transaction " << transactionId << LL_ENDL;
return results;
}
@@ -370,16 +379,6 @@ LLSD HttpCoroutineAdapter::putAndYield(LLCoros::self & self, LLCore::HttpRequest
const std::string & url, const LLSD & body,
LLCore::HttpOptions::ptr_t options, LLCore::HttpHeaders::ptr_t headers)
{
- if (!options)
- {
- options = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions(), false);
- }
-
- if (!headers)
- {
- headers = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders(), false);
- }
-
LLEventStream replyPump(mAdapterName, true);
LLCoreHttpUtil::HttpCoroHandler::ptr_t httpHandler =
LLCoreHttpUtil::HttpCoroHandler::ptr_t(new LLCoreHttpUtil::HttpCoroHandler(replyPump));
@@ -394,12 +393,12 @@ LLSD HttpCoroutineAdapter::putAndYield(LLCoros::self & self, LLCore::HttpRequest
if (hhandle == LLCORE_HTTP_HANDLE_INVALID)
{
- return HttpCoroutineAdapter::buildImmediateErrorResult(request, url, httpHandler);
+ return HttpCoroutineAdapter::buildImmediateErrorResult(request, url);
}
- mYieldingHandle = hhandle;
+ saveState(hhandle, request, httpHandler);
LLSD results = waitForEventOn(self, replyPump);
- mYieldingHandle = LLCORE_HTTP_HANDLE_INVALID;
+ cleanState();
//LL_INFOS() << "Results for transaction " << transactionId << LL_ENDL;
return results;
}
@@ -408,16 +407,6 @@ LLSD HttpCoroutineAdapter::getAndYield(LLCoros::self & self, LLCore::HttpRequest
const std::string & url,
LLCore::HttpOptions::ptr_t options, LLCore::HttpHeaders::ptr_t headers)
{
- if (!options)
- {
- options = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions(), false);
- }
-
- if (!headers)
- {
- headers = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders(), false);
- }
-
LLEventStream replyPump(mAdapterName + "Reply", true);
LLCoreHttpUtil::HttpCoroHandler::ptr_t httpHandler =
LLCoreHttpUtil::HttpCoroHandler::ptr_t(new LLCoreHttpUtil::HttpCoroHandler(replyPump));
@@ -431,18 +420,45 @@ LLSD HttpCoroutineAdapter::getAndYield(LLCoros::self & self, LLCore::HttpRequest
if (hhandle == LLCORE_HTTP_HANDLE_INVALID)
{
- return HttpCoroutineAdapter::buildImmediateErrorResult(request, url, httpHandler);
+ return HttpCoroutineAdapter::buildImmediateErrorResult(request, url);
}
- mYieldingHandle = hhandle;
+ saveState(hhandle, request, httpHandler);
LLSD results = waitForEventOn(self, replyPump);
- mYieldingHandle = LLCORE_HTTP_HANDLE_INVALID;
+ cleanState();
//LL_INFOS() << "Results for transaction " << transactionId << LL_ENDL;
return results;
}
+void HttpCoroutineAdapter::cancelYieldingOperation()
+{
+ LLCore::HttpRequest::ptr_t request = mWeakRequest.lock();
+ HttpCoroHandler::ptr_t handler = mWeakHandler.lock();
+ if ((request) && (handler) && (mYieldingHandle != LLCORE_HTTP_HANDLE_INVALID))
+ {
+ cleanState();
+ LL_INFOS() << "Canceling yielding request!" << LL_ENDL;
+ request->requestCancel(mYieldingHandle, handler.get());
+ }
+}
+
+void HttpCoroutineAdapter::saveState(LLCore::HttpHandle yieldingHandle,
+ LLCore::HttpRequest::ptr_t &request, HttpCoroHandler::ptr_t &handler)
+{
+ mWeakRequest = request;
+ mWeakHandler = handler;
+ mYieldingHandle = yieldingHandle;
+}
+
+void HttpCoroutineAdapter::cleanState()
+{
+ mWeakRequest.reset();
+ mWeakHandler.reset();
+ mYieldingHandle = LLCORE_HTTP_HANDLE_INVALID;
+}
+
LLSD HttpCoroutineAdapter::buildImmediateErrorResult(const LLCore::HttpRequest::ptr_t &request,
- const std::string &url, LLCoreHttpUtil::HttpCoroHandler::ptr_t &httpHandler)
+ const std::string &url)
{
LLCore::HttpStatus status = request->getStatus();
LL_WARNS() << "Error posting to " << url << " Status=" << status.getStatus() <<
@@ -452,7 +468,7 @@ LLSD HttpCoroutineAdapter::buildImmediateErrorResult(const LLCore::HttpRequest::
// to wait on
LLSD httpresults = LLSD::emptyMap();
- httpHandler->writeStatusCodes(status, url, httpresults);
+ HttpCoroHandler::writeStatusCodes(status, url, httpresults);
LLSD errorres = LLSD::emptyMap();
errorres["http_result"] = httpresults;
diff --git a/indra/llmessage/llcorehttputil.h b/indra/llmessage/llcorehttputil.h
index 33cc389c49..471710f61b 100644
--- a/indra/llmessage/llcorehttputil.h
+++ b/indra/llmessage/llcorehttputil.h
@@ -170,13 +170,16 @@ LLCore::HttpHandle requestPutWithLLSD(LLCore::HttpRequest::ptr_t & request,
class HttpCoroHandler : public LLCore::HttpHandler
{
public:
+ typedef boost::shared_ptr<HttpCoroHandler> ptr_t;
+ typedef boost::weak_ptr<HttpCoroHandler> wptr_t;
+
HttpCoroHandler(LLEventStream &reply);
virtual void onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response);
- typedef boost::shared_ptr<HttpCoroHandler> ptr_t;
+ static void writeStatusCodes(LLCore::HttpStatus status, const std::string &url, LLSD &result);
+ static LLCore::HttpStatus getStatusFromLLSD(const LLSD &httpResults);
- void writeStatusCodes(LLCore::HttpStatus status, const std::string &url, LLSD &result);
private:
void buildStatusEntry(LLCore::HttpResponse *response, LLCore::HttpStatus status, LLSD &result);
@@ -219,7 +222,8 @@ public:
/// Execute a Post transaction on the supplied URL and yield execution of
/// the coroutine until a result is available.
- /// Note: the request's smart pointer is passed by value so that it will
+ ///
+ /// @Note: the request's smart pointer is passed by value so that it will
/// not be deallocated during the yield.
LLSD postAndYield(LLCoros::self & self, LLCore::HttpRequest::ptr_t request,
const std::string & url, const LLSD & body,
@@ -228,28 +232,34 @@ public:
/// Execute a Put transaction on the supplied URL and yield execution of
/// the coroutine until a result is available.
- /// Note: the request's smart pointer is passed by value so that it will
+ ///
+ /// @Note: the request's smart pointer is passed by value so that it will
/// not be deallocated during the yield.
LLSD putAndYield(LLCoros::self & self, LLCore::HttpRequest::ptr_t request,
const std::string & url, const LLSD & body,
- LLCore::HttpOptions::ptr_t options = LLCore::HttpOptions::ptr_t(),
- LLCore::HttpHeaders::ptr_t headers = LLCore::HttpHeaders::ptr_t());
+ LLCore::HttpOptions::ptr_t options = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions(), false),
+ LLCore::HttpHeaders::ptr_t headers = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders(), false));
/// Execute a Get transaction on the supplied URL and yield execution of
/// the coroutine until a result is available.
- /// Note: the request's smart pointer is passed by value so that it will
+ ///
+ /// @Note: the request's smart pointer is passed by value so that it will
/// not be deallocated during the yield.
LLSD getAndYield(LLCoros::self & self, LLCore::HttpRequest::ptr_t request,
const std::string & url,
- LLCore::HttpOptions::ptr_t options = LLCore::HttpOptions::ptr_t(),
- LLCore::HttpHeaders::ptr_t headers = LLCore::HttpHeaders::ptr_t());
+ LLCore::HttpOptions::ptr_t options = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions(), false),
+ LLCore::HttpHeaders::ptr_t headers = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders(), false));
///
void cancelYieldingOperation();
private:
- static LLSD buildImmediateErrorResult(const LLCore::HttpRequest::ptr_t &request,
- const std::string &url, LLCoreHttpUtil::HttpCoroHandler::ptr_t &httpHandler);
+ static LLSD buildImmediateErrorResult(const LLCore::HttpRequest::ptr_t &request, const std::string &url);
+
+ void saveState(LLCore::HttpHandle yieldingHandle, LLCore::HttpRequest::ptr_t &request,
+ HttpCoroHandler::ptr_t &handler);
+ void cleanState();
+
std::string mAdapterName;
LLCore::HttpRequest::priority_t mPriority;
@@ -257,9 +267,12 @@ private:
LLCore::HttpHandle mYieldingHandle;
LLCore::HttpRequest::wptr_t mWeakRequest;
-
+ HttpCoroHandler::wptr_t mWeakHandler;
};
+//-------------------------------------------------------------------------
+LLCore::HttpStatus getStatusFromLLSD(const LLSD &httpResults);
+
} // end namespace LLCoreHttpUtil
#endif // LL_LLCOREHTTPUTIL_H
diff --git a/indra/newview/lleventpoll.cpp b/indra/newview/lleventpoll.cpp
index 493ee06083..625bbfae0c 100755
--- a/indra/newview/lleventpoll.cpp
+++ b/indra/newview/lleventpoll.cpp
@@ -41,9 +41,11 @@
#include "lleventcoro.h"
#include "llcorehttputil.h"
-namespace
+namespace LLEventPolling
{
- // We will wait RETRY_SECONDS + (errorCount * RETRY_SECONDS_INC) before retrying after an error.
+namespace Details
+{
+ // We will wait RETRY_SECONDS + (errorCount * RETRY_SECONDS_INC) before retrying after an error.
// This means we attempt to recover relatively quickly but back off giving more time to recover
// until we finally give up after MAX_EVENT_POLL_HTTP_ERRORS attempts.
const F32 EVENT_POLL_ERROR_RETRY_SECONDS = 15.f; // ~ half of a normal timeout.
@@ -69,6 +71,7 @@ namespace
LLCore::HttpRequest::policy_t mHttpPolicy;
std::string mSenderIp;
int mCounter;
+ LLCoreHttpUtil::HttpCoroutineAdapter::wptr_t mAdapter;
static int sNextCounter;
};
@@ -105,24 +108,33 @@ namespace
std::string coroname =
LLCoros::instance().launch("LLAccountingCostManager::accountingCostCoro",
boost::bind(&LLEventPollImpl::eventPollCoro, this, _1, url));
- LL_DEBUGS() << coroname << " with url '" << url << LL_ENDL;
+ LL_INFOS() << coroname << " with url '" << url << LL_ENDL;
}
}
void LLEventPollImpl::stop()
{
+ LL_INFOS() << "requesting stop for event poll coroutine <" << mCounter << ">" << LL_ENDL;
mDone = true;
+
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t adapter = mAdapter.lock();
+ if (adapter)
+ {
+ // cancel the yielding operation if any.
+ adapter->cancelYieldingOperation();
+ }
}
void LLEventPollImpl::eventPollCoro(LLCoros::self& self, std::string url)
{
- LLCoreHttpUtil::HttpCoroutineAdapter httpAdapter("EventPoller", mHttpPolicy);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("EventPoller", mHttpPolicy));
LLSD acknowledge;
int errorCount = 0;
int counter = mCounter; // saved on the stack for debugging.
LL_INFOS("LLEventPollImpl::eventPollCoro") << " <" << counter << "> entering coroutine." << LL_ENDL;
+ mAdapter = httpAdapter;
while (!mDone)
{
LLSD request;
@@ -132,33 +144,35 @@ namespace
// LL_DEBUGS("LLEventPollImpl::eventPollCoro") << "<" << counter << "> request = "
// << LLSDXMLStreamer(request) << LL_ENDL;
- LL_INFOS("LLEventPollImpl::eventPollCoro") << " <" << counter << "> posting and yielding." << LL_ENDL;
- LLSD result = httpAdapter.postAndYield(self, mHttpRequest, url, request);
+ LL_DEBUGS("LLEventPollImpl::eventPollCoro") << " <" << counter << "> posting and yielding." << LL_ENDL;
+ LLSD result = httpAdapter->postAndYield(self, mHttpRequest, url, request);
// LL_DEBUGS("LLEventPollImpl::eventPollCoro") << "<" << counter << "> result = "
// << LLSDXMLStreamer(result) << LL_ENDL;
- if (mDone)
- break;
-
LLSD httpResults;
httpResults = result["http_result"];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroHandler::getStatusFromLLSD(httpResults);
-
- if (!httpResults["success"].asBoolean())
+ if (!status)
{
- LL_WARNS("LLEventPollImpl::eventPollCoro") << "<" << counter << "> Error result from LLCoreHttpUtil::HttpCoroHandler. Code "
- << httpResults["status"] << ": '" << httpResults["message"] << "'" << LL_ENDL;
- if (httpResults["status"].asInteger() == HTTP_BAD_GATEWAY)
+ if (status == LLCore::HttpStatus(HTTP_BAD_GATEWAY))
{
// A HTTP_BAD_GATEWAY (502) error is our standard timeout response
// we get this when there are no events.
errorCount = 0;
continue;
}
-
- LL_WARNS("LLEventPollImpl::eventPollCoro") << "<" << counter << "> " << LLSDXMLStreamer(result) << (mDone ? " -- done" : "") << LL_ENDL;
+
+ if ((status == LLCore::HttpStatus(LLCore::HttpStatus::LLCORE, LLCore::HE_OP_CANCELED)) ||
+ (status == LLCore::HttpStatus(HTTP_NOT_FOUND)))
+ {
+ LL_WARNS() << "Canceling coroutine" << LL_ENDL;
+ break;
+ }
+ LL_WARNS("LLEventPollImpl::eventPollCoro") << "<" << counter << "> Error result from LLCoreHttpUtil::HttpCoroHandler. Code "
+ << status.toTerseString() << ": '" << httpResults["message"] << "'" << LL_ENDL;
if (errorCount < MAX_EVENT_POLL_HTTP_ERRORS)
{
@@ -481,11 +495,13 @@ LLEventPoll::~LLEventPoll()
}
#endif
}
+}
LLEventPoll::LLEventPoll(const std::string& poll_url, const LLHost& sender):
mImpl()
{
- mImpl = boost::unique_ptr<LLEventPollImpl>(new LLEventPollImpl(sender));
+ mImpl = boost::unique_ptr<LLEventPolling::Details::LLEventPollImpl>
+ (new LLEventPolling::Details::LLEventPollImpl(sender));
mImpl->start(poll_url);
}
diff --git a/indra/newview/lleventpoll.h b/indra/newview/lleventpoll.h
index 4b9944724d..0be48be6b4 100755
--- a/indra/newview/lleventpoll.h
+++ b/indra/newview/lleventpoll.h
@@ -37,10 +37,13 @@ namespace boost
class LLHost;
-namespace
+namespace LLEventPolling
+{
+namespace Details
{
class LLEventPollImpl;
}
+}
class LLEventPoll
@@ -56,7 +59,8 @@ public:
private:
#if 1
- boost::unique_ptr<LLEventPollImpl> mImpl;
+ boost::unique_ptr<LLEventPolling::Details::LLEventPollImpl> mImpl;
+
#else
LLHTTPClient::ResponderPtr mImpl;
#endif