From 5611cb6d476540e6a1c654c1f9acdce2787b3505 Mon Sep 17 00:00:00 2001 From: Monty Brandenberg Date: Mon, 23 Apr 2012 16:19:39 -0400 Subject: Okay, imported the core-http library and got it compiling suspiciously easily. The unit/integration tests don't work yet as I'm still battling cmake/autobuild as usual but first milestone passed. --- indra/llcorehttp/_httplibcurl.cpp | 214 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 214 insertions(+) create mode 100644 indra/llcorehttp/_httplibcurl.cpp (limited to 'indra/llcorehttp/_httplibcurl.cpp') diff --git a/indra/llcorehttp/_httplibcurl.cpp b/indra/llcorehttp/_httplibcurl.cpp new file mode 100644 index 0000000000..15be977adf --- /dev/null +++ b/indra/llcorehttp/_httplibcurl.cpp @@ -0,0 +1,214 @@ +/** + * @file _httplibcurl.cpp + * @brief Internal definitions of the Http libcurl thread + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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 "_httplibcurl.h" + +#include "httpheaders.h" + +#include "_httpoprequest.h" +#include "_httpservice.h" + + +namespace LLCore +{ + + +HttpLibcurl::HttpLibcurl(HttpService * service) + : mService(service) +{ + mMultiHandles[0] = curl_multi_init(); +} + + +HttpLibcurl::~HttpLibcurl() +{ + // *FIXME: need to cancel requests in this class, not in op class. + while (! mActiveOps.empty()) + { + active_set_t::iterator item(mActiveOps.begin()); + + (*item)->cancel(); + (*item)->release(); + } + + if (mMultiHandles[0]) + { + // *FIXME: Do some multi cleanup here first + + + curl_multi_cleanup(mMultiHandles[0]); + mMultiHandles[0] = NULL; + } + + mService = NULL; +} + + +void HttpLibcurl::init() +{} + + +void HttpLibcurl::term() +{} + + +void HttpLibcurl::processTransport() +{ + if (mMultiHandles[0]) + { + // Give libcurl some cycles to do I/O & callbacks + int running(0); + CURLMcode status(CURLM_CALL_MULTI_PERFORM); + do + { + running = 0; + status = curl_multi_perform(mMultiHandles[0], &running); + } + while (0 != running && CURLM_CALL_MULTI_PERFORM == status); + + // Run completion on anything done + CURLMsg * msg(NULL); + int msgs_in_queue(0); + while ((msg = curl_multi_info_read(mMultiHandles[0], &msgs_in_queue))) + { + if (CURLMSG_DONE == msg->msg) + { + CURL * handle(msg->easy_handle); + CURLcode result(msg->data.result); + + completeRequest(mMultiHandles[0], handle, result); + handle = NULL; // No longer valid on return + } + else if (CURLMSG_NONE == msg->msg) + { + // Ignore this... it shouldn't mean anything. + ; + } + else + { + // *FIXME: Issue a logging event for this. + ; + } + msgs_in_queue = 0; + } + } +} + + +void HttpLibcurl::addOp(HttpOpRequest * op) +{ + // Create standard handle + if (! op->prepareForGet(mService)) + { + // Couldn't issue request, fail with notification + // *FIXME: Need failure path + return; + } + + // Make the request live + curl_multi_add_handle(mMultiHandles[0], op->mCurlHandle); + op->mCurlActive = true; + + // On success, make operation active + mActiveOps.insert(op); +} + + +void HttpLibcurl::completeRequest(CURLM * multi_handle, CURL * handle, CURLcode status) +{ + HttpOpRequest * op(NULL); + curl_easy_getinfo(handle, CURLINFO_PRIVATE, &op); + // *FIXME: check the pointer + + if (handle != op->mCurlHandle || ! op->mCurlActive) + { + // *FIXME: This is a sanity check that needs validation/termination. + ; + } + + active_set_t::iterator it(mActiveOps.find(op)); + if (mActiveOps.end() == it) + { + // *FIXME: Fatal condition. This must be here. + ; + } + else + { + mActiveOps.erase(it); + } + + // Deactivate request + op->mCurlActive = false; + + // Set final status of request + if (op->mStatus) + { + // Only set if it hasn't failed by other mechanisms yet + op->mStatus = HttpStatus(HttpStatus::EXT_CURL_EASY, status); + } + if (op->mStatus) + { + int http_status(200); + + curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &status); + op->mReplyStatus = http_status; + } + + // Detach from multi and recycle handle + curl_multi_remove_handle(multi_handle, handle); + curl_easy_cleanup(handle); + op->mCurlHandle = NULL; + + // Deliver to reply queue and release + op->stageFromActive(mService); + op->release(); +} + + +int HttpLibcurl::activeCount() const +{ + return mActiveOps.size(); +} + + +// --------------------------------------- +// Free functions +// --------------------------------------- + + +struct curl_slist * append_headers_to_slist(const HttpHeaders * headers, struct curl_slist * slist) +{ + for (HttpHeaders::container_t::const_iterator it(headers->mHeaders.begin()); + headers->mHeaders.end() != it; + ++it) + { + slist = curl_slist_append(slist, (*it).c_str()); + } + return slist; +} + + +} // end namespace LLCore -- cgit v1.2.3 From 8fc350125c671baeae6b7f8b1814251009f4f50a Mon Sep 17 00:00:00 2001 From: Monty Brandenberg Date: Wed, 23 May 2012 19:12:09 -0400 Subject: Integrate llcorehttp library into lltexturefetch design. This is the first functional viewer pass with the HTTP work of the texture fetch code performed by the llcorehttp library. Not exactly a 'drop-in' replacement but a work-alike with some changes (e.g. handler notification in consumer thread versus responder notification in worker thread). This also includes some temporary changes in the priority scheme to prevent the kind of priority inversion found in VWR-28996. Scheme used here does provide liveness if not optimal responsiveness or order-of-operation. The llcorehttp library at this point is far from optimally performing. Its worker thread is making relatively poor use of cycles it gets and it doesn't idle or sleep intelligently yet. This early integration step helps shake out the interfaces, implementation niceties will be covered soon. --- indra/llcorehttp/_httplibcurl.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'indra/llcorehttp/_httplibcurl.cpp') diff --git a/indra/llcorehttp/_httplibcurl.cpp b/indra/llcorehttp/_httplibcurl.cpp index 15be977adf..1b951818e4 100644 --- a/indra/llcorehttp/_httplibcurl.cpp +++ b/indra/llcorehttp/_httplibcurl.cpp @@ -27,7 +27,6 @@ #include "_httplibcurl.h" #include "httpheaders.h" - #include "_httpoprequest.h" #include "_httpservice.h" @@ -173,8 +172,11 @@ void HttpLibcurl::completeRequest(CURLM * multi_handle, CURL * handle, CURLcode { int http_status(200); - curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &status); - op->mReplyStatus = http_status; + curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &http_status); + op->mStatus = LLCore::HttpStatus(http_status, + (http_status >= 200 && http_status <= 299 + ? HE_SUCCESS + : HE_REPLY_ERROR)); } // Detach from multi and recycle handle @@ -202,7 +204,8 @@ int HttpLibcurl::activeCount() const struct curl_slist * append_headers_to_slist(const HttpHeaders * headers, struct curl_slist * slist) { for (HttpHeaders::container_t::const_iterator it(headers->mHeaders.begin()); - headers->mHeaders.end() != it; + + headers->mHeaders.end() != it; ++it) { slist = curl_slist_append(slist, (*it).c_str()); -- cgit v1.2.3 From b8edacd0bb4feacc3ac1d61421e600c75ab87f7c Mon Sep 17 00:00:00 2001 From: Monty Brandenberg Date: Fri, 1 Jun 2012 14:07:34 -0400 Subject: Major steps towards implementing the policy component. Identified and reacted to the priority inversion problem we have in texturefetch. Includes the introduction of a priority_queue for the requests that are ready. Start some parameterization in anticipation of having policy_class everywhere. Removed _assert.h which isn't really needed in indra codebase. Implemented async setPriority request (which I hope I can get rid of eventually along with all priorities in this library). Converted to using unsigned int for priority rather than float. Implemented POST and did groundwork for PUT. --- indra/llcorehttp/_httplibcurl.cpp | 52 ++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 15 deletions(-) (limited to 'indra/llcorehttp/_httplibcurl.cpp') diff --git a/indra/llcorehttp/_httplibcurl.cpp b/indra/llcorehttp/_httplibcurl.cpp index 1b951818e4..704f9baac9 100644 --- a/indra/llcorehttp/_httplibcurl.cpp +++ b/indra/llcorehttp/_httplibcurl.cpp @@ -28,7 +28,6 @@ #include "httpheaders.h" #include "_httpoprequest.h" -#include "_httpservice.h" namespace LLCore @@ -38,6 +37,12 @@ namespace LLCore HttpLibcurl::HttpLibcurl(HttpService * service) : mService(service) { + for (int policy_class(0); policy_class < HttpRequest::POLICY_CLASS_LIMIT; ++policy_class) + { + mMultiHandles[policy_class] = 0; + } + + // Create multi handle for default class mMultiHandles[0] = curl_multi_init(); } @@ -51,15 +56,18 @@ HttpLibcurl::~HttpLibcurl() (*item)->cancel(); (*item)->release(); + mActiveOps.erase(item); } - if (mMultiHandles[0]) + for (int policy_class(0); policy_class < HttpRequest::POLICY_CLASS_LIMIT; ++policy_class) { - // *FIXME: Do some multi cleanup here first - + if (mMultiHandles[policy_class]) + { + // *FIXME: Do some multi cleanup here first - curl_multi_cleanup(mMultiHandles[0]); - mMultiHandles[0] = NULL; + curl_multi_cleanup(mMultiHandles[policy_class]); + mMultiHandles[policy_class] = 0; + } } mService = NULL; @@ -74,31 +82,34 @@ void HttpLibcurl::term() {} -void HttpLibcurl::processTransport() +HttpService::ELoopSpeed HttpLibcurl::processTransport() { - if (mMultiHandles[0]) + // Give libcurl some cycles to do I/O & callbacks + for (int policy_class(0); policy_class < HttpRequest::POLICY_CLASS_LIMIT; ++policy_class) { - // Give libcurl some cycles to do I/O & callbacks + if (! mMultiHandles[policy_class]) + continue; + int running(0); CURLMcode status(CURLM_CALL_MULTI_PERFORM); do { running = 0; - status = curl_multi_perform(mMultiHandles[0], &running); + status = curl_multi_perform(mMultiHandles[policy_class], &running); } while (0 != running && CURLM_CALL_MULTI_PERFORM == status); // Run completion on anything done CURLMsg * msg(NULL); int msgs_in_queue(0); - while ((msg = curl_multi_info_read(mMultiHandles[0], &msgs_in_queue))) + while ((msg = curl_multi_info_read(mMultiHandles[policy_class], &msgs_in_queue))) { if (CURLMSG_DONE == msg->msg) { CURL * handle(msg->easy_handle); CURLcode result(msg->data.result); - completeRequest(mMultiHandles[0], handle, result); + completeRequest(mMultiHandles[policy_class], handle, result); handle = NULL; // No longer valid on return } else if (CURLMSG_NONE == msg->msg) @@ -114,13 +125,18 @@ void HttpLibcurl::processTransport() msgs_in_queue = 0; } } + + return mActiveOps.empty() ? HttpService::REQUEST_SLEEP : HttpService::NORMAL; } void HttpLibcurl::addOp(HttpOpRequest * op) { + llassert_always(op->mReqPolicy < HttpRequest::POLICY_CLASS_LIMIT); + llassert_always(mMultiHandles[op->mReqPolicy] != NULL); + // Create standard handle - if (! op->prepareForGet(mService)) + if (! op->prepareRequest(mService)) { // Couldn't issue request, fail with notification // *FIXME: Need failure path @@ -128,7 +144,7 @@ void HttpLibcurl::addOp(HttpOpRequest * op) } // Make the request live - curl_multi_add_handle(mMultiHandles[0], op->mCurlHandle); + curl_multi_add_handle(mMultiHandles[op->mReqPolicy], op->mCurlHandle); op->mCurlActive = true; // On success, make operation active @@ -190,12 +206,18 @@ void HttpLibcurl::completeRequest(CURLM * multi_handle, CURL * handle, CURLcode } -int HttpLibcurl::activeCount() const +int HttpLibcurl::getActiveCount() const { return mActiveOps.size(); } +int HttpLibcurl::getActiveCountInClass(int /* policy_class */) const +{ + return getActiveCount(); +} + + // --------------------------------------- // Free functions // --------------------------------------- -- cgit v1.2.3 From 05af16a23abe37210e0b880aa27387d8994419dd Mon Sep 17 00:00:00 2001 From: Monty Brandenberg Date: Wed, 6 Jun 2012 13:52:38 -0400 Subject: Policy + caching fixes + https support + POST working Implemented first global policy definitions to support SSL CA certificate configuration to support https: operations. Fixed HTTP 206 status handling to match what is currently being done by grid services and to lay a foundation for fixes that will be a response to ER-1824. More libcurl CURLOPT options set on easy handles to do peer verification in the traditional way. HTTP POST working and now reporting asset metrics back to grid for the viewer's asset system. This uses LLSD so that is also showing as compatible with the new library. --- indra/llcorehttp/_httplibcurl.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'indra/llcorehttp/_httplibcurl.cpp') diff --git a/indra/llcorehttp/_httplibcurl.cpp b/indra/llcorehttp/_httplibcurl.cpp index 704f9baac9..5272c391e8 100644 --- a/indra/llcorehttp/_httplibcurl.cpp +++ b/indra/llcorehttp/_httplibcurl.cpp @@ -27,6 +27,7 @@ #include "_httplibcurl.h" #include "httpheaders.h" +#include "bufferarray.h" #include "_httpoprequest.h" -- cgit v1.2.3 From 28a04400b4160dd34166483ddcf0c12637bcc363 Mon Sep 17 00:00:00 2001 From: Monty Brandenberg Date: Fri, 8 Jun 2012 20:21:54 -0400 Subject: Implemented HTTP retry for requests. Went in rather easily which surprised me. Added a retry queue similar to ready queue to the policy object which is sorted by retry time. Currently do five retries (after the initial try) delayed by .25, .5, 1, 2 and 5 seconds. Removed the retry logic from the lltexturefetch module. Upped the waiting time in the unit test for the retries. People won't like this but tough, need tests. --- indra/llcorehttp/_httplibcurl.cpp | 58 +++++++++++++++++++++++++++++++++------ 1 file changed, 50 insertions(+), 8 deletions(-) (limited to 'indra/llcorehttp/_httplibcurl.cpp') diff --git a/indra/llcorehttp/_httplibcurl.cpp b/indra/llcorehttp/_httplibcurl.cpp index 5272c391e8..05b2c2be69 100644 --- a/indra/llcorehttp/_httplibcurl.cpp +++ b/indra/llcorehttp/_httplibcurl.cpp @@ -29,6 +29,7 @@ #include "httpheaders.h" #include "bufferarray.h" #include "_httpoprequest.h" +#include "_httppolicy.h" namespace LLCore @@ -85,6 +86,8 @@ void HttpLibcurl::term() HttpService::ELoopSpeed HttpLibcurl::processTransport() { + HttpService::ELoopSpeed ret(HttpService::REQUEST_SLEEP); + // Give libcurl some cycles to do I/O & callbacks for (int policy_class(0); policy_class < HttpRequest::POLICY_CLASS_LIMIT; ++policy_class) { @@ -110,7 +113,8 @@ HttpService::ELoopSpeed HttpLibcurl::processTransport() CURL * handle(msg->easy_handle); CURLcode result(msg->data.result); - completeRequest(mMultiHandles[policy_class], handle, result); + HttpService::ELoopSpeed speed(completeRequest(mMultiHandles[policy_class], handle, result)); + ret = (std::min)(ret, speed); handle = NULL; // No longer valid on return } else if (CURLMSG_NONE == msg->msg) @@ -127,7 +131,11 @@ HttpService::ELoopSpeed HttpLibcurl::processTransport() } } - return mActiveOps.empty() ? HttpService::REQUEST_SLEEP : HttpService::NORMAL; + if (! mActiveOps.empty()) + { + ret = (std::min)(ret, HttpService::NORMAL); + } + return ret; } @@ -153,8 +161,12 @@ void HttpLibcurl::addOp(HttpOpRequest * op) } -void HttpLibcurl::completeRequest(CURLM * multi_handle, CURL * handle, CURLcode status) +HttpService::ELoopSpeed HttpLibcurl::completeRequest(CURLM * multi_handle, CURL * handle, CURLcode status) { + static const HttpStatus cant_connect(HttpStatus::EXT_CURL_EASY, CURLE_COULDNT_CONNECT); + static const HttpStatus cant_res_proxy(HttpStatus::EXT_CURL_EASY, CURLE_COULDNT_RESOLVE_PROXY); + static const HttpStatus cant_res_host(HttpStatus::EXT_CURL_EASY, CURLE_COULDNT_RESOLVE_HOST); + HttpOpRequest * op(NULL); curl_easy_getinfo(handle, CURLINFO_PRIVATE, &op); // *FIXME: check the pointer @@ -190,10 +202,7 @@ void HttpLibcurl::completeRequest(CURLM * multi_handle, CURL * handle, CURLcode int http_status(200); curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &http_status); - op->mStatus = LLCore::HttpStatus(http_status, - (http_status >= 200 && http_status <= 299 - ? HE_SUCCESS - : HE_REPLY_ERROR)); + op->mStatus = LLCore::HttpStatus(http_status); } // Detach from multi and recycle handle @@ -201,9 +210,42 @@ void HttpLibcurl::completeRequest(CURLM * multi_handle, CURL * handle, CURLcode curl_easy_cleanup(handle); op->mCurlHandle = NULL; - // Deliver to reply queue and release + // Retry or finalize + if (! op->mStatus) + { + // If this failed, we might want to retry. Have to inspect + // the status a little more deeply for those reasons worth retrying... + if (op->mPolicyRetries < op->mPolicyRetryLimit && + ((op->mStatus.isHttpStatus() && op->mStatus.mType >= 499 && op->mStatus.mType <= 599) || + cant_connect == op->mStatus || + cant_res_proxy == op->mStatus || + cant_res_host == op->mStatus)) + { + // Okay, worth a retry. We include 499 in this test as + // it's the old 'who knows?' error from many grid services... + HttpPolicy & policy(mService->getPolicy()); + + policy.retryOp(op); + return HttpService::NORMAL; // Having pushed to retry, keep things running + } + } + + // This op is done, finalize it delivering it to the reply queue... + if (! op->mStatus) + { + LL_WARNS("CoreHttp") << "URL op failed after " << op->mPolicyRetries + << " retries. Reason: " << op->mStatus.toString() + << LL_ENDL; + } + else if (op->mPolicyRetries) + { + LL_WARNS("CoreHttp") << "URL op succeeded after " << op->mPolicyRetries << " retries." + << LL_ENDL; + } + op->stageFromActive(mService); op->release(); + return HttpService::REQUEST_SLEEP; } -- cgit v1.2.3 From f4a59854c5aab0fb1f666d8df45984a0f4cfd465 Mon Sep 17 00:00:00 2001 From: Monty Brandenberg Date: Mon, 11 Jun 2012 12:24:54 -0400 Subject: Unit test fixups. Mac/Linux detect memory leak due to llwarns, try/catch cleanup. Our logging holds on to a changing bit of memory between operations and the memory leak detection I'm using senses this and complains. So, for now, disable the final memory check on Mac & Linux, leave it active on Windows. Solve this for real some other day. Add try/catch blocks to do cleanup in unit tests that go wrong so that we don't get a cascade of assertion failures when subsequent tests find singletons still alive. --- indra/llcorehttp/_httplibcurl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llcorehttp/_httplibcurl.cpp') diff --git a/indra/llcorehttp/_httplibcurl.cpp b/indra/llcorehttp/_httplibcurl.cpp index 05b2c2be69..332b6f3856 100644 --- a/indra/llcorehttp/_httplibcurl.cpp +++ b/indra/llcorehttp/_httplibcurl.cpp @@ -242,7 +242,7 @@ HttpService::ELoopSpeed HttpLibcurl::completeRequest(CURLM * multi_handle, CURL LL_WARNS("CoreHttp") << "URL op succeeded after " << op->mPolicyRetries << " retries." << LL_ENDL; } - + op->stageFromActive(mService); op->release(); return HttpService::REQUEST_SLEEP; -- cgit v1.2.3 From 89187229dd630845177ecd7a16e2b9cb01dc47ce Mon Sep 17 00:00:00 2001 From: Monty Brandenberg Date: Mon, 11 Jun 2012 15:28:06 -0400 Subject: Refactoring of the request completion thread and removal of 206/content-range hack in xport. Retry/response handling is decided in policy so moved that there. Removed special case 206-without-content-range response in transport. Have this sitation recognizable in the API and let callers deal with it as needed. --- indra/llcorehttp/_httplibcurl.cpp | 51 +++++++-------------------------------- 1 file changed, 9 insertions(+), 42 deletions(-) (limited to 'indra/llcorehttp/_httplibcurl.cpp') diff --git a/indra/llcorehttp/_httplibcurl.cpp b/indra/llcorehttp/_httplibcurl.cpp index 332b6f3856..e134a28401 100644 --- a/indra/llcorehttp/_httplibcurl.cpp +++ b/indra/llcorehttp/_httplibcurl.cpp @@ -113,8 +113,11 @@ HttpService::ELoopSpeed HttpLibcurl::processTransport() CURL * handle(msg->easy_handle); CURLcode result(msg->data.result); - HttpService::ELoopSpeed speed(completeRequest(mMultiHandles[policy_class], handle, result)); - ret = (std::min)(ret, speed); + if (completeRequest(mMultiHandles[policy_class], handle, result)) + { + // Request is still active, don't get too sleepy + ret = (std::min)(ret, HttpService::NORMAL); + } handle = NULL; // No longer valid on return } else if (CURLMSG_NONE == msg->msg) @@ -161,12 +164,8 @@ void HttpLibcurl::addOp(HttpOpRequest * op) } -HttpService::ELoopSpeed HttpLibcurl::completeRequest(CURLM * multi_handle, CURL * handle, CURLcode status) +bool HttpLibcurl::completeRequest(CURLM * multi_handle, CURL * handle, CURLcode status) { - static const HttpStatus cant_connect(HttpStatus::EXT_CURL_EASY, CURLE_COULDNT_CONNECT); - static const HttpStatus cant_res_proxy(HttpStatus::EXT_CURL_EASY, CURLE_COULDNT_RESOLVE_PROXY); - static const HttpStatus cant_res_host(HttpStatus::EXT_CURL_EASY, CURLE_COULDNT_RESOLVE_HOST); - HttpOpRequest * op(NULL); curl_easy_getinfo(handle, CURLINFO_PRIVATE, &op); // *FIXME: check the pointer @@ -209,43 +208,11 @@ HttpService::ELoopSpeed HttpLibcurl::completeRequest(CURLM * multi_handle, CURL curl_multi_remove_handle(multi_handle, handle); curl_easy_cleanup(handle); op->mCurlHandle = NULL; - - // Retry or finalize - if (! op->mStatus) - { - // If this failed, we might want to retry. Have to inspect - // the status a little more deeply for those reasons worth retrying... - if (op->mPolicyRetries < op->mPolicyRetryLimit && - ((op->mStatus.isHttpStatus() && op->mStatus.mType >= 499 && op->mStatus.mType <= 599) || - cant_connect == op->mStatus || - cant_res_proxy == op->mStatus || - cant_res_host == op->mStatus)) - { - // Okay, worth a retry. We include 499 in this test as - // it's the old 'who knows?' error from many grid services... - HttpPolicy & policy(mService->getPolicy()); - - policy.retryOp(op); - return HttpService::NORMAL; // Having pushed to retry, keep things running - } - } - // This op is done, finalize it delivering it to the reply queue... - if (! op->mStatus) - { - LL_WARNS("CoreHttp") << "URL op failed after " << op->mPolicyRetries - << " retries. Reason: " << op->mStatus.toString() - << LL_ENDL; - } - else if (op->mPolicyRetries) - { - LL_WARNS("CoreHttp") << "URL op succeeded after " << op->mPolicyRetries << " retries." - << LL_ENDL; - } + HttpPolicy & policy(mService->getPolicy()); + bool still_active(policy.stageAfterCompletion(op)); - op->stageFromActive(mService); - op->release(); - return HttpService::REQUEST_SLEEP; + return still_active; } -- cgit v1.2.3 From b08125a5874a89ce5210f8fb2c961ae17fb80fde Mon Sep 17 00:00:00 2001 From: Monty Brandenberg Date: Thu, 14 Jun 2012 16:31:48 -0400 Subject: LLMutex recursive lock, global & per-request tracing, simple GET request, LLProxy support, HttpOptions starting to work, HTTP resource waiting fixed. Non-LLThread-based threads need to do some registration or LLMutex locks taken out in these threads will not work as expected (SH-3154). We'll get a better solution later, this fixes some things for now. Tracing of operations now supported. Global and per-request (via HttpOptions) tracing levels of [0..3]. The 2 and 3 levels use libcurl's VERBOSE mode combined with CURLOPT_DEBUGFUNCTION to stream high levels of detail into the log. *Very* laggy but useful. Simple GET request supported (no Range: header). Really just a degenrate case of a ranged get but supplied an API anyway. Global option to use the LLProxy interface to setup CURL handles for either socks5 or http proxy usage. This isn't really the most encapsulated way to do this but a better solution will have to come later. The wantHeaders and tracing options are now supported in HttpOptions giving per-request controls. Big refactoring of the HTTP resource waiter in lltexturefetch. What I was doing before wasn't correct. Instead, I'm implementing the resource wait after the Semaphore model (though not using system semaphores). So instead of having a sequence like: SEND_HTTP_REQ -> WAIT_HTTP_RESOURCE -> SEND_HTTP_REQ, we now do WAIT_HTTP_RESOURCE -> WAIT_HTTP_RESOURCE2 (actual wait) -> SEND_HTTP_REQ. Works well but the prioritized filling of the corehttp library needs some performance work later. --- indra/llcorehttp/_httplibcurl.cpp | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'indra/llcorehttp/_httplibcurl.cpp') diff --git a/indra/llcorehttp/_httplibcurl.cpp b/indra/llcorehttp/_httplibcurl.cpp index e134a28401..a176dd5b2a 100644 --- a/indra/llcorehttp/_httplibcurl.cpp +++ b/indra/llcorehttp/_httplibcurl.cpp @@ -159,6 +159,17 @@ void HttpLibcurl::addOp(HttpOpRequest * op) curl_multi_add_handle(mMultiHandles[op->mReqPolicy], op->mCurlHandle); op->mCurlActive = true; + if (op->mTracing > 0) + { + HttpPolicy & policy(mService->getPolicy()); + + LL_INFOS("CoreHttp") << "TRACE, ToActiveQueue, Handle: " + << static_cast(op) + << ", Actives: " << mActiveOps.size() + << ", Readies: " << policy.getReadyCount(op->mReqPolicy) + << LL_ENDL; + } + // On success, make operation active mActiveOps.insert(op); } @@ -190,10 +201,9 @@ bool HttpLibcurl::completeRequest(CURLM * multi_handle, CURL * handle, CURLcode // Deactivate request op->mCurlActive = false; - // Set final status of request + // Set final status of request if it hasn't failed by other mechanisms yet if (op->mStatus) { - // Only set if it hasn't failed by other mechanisms yet op->mStatus = HttpStatus(HttpStatus::EXT_CURL_EASY, status); } if (op->mStatus) @@ -209,6 +219,16 @@ bool HttpLibcurl::completeRequest(CURLM * multi_handle, CURL * handle, CURLcode curl_easy_cleanup(handle); op->mCurlHandle = NULL; + // Tracing + if (op->mTracing > 0) + { + LL_INFOS("CoreHttp") << "TRACE, RequestComplete, Handle: " + << static_cast(op) + << ", Status: " << op->mStatus.toHex() + << LL_ENDL; + } + + // Dispatch to next stage HttpPolicy & policy(mService->getPolicy()); bool still_active(policy.stageAfterCompletion(op)); -- cgit v1.2.3 From a50944e078b98435685f04eda0ba93e95d4c61f2 Mon Sep 17 00:00:00 2001 From: Monty Brandenberg Date: Tue, 19 Jun 2012 17:01:02 -0400 Subject: Cleanup: move magic nubmers to new _httpinternal.h header file. --- indra/llcorehttp/_httplibcurl.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'indra/llcorehttp/_httplibcurl.cpp') diff --git a/indra/llcorehttp/_httplibcurl.cpp b/indra/llcorehttp/_httplibcurl.cpp index a176dd5b2a..65eb642056 100644 --- a/indra/llcorehttp/_httplibcurl.cpp +++ b/indra/llcorehttp/_httplibcurl.cpp @@ -31,6 +31,8 @@ #include "_httpoprequest.h" #include "_httppolicy.h" +#include "llhttpstatuscodes.h" + namespace LLCore { @@ -39,7 +41,8 @@ namespace LLCore HttpLibcurl::HttpLibcurl(HttpService * service) : mService(service) { - for (int policy_class(0); policy_class < HttpRequest::POLICY_CLASS_LIMIT; ++policy_class) + // *FIXME: Use active policy class count later + for (int policy_class(0); policy_class < LL_ARRAY_SIZE(mMultiHandles); ++policy_class) { mMultiHandles[policy_class] = 0; } @@ -61,7 +64,7 @@ HttpLibcurl::~HttpLibcurl() mActiveOps.erase(item); } - for (int policy_class(0); policy_class < HttpRequest::POLICY_CLASS_LIMIT; ++policy_class) + for (int policy_class(0); policy_class < LL_ARRAY_SIZE(mMultiHandles); ++policy_class) { if (mMultiHandles[policy_class]) { @@ -89,7 +92,7 @@ HttpService::ELoopSpeed HttpLibcurl::processTransport() HttpService::ELoopSpeed ret(HttpService::REQUEST_SLEEP); // Give libcurl some cycles to do I/O & callbacks - for (int policy_class(0); policy_class < HttpRequest::POLICY_CLASS_LIMIT; ++policy_class) + for (int policy_class(0); policy_class < LL_ARRAY_SIZE(mMultiHandles); ++policy_class) { if (! mMultiHandles[policy_class]) continue; @@ -144,7 +147,7 @@ HttpService::ELoopSpeed HttpLibcurl::processTransport() void HttpLibcurl::addOp(HttpOpRequest * op) { - llassert_always(op->mReqPolicy < HttpRequest::POLICY_CLASS_LIMIT); + llassert_always(op->mReqPolicy < POLICY_CLASS_LIMIT); llassert_always(mMultiHandles[op->mReqPolicy] != NULL); // Create standard handle @@ -159,7 +162,7 @@ void HttpLibcurl::addOp(HttpOpRequest * op) curl_multi_add_handle(mMultiHandles[op->mReqPolicy], op->mCurlHandle); op->mCurlActive = true; - if (op->mTracing > 0) + if (op->mTracing > TRACE_OFF) { HttpPolicy & policy(mService->getPolicy()); @@ -208,7 +211,7 @@ bool HttpLibcurl::completeRequest(CURLM * multi_handle, CURL * handle, CURLcode } if (op->mStatus) { - int http_status(200); + int http_status(HTTP_OK); curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &http_status); op->mStatus = LLCore::HttpStatus(http_status); @@ -220,7 +223,7 @@ bool HttpLibcurl::completeRequest(CURLM * multi_handle, CURL * handle, CURLcode op->mCurlHandle = NULL; // Tracing - if (op->mTracing > 0) + if (op->mTracing > TRACE_OFF) { LL_INFOS("CoreHttp") << "TRACE, RequestComplete, Handle: " << static_cast(op) -- cgit v1.2.3 From bc7d5b24d16963a2715e880c518a4706a99f02fa Mon Sep 17 00:00:00 2001 From: Monty Brandenberg Date: Fri, 22 Jun 2012 19:13:50 -0400 Subject: This sets down the groundwork for dynamic policy classes. Groundwork is used for the default class which currently represents texture fetching. Class options implemented from API user into HttpLibcurl. Policy layer is going to start doing some traffic shaping like work to solve problems with consumer-grade gear. Need to have dynamic aspects to policies and that starts now... --- indra/llcorehttp/_httplibcurl.cpp | 51 ++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 19 deletions(-) (limited to 'indra/llcorehttp/_httplibcurl.cpp') diff --git a/indra/llcorehttp/_httplibcurl.cpp b/indra/llcorehttp/_httplibcurl.cpp index 65eb642056..45e16d420e 100644 --- a/indra/llcorehttp/_httplibcurl.cpp +++ b/indra/llcorehttp/_httplibcurl.cpp @@ -39,17 +39,10 @@ namespace LLCore HttpLibcurl::HttpLibcurl(HttpService * service) - : mService(service) -{ - // *FIXME: Use active policy class count later - for (int policy_class(0); policy_class < LL_ARRAY_SIZE(mMultiHandles); ++policy_class) - { - mMultiHandles[policy_class] = 0; - } - - // Create multi handle for default class - mMultiHandles[0] = curl_multi_init(); -} + : mService(service), + mPolicyCount(0), + mMultiHandles(NULL) +{} HttpLibcurl::~HttpLibcurl() @@ -64,17 +57,23 @@ HttpLibcurl::~HttpLibcurl() mActiveOps.erase(item); } - for (int policy_class(0); policy_class < LL_ARRAY_SIZE(mMultiHandles); ++policy_class) + if (mMultiHandles) { - if (mMultiHandles[policy_class]) + for (int policy_class(0); policy_class < mPolicyCount; ++policy_class) { - // *FIXME: Do some multi cleanup here first + if (mMultiHandles[policy_class]) + { + // *FIXME: Do some multi cleanup here first - curl_multi_cleanup(mMultiHandles[policy_class]); - mMultiHandles[policy_class] = 0; + curl_multi_cleanup(mMultiHandles[policy_class]); + mMultiHandles[policy_class] = 0; + } } - } + delete [] mMultiHandles; + mMultiHandles = NULL; + } + mService = NULL; } @@ -87,12 +86,26 @@ void HttpLibcurl::term() {} +void HttpLibcurl::setPolicyCount(int policy_count) +{ + llassert_always(policy_count <= POLICY_CLASS_LIMIT); + llassert_always(! mMultiHandles); // One-time call only + + mPolicyCount = policy_count; + mMultiHandles = new CURLM * [mPolicyCount]; + for (int policy_class(0); policy_class < mPolicyCount; ++policy_class) + { + mMultiHandles[policy_class] = curl_multi_init(); + } +} + + HttpService::ELoopSpeed HttpLibcurl::processTransport() { HttpService::ELoopSpeed ret(HttpService::REQUEST_SLEEP); // Give libcurl some cycles to do I/O & callbacks - for (int policy_class(0); policy_class < LL_ARRAY_SIZE(mMultiHandles); ++policy_class) + for (int policy_class(0); policy_class < mPolicyCount; ++policy_class) { if (! mMultiHandles[policy_class]) continue; @@ -147,7 +160,7 @@ HttpService::ELoopSpeed HttpLibcurl::processTransport() void HttpLibcurl::addOp(HttpOpRequest * op) { - llassert_always(op->mReqPolicy < POLICY_CLASS_LIMIT); + llassert_always(op->mReqPolicy < mPolicyCount); llassert_always(mMultiHandles[op->mReqPolicy] != NULL); // Create standard handle -- cgit v1.2.3 From e172ec84fa217aae8d1e51c1e0673322c30891fe Mon Sep 17 00:00:00 2001 From: Monty Brandenberg Date: Sat, 23 Jun 2012 23:33:50 -0400 Subject: SH-3184/SH-3221 Improve cleanup, destructor, thread termination, etc. logic in library. With this commit, the cleanup paths should be production quality. Unit tests have been expanded to include cases requiring thread termination and cleanup by the worker thread. Special operation/request added to support the unit tests. Thread interface expanded to include a very aggressive cancel() method that does not do cleanup but prevents the thread from accessing objects that will be destroyed. --- indra/llcorehttp/_httplibcurl.cpp | 97 ++++++++++++++++++++++++++++----------- 1 file changed, 69 insertions(+), 28 deletions(-) (limited to 'indra/llcorehttp/_httplibcurl.cpp') diff --git a/indra/llcorehttp/_httplibcurl.cpp b/indra/llcorehttp/_httplibcurl.cpp index 45e16d420e..bc8b3cc9be 100644 --- a/indra/llcorehttp/_httplibcurl.cpp +++ b/indra/llcorehttp/_httplibcurl.cpp @@ -47,12 +47,19 @@ HttpLibcurl::HttpLibcurl(HttpService * service) HttpLibcurl::~HttpLibcurl() { - // *FIXME: need to cancel requests in this class, not in op class. + shutdown(); + + mService = NULL; +} + + +void HttpLibcurl::shutdown() +{ while (! mActiveOps.empty()) { active_set_t::iterator item(mActiveOps.begin()); - (*item)->cancel(); + cancelRequest(*item); (*item)->release(); mActiveOps.erase(item); } @@ -63,8 +70,6 @@ HttpLibcurl::~HttpLibcurl() { if (mMultiHandles[policy_class]) { - // *FIXME: Do some multi cleanup here first - curl_multi_cleanup(mMultiHandles[policy_class]); mMultiHandles[policy_class] = 0; } @@ -73,20 +78,12 @@ HttpLibcurl::~HttpLibcurl() delete [] mMultiHandles; mMultiHandles = NULL; } - - mService = NULL; -} - -void HttpLibcurl::init() -{} - - -void HttpLibcurl::term() -{} + mPolicyCount = 0; +} -void HttpLibcurl::setPolicyCount(int policy_count) +void HttpLibcurl::start(int policy_count) { llassert_always(policy_count <= POLICY_CLASS_LIMIT); llassert_always(! mMultiHandles); // One-time call only @@ -143,8 +140,9 @@ HttpService::ELoopSpeed HttpLibcurl::processTransport() } else { - // *FIXME: Issue a logging event for this. - ; + LL_WARNS_ONCE("CoreHttp") << "Unexpected message from libcurl. Msg code: " + << msg->msg + << LL_ENDL; } msgs_in_queue = 0; } @@ -191,30 +189,61 @@ void HttpLibcurl::addOp(HttpOpRequest * op) } +// *NOTE: cancelRequest logic parallels completeRequest logic. +// Keep them synchronized as necessary. Caller is expected to +// remove to op from the active list and release the op *after* +// calling this method. It must be called first to deliver the +// op to the reply queue with refcount intact. +void HttpLibcurl::cancelRequest(HttpOpRequest * op) +{ + // Deactivate request + op->mCurlActive = false; + + // Detach from multi and recycle handle + curl_multi_remove_handle(mMultiHandles[op->mReqPolicy], op->mCurlHandle); + curl_easy_cleanup(op->mCurlHandle); + op->mCurlHandle = NULL; + + // Tracing + if (op->mTracing > TRACE_OFF) + { + LL_INFOS("CoreHttp") << "TRACE, RequestCanceled, Handle: " + << static_cast(op) + << ", Status: " << op->mStatus.toHex() + << LL_ENDL; + } + + // Cancel op and deliver for notification + op->cancel(); +} + + +// *NOTE: cancelRequest logic parallels completeRequest logic. +// Keep them synchronized as necessary. bool HttpLibcurl::completeRequest(CURLM * multi_handle, CURL * handle, CURLcode status) { HttpOpRequest * op(NULL); curl_easy_getinfo(handle, CURLINFO_PRIVATE, &op); - // *FIXME: check the pointer if (handle != op->mCurlHandle || ! op->mCurlActive) { - // *FIXME: This is a sanity check that needs validation/termination. - ; + LL_WARNS("CoreHttp") << "libcurl handle and HttpOpRequest handle in disagreement or inactive request." + << " Handle: " << static_cast(handle) + << LL_ENDL; + return false; } active_set_t::iterator it(mActiveOps.find(op)); if (mActiveOps.end() == it) { - // *FIXME: Fatal condition. This must be here. - ; - } - else - { - mActiveOps.erase(it); + LL_WARNS("CoreHttp") << "libcurl completion for request not on active list. Continuing." + << " Handle: " << static_cast(handle) + << LL_ENDL; + return false; } // Deactivate request + mActiveOps.erase(it); op->mCurlActive = false; // Set final status of request if it hasn't failed by other mechanisms yet @@ -258,9 +287,21 @@ int HttpLibcurl::getActiveCount() const } -int HttpLibcurl::getActiveCountInClass(int /* policy_class */) const +int HttpLibcurl::getActiveCountInClass(int policy_class) const { - return getActiveCount(); + int count(0); + + for (active_set_t::const_iterator iter(mActiveOps.begin()); + mActiveOps.end() != iter; + ++iter) + { + if ((*iter)->mReqPolicy == policy_class) + { + ++count; + } + } + + return count; } -- cgit v1.2.3 From e8b0088d1a0c02bfa1f9768dc91fc3df4322adae Mon Sep 17 00:00:00 2001 From: Monty Brandenberg Date: Tue, 26 Jun 2012 12:28:58 -0400 Subject: SH-3184/SH-3221 More work on cleanup with better unit test work and more aggressive shutdown of a thread. Some additional work let me enable a memory check for the clean shutdown case and generally do a better job on other interfaces. Request queue waiters now awake on shutdown and don't sleep once the queue is turned off. Much better semantically for how this will be used. --- indra/llcorehttp/_httplibcurl.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'indra/llcorehttp/_httplibcurl.cpp') diff --git a/indra/llcorehttp/_httplibcurl.cpp b/indra/llcorehttp/_httplibcurl.cpp index bc8b3cc9be..39abca12c5 100644 --- a/indra/llcorehttp/_httplibcurl.cpp +++ b/indra/llcorehttp/_httplibcurl.cpp @@ -57,11 +57,11 @@ void HttpLibcurl::shutdown() { while (! mActiveOps.empty()) { - active_set_t::iterator item(mActiveOps.begin()); + HttpOpRequest * op(* mActiveOps.begin()); + mActiveOps.erase(mActiveOps.begin()); - cancelRequest(*item); - (*item)->release(); - mActiveOps.erase(item); + cancelRequest(op); + op->release(); } if (mMultiHandles) -- cgit v1.2.3 From 2d7b7de20327a40be12a620debaae9917af16cd6 Mon Sep 17 00:00:00 2001 From: Monty Brandenberg Date: Tue, 3 Jul 2012 13:06:46 -0400 Subject: More integration work for texture fetch timeouts. The fetch state machine received a new timeout during the WAIT_HTTP_REQ state. For the integration, rather than jump the state to done, we issue a request cancel and let the notification plumbing do the rest without any race conditions or special-case logic. --- indra/llcorehttp/_httplibcurl.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'indra/llcorehttp/_httplibcurl.cpp') diff --git a/indra/llcorehttp/_httplibcurl.cpp b/indra/llcorehttp/_httplibcurl.cpp index 39abca12c5..3c69ae1c96 100644 --- a/indra/llcorehttp/_httplibcurl.cpp +++ b/indra/llcorehttp/_httplibcurl.cpp @@ -189,6 +189,30 @@ void HttpLibcurl::addOp(HttpOpRequest * op) } +// Implements the transport part of any cancel operation. +// See if the handle is an active operation and if so, +// use the more complicated transport-based cancelation +// method to kill the request. +bool HttpLibcurl::cancel(HttpHandle handle) +{ + HttpOpRequest * op(static_cast(handle)); + active_set_t::iterator it(mActiveOps.find(op)); + if (mActiveOps.end() == it) + { + return false; + } + + // Cancel request + cancelRequest(op); + + // Drop references + mActiveOps.erase(it); + op->release(); + + return true; +} + + // *NOTE: cancelRequest logic parallels completeRequest logic. // Keep them synchronized as necessary. Caller is expected to // remove to op from the active list and release the op *after* -- cgit v1.2.3 From d238341afaecedfe227141126c4c35dcde4a0671 Mon Sep 17 00:00:00 2001 From: Monty Brandenberg Date: Mon, 16 Jul 2012 11:53:04 -0400 Subject: SH-3189 Remove/improve naive data structures When releasing HTTP waiters, avoid unnecessary sort activity. For Content-Type in responses, let libcurl do the work and removed my parsing of headers. Drop Content-Encoding as libcurl will deal with that. If anyone is interested, they can parse. --- indra/llcorehttp/_httplibcurl.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'indra/llcorehttp/_httplibcurl.cpp') diff --git a/indra/llcorehttp/_httplibcurl.cpp b/indra/llcorehttp/_httplibcurl.cpp index 3c69ae1c96..e031efbc91 100644 --- a/indra/llcorehttp/_httplibcurl.cpp +++ b/indra/llcorehttp/_httplibcurl.cpp @@ -280,7 +280,23 @@ bool HttpLibcurl::completeRequest(CURLM * multi_handle, CURL * handle, CURLcode int http_status(HTTP_OK); curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &http_status); - op->mStatus = LLCore::HttpStatus(http_status); + if (http_status >= 100 && http_status <= 999) + { + char * cont_type(NULL); + curl_easy_getinfo(handle, CURLINFO_CONTENT_TYPE, &cont_type); + if (cont_type) + { + op->mReplyConType = cont_type; + } + op->mStatus = HttpStatus(http_status); + } + else + { + LL_WARNS("CoreHttp") << "Invalid HTTP response code (" + << http_status << ") received from server." + << LL_ENDL; + op->mStatus = HttpStatus(HttpStatus::LLCORE, HE_INVALID_HTTP_STATUS); + } } // Detach from multi and recycle handle -- cgit v1.2.3 From 85e69b043b098dbe5a09f2eac6ff541123089f13 Mon Sep 17 00:00:00 2001 From: Monty Brandenberg Date: Mon, 23 Jul 2012 23:40:07 +0000 Subject: Big comment and naming cleanup. Ready for prime-time. Add to-do list to _httpinternal.h to guide anyone who wants to pitch in and help. --- indra/llcorehttp/_httplibcurl.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'indra/llcorehttp/_httplibcurl.cpp') diff --git a/indra/llcorehttp/_httplibcurl.cpp b/indra/llcorehttp/_httplibcurl.cpp index e031efbc91..4e2e3f0e0e 100644 --- a/indra/llcorehttp/_httplibcurl.cpp +++ b/indra/llcorehttp/_httplibcurl.cpp @@ -85,7 +85,7 @@ void HttpLibcurl::shutdown() void HttpLibcurl::start(int policy_count) { - llassert_always(policy_count <= POLICY_CLASS_LIMIT); + llassert_always(policy_count <= HTTP_POLICY_CLASS_LIMIT); llassert_always(! mMultiHandles); // One-time call only mPolicyCount = policy_count; @@ -156,6 +156,7 @@ HttpService::ELoopSpeed HttpLibcurl::processTransport() } +// Caller has provided us with a ref count on op. void HttpLibcurl::addOp(HttpOpRequest * op) { llassert_always(op->mReqPolicy < mPolicyCount); @@ -165,7 +166,7 @@ void HttpLibcurl::addOp(HttpOpRequest * op) if (! op->prepareRequest(mService)) { // Couldn't issue request, fail with notification - // *FIXME: Need failure path + // *TODO: Need failure path return; } @@ -173,7 +174,7 @@ void HttpLibcurl::addOp(HttpOpRequest * op) curl_multi_add_handle(mMultiHandles[op->mReqPolicy], op->mCurlHandle); op->mCurlActive = true; - if (op->mTracing > TRACE_OFF) + if (op->mTracing > HTTP_TRACE_OFF) { HttpPolicy & policy(mService->getPolicy()); @@ -215,7 +216,7 @@ bool HttpLibcurl::cancel(HttpHandle handle) // *NOTE: cancelRequest logic parallels completeRequest logic. // Keep them synchronized as necessary. Caller is expected to -// remove to op from the active list and release the op *after* +// remove the op from the active list and release the op *after* // calling this method. It must be called first to deliver the // op to the reply queue with refcount intact. void HttpLibcurl::cancelRequest(HttpOpRequest * op) @@ -229,7 +230,7 @@ void HttpLibcurl::cancelRequest(HttpOpRequest * op) op->mCurlHandle = NULL; // Tracing - if (op->mTracing > TRACE_OFF) + if (op->mTracing > HTTP_TRACE_OFF) { LL_INFOS("CoreHttp") << "TRACE, RequestCanceled, Handle: " << static_cast(op) @@ -305,7 +306,7 @@ bool HttpLibcurl::completeRequest(CURLM * multi_handle, CURL * handle, CURLcode op->mCurlHandle = NULL; // Tracing - if (op->mTracing > TRACE_OFF) + if (op->mTracing > HTTP_TRACE_OFF) { LL_INFOS("CoreHttp") << "TRACE, RequestComplete, Handle: " << static_cast(op) -- cgit v1.2.3 From bf004be1023347bcabaae6baa1624b2ed78d69fd Mon Sep 17 00:00:00 2001 From: Monty Brandenberg Date: Wed, 1 Aug 2012 12:38:28 -0400 Subject: SH-3308 Beef up retry messaging. Reformatted messages around request retry. Successfully retried requests also message so you can see the cycle closed. Added additional retryable error codes (timeout, other libcurl failures). Commenting and removed some unnecessary std::min logic. --- indra/llcorehttp/_httplibcurl.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'indra/llcorehttp/_httplibcurl.cpp') diff --git a/indra/llcorehttp/_httplibcurl.cpp b/indra/llcorehttp/_httplibcurl.cpp index 4e2e3f0e0e..6fe0bfc7d1 100644 --- a/indra/llcorehttp/_httplibcurl.cpp +++ b/indra/llcorehttp/_httplibcurl.cpp @@ -97,6 +97,12 @@ void HttpLibcurl::start(int policy_count) } +// Give libcurl some cycles, invoke it's callbacks, process +// completed requests finalizing or issuing retries as needed. +// +// If active list goes empty *and* we didn't queue any +// requests for retry, we return a request for a hard +// sleep otherwise ask for a normal polling interval. HttpService::ELoopSpeed HttpLibcurl::processTransport() { HttpService::ELoopSpeed ret(HttpService::REQUEST_SLEEP); @@ -129,7 +135,7 @@ HttpService::ELoopSpeed HttpLibcurl::processTransport() if (completeRequest(mMultiHandles[policy_class], handle, result)) { // Request is still active, don't get too sleepy - ret = (std::min)(ret, HttpService::NORMAL); + ret = HttpService::NORMAL; } handle = NULL; // No longer valid on return } @@ -150,7 +156,7 @@ HttpService::ELoopSpeed HttpLibcurl::processTransport() if (! mActiveOps.empty()) { - ret = (std::min)(ret, HttpService::NORMAL); + ret = HttpService::NORMAL; } return ret; } -- cgit v1.2.3