summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMonty Brandenberg <monty@lindenlab.com>2012-07-16 11:53:04 -0400
committerMonty Brandenberg <monty@lindenlab.com>2012-07-16 11:53:04 -0400
commitd238341afaecedfe227141126c4c35dcde4a0671 (patch)
treeb1c3140fdd357c67abbc75d09846ce7c21678b69
parent5eb5dc6b27c57f1c3e77fc04b471614968620068 (diff)
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.
-rw-r--r--indra/llcorehttp/_httplibcurl.cpp18
-rw-r--r--indra/llcorehttp/_httpoprequest.cpp48
-rw-r--r--indra/llcorehttp/_httpoprequest.h2
-rw-r--r--indra/llcorehttp/httpcommon.cpp3
-rw-r--r--indra/llcorehttp/httpcommon.h5
-rw-r--r--indra/llcorehttp/httpresponse.h9
-rw-r--r--indra/llcorehttp/tests/test_httprequest.hpp3
-rwxr-xr-xindra/newview/lltexturefetch.cpp22
8 files changed, 48 insertions, 62 deletions
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
diff --git a/indra/llcorehttp/_httpoprequest.cpp b/indra/llcorehttp/_httpoprequest.cpp
index 1854d7ada4..1a770f67be 100644
--- a/indra/llcorehttp/_httpoprequest.cpp
+++ b/indra/llcorehttp/_httpoprequest.cpp
@@ -228,7 +228,7 @@ void HttpOpRequest::visitNotifier(HttpRequest * request)
// Got an explicit offset/length in response
response->setRange(mReplyOffset, mReplyLength, mReplyFullLength);
}
- response->setContent(mReplyConType, mReplyConEncode);
+ response->setContentType(mReplyConType);
mUserHandler->onCompleted(static_cast<HttpHandle>(this), response);
@@ -316,7 +316,7 @@ void HttpOpRequest::setupCommon(HttpRequest::policy_t policy_id,
HttpOptions * options,
HttpHeaders * headers)
{
- mProcFlags = PF_SCAN_CONTENT_HEADERS; // Always scan for content headers
+ mProcFlags = 0U;
mReqPolicy = policy_id;
mReqPriority = priority;
mReqURL = url;
@@ -379,7 +379,6 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
mReplyHeaders = NULL;
}
mReplyConType.clear();
- mReplyConEncode.clear();
// *FIXME: better error handling later
HttpStatus status;
@@ -542,7 +541,7 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
}
curl_easy_setopt(mCurlHandle, CURLOPT_HTTPHEADER, mCurlHeaders);
- if (mProcFlags & (PF_SCAN_RANGE_HEADER | PF_SAVE_HEADERS | PF_SCAN_CONTENT_HEADERS))
+ if (mProcFlags & (PF_SCAN_RANGE_HEADER | PF_SAVE_HEADERS))
{
curl_easy_setopt(mCurlHandle, CURLOPT_HEADERFUNCTION, headerCallback);
curl_easy_setopt(mCurlHandle, CURLOPT_HEADERDATA, this);
@@ -620,8 +619,6 @@ size_t HttpOpRequest::headerCallback(void * data, size_t size, size_t nmemb, voi
op->mReplyOffset = 0;
op->mReplyLength = 0;
op->mReplyFullLength = 0;
- op->mReplyConType.clear();
- op->mReplyConEncode.clear();
op->mStatus = HttpStatus();
if (op->mReplyHeaders)
{
@@ -688,45 +685,6 @@ size_t HttpOpRequest::headerCallback(void * data, size_t size, size_t nmemb, voi
}
}
- // Detect and parse 'Content-Type' and 'Content-Encoding' headers
- if (op->mProcFlags & PF_SCAN_CONTENT_HEADERS)
- {
- if (wanted_hdr_size > con_type_line_len &&
- ! os_strncasecmp(hdr_data, con_type_line, con_type_line_len))
- {
- // Found 'Content-Type:', extract single-token value
- std::string rhs(hdr_data + con_type_line_len, wanted_hdr_size - con_type_line_len);
- std::string::size_type begin(0), end(rhs.size()), pos;
-
- if ((pos = rhs.find_first_not_of(hdr_whitespace)) != std::string::npos)
- {
- begin = pos;
- }
- if ((pos = rhs.find_first_of(hdr_whitespace, begin)) != std::string::npos)
- {
- end = pos;
- }
- op->mReplyConType.assign(rhs, begin, end - begin);
- }
- else if (wanted_hdr_size > con_enc_line_len &&
- ! os_strncasecmp(hdr_data, con_enc_line, con_enc_line_len))
- {
- // Found 'Content-Encoding:', extract single-token value
- std::string rhs(hdr_data + con_enc_line_len, wanted_hdr_size - con_enc_line_len);
- std::string::size_type begin(0), end(rhs.size()), pos;
-
- if ((pos = rhs.find_first_not_of(hdr_whitespace)) != std::string::npos)
- {
- begin = pos;
- }
- if ((pos = rhs.find_first_of(hdr_whitespace, begin)) != std::string::npos)
- {
- end = pos;
- }
- op->mReplyConEncode.assign(rhs, begin, end - begin);
- }
- }
-
return hdr_size;
}
diff --git a/indra/llcorehttp/_httpoprequest.h b/indra/llcorehttp/_httpoprequest.h
index 200b925c4e..36dc5dc876 100644
--- a/indra/llcorehttp/_httpoprequest.h
+++ b/indra/llcorehttp/_httpoprequest.h
@@ -138,7 +138,6 @@ protected:
unsigned int mProcFlags;
static const unsigned int PF_SCAN_RANGE_HEADER = 0x00000001U;
static const unsigned int PF_SAVE_HEADERS = 0x00000002U;
- static const unsigned int PF_SCAN_CONTENT_HEADERS = 0x00000004U;
public:
// Request data
@@ -165,7 +164,6 @@ public:
size_t mReplyFullLength;
HttpHeaders * mReplyHeaders;
std::string mReplyConType;
- std::string mReplyConEncode;
// Policy data
int mPolicyRetries;
diff --git a/indra/llcorehttp/httpcommon.cpp b/indra/llcorehttp/httpcommon.cpp
index 1b18976359..f2fcbf77a3 100644
--- a/indra/llcorehttp/httpcommon.cpp
+++ b/indra/llcorehttp/httpcommon.cpp
@@ -69,7 +69,8 @@ std::string HttpStatus::toString() const
"Request handle not found",
"Invalid datatype for argument or option",
"Option has not been explicitly set",
- "Option is not dynamic and must be set early"
+ "Option is not dynamic and must be set early",
+ "Invalid HTTP status code received from server"
};
static const int llcore_errors_count(sizeof(llcore_errors) / sizeof(llcore_errors[0]));
diff --git a/indra/llcorehttp/httpcommon.h b/indra/llcorehttp/httpcommon.h
index 576a113e54..dd5798edf9 100644
--- a/indra/llcorehttp/httpcommon.h
+++ b/indra/llcorehttp/httpcommon.h
@@ -149,7 +149,10 @@ enum HttpError
HE_OPT_NOT_SET = 7,
// Option not dynamic, must be set during init phase
- HE_OPT_NOT_DYNAMIC = 8
+ HE_OPT_NOT_DYNAMIC = 8,
+
+ // Invalid HTTP status code returned by server
+ HE_INVALID_HTTP_STATUS = 9
}; // end enum HttpError
diff --git a/indra/llcorehttp/httpresponse.h b/indra/llcorehttp/httpresponse.h
index 3d35050c17..4a481db6ac 100644
--- a/indra/llcorehttp/httpresponse.h
+++ b/indra/llcorehttp/httpresponse.h
@@ -134,16 +134,14 @@ public:
}
///
- void getContent(std::string & con_type, std::string & con_encode) const
+ const std::string & getContentType() const
{
- con_type = mContentType;
- con_encode = mContentEncoding;
+ return mContentType;
}
- void setContent(const std::string & con_type, const std::string & con_encode)
+ void setContentType(const std::string & con_type)
{
mContentType = con_type;
- mContentEncoding = con_encode;
}
protected:
@@ -155,7 +153,6 @@ protected:
BufferArray * mBufferArray;
HttpHeaders * mHeaders;
std::string mContentType;
- std::string mContentEncoding;
};
diff --git a/indra/llcorehttp/tests/test_httprequest.hpp b/indra/llcorehttp/tests/test_httprequest.hpp
index 0f9eb93996..1acf4f9d4b 100644
--- a/indra/llcorehttp/tests/test_httprequest.hpp
+++ b/indra/llcorehttp/tests/test_httprequest.hpp
@@ -147,8 +147,7 @@ public:
if (! mCheckContentType.empty())
{
ensure("Response required with content type check", response != NULL);
- std::string con_type, con_enc;
- response->getContent(con_type, con_enc);
+ std::string con_type(response->getContentType());
ensure("Content-Type as expected (" + mCheckContentType + ")",
mCheckContentType == con_type);
}
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index 8314031f14..225ea46558 100755
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -3342,6 +3342,17 @@ void LLTextureFetch::removeHttpWaiter(const LLUUID & tid)
mNetworkQueueMutex.unlock(); // -Mfnq
}
+// Release as many requests as permitted from the WAIT_HTTP_RESOURCE2
+// state to the SEND_HTTP_REQ state based on their current priority.
+//
+// This data structures and code associated with this looks a bit
+// indirect and naive but it's done in the name of safety. An
+// ordered container may become invalid from time to time due to
+// priority changes caused by actions in other threads. State itself
+// could also suffer the same fate with canceled operations. Even
+// done this way, I'm not fully trusting we're truly safe. This
+// module is due for a major refactoring and we'll deal with it then.
+//
// Threads: Ttf
// Locks: -Mw (must not hold any worker when called)
void LLTextureFetch::releaseHttpWaiters()
@@ -3384,12 +3395,15 @@ void LLTextureFetch::releaseHttpWaiters()
tids2.push_back(worker);
}
}
-
- // Sort into priority order
- LLTextureFetchWorker::Compare compare;
- std::sort(tids2.begin(), tids2.end(), compare);
tids.clear();
+ // Sort into priority order, if necessary and only as much as needed
+ if (tids2.size() > mHttpSemaphore)
+ {
+ LLTextureFetchWorker::Compare compare;
+ std::partial_sort(tids2.begin(), tids2.begin() + mHttpSemaphore, tids2.end(), compare);
+ }
+
// Release workers up to the high water mark. Since we aren't
// holding any locks at this point, we can be in competition
// with other callers. Do defensive things like getting