From aba4f7ddc89c9d28bdd4b02735134101f40634ed Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Mon, 20 Jun 2011 14:01:32 -0600 Subject: fix for SH-1870: can not upload book_collection_1.dae when include textures --- indra/llmessage/llcurl.cpp | 14 +++++++------- indra/llmessage/llcurl.h | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'indra/llmessage') diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index 7c8b7e3584..44330cf8ff 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -244,7 +244,7 @@ public: U32 report(CURLcode); void getTransferInfo(LLCurl::TransferInfo* info); - void prepRequest(const std::string& url, const std::vector& headers, ResponderPtr, bool post = false); + void prepRequest(const std::string& url, const std::vector& headers, ResponderPtr, S32 time_out = 0, bool post = false); const char* getErrorBuffer(); @@ -525,7 +525,7 @@ size_t curlHeaderCallback(void* data, size_t size, size_t nmemb, void* user_data void LLCurl::Easy::prepRequest(const std::string& url, const std::vector& headers, - ResponderPtr responder, bool post) + ResponderPtr responder, S32 time_out, bool post) { resetState(); @@ -558,7 +558,7 @@ void LLCurl::Easy::prepRequest(const std::string& url, //don't verify host name so urls with scrubbed host names will work (improves DNS performance) setopt(CURLOPT_SSL_VERIFYHOST, 0); - setopt(CURLOPT_TIMEOUT, CURL_REQUEST_TIMEOUT); + setopt(CURLOPT_TIMEOUT, llmax(time_out, CURL_REQUEST_TIMEOUT)); setoptString(CURLOPT_URL, url); @@ -855,14 +855,14 @@ bool LLCurlRequest::getByteRange(const std::string& url, bool LLCurlRequest::post(const std::string& url, const headers_t& headers, const LLSD& data, - LLCurl::ResponderPtr responder) + LLCurl::ResponderPtr responder, S32 time_out) { LLCurl::Easy* easy = allocEasy(); if (!easy) { return false; } - easy->prepRequest(url, headers, responder); + easy->prepRequest(url, headers, responder, time_out); LLSDSerialize::toXML(data, easy->getInput()); S32 bytes = easy->getInput().str().length(); @@ -882,14 +882,14 @@ bool LLCurlRequest::post(const std::string& url, bool LLCurlRequest::post(const std::string& url, const headers_t& headers, const std::string& data, - LLCurl::ResponderPtr responder) + LLCurl::ResponderPtr responder, S32 time_out) { LLCurl::Easy* easy = allocEasy(); if (!easy) { return false; } - easy->prepRequest(url, headers, responder); + easy->prepRequest(url, headers, responder, time_out); easy->getInput().write(data.data(), data.size()); S32 bytes = easy->getInput().str().length(); diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h index 4ce3fa1078..5833a27b84 100644 --- a/indra/llmessage/llcurl.h +++ b/indra/llmessage/llcurl.h @@ -201,8 +201,8 @@ public: void get(const std::string& url, LLCurl::ResponderPtr responder); bool getByteRange(const std::string& url, const headers_t& headers, S32 offset, S32 length, LLCurl::ResponderPtr responder); - bool post(const std::string& url, const headers_t& headers, const LLSD& data, LLCurl::ResponderPtr responder); - bool post(const std::string& url, const headers_t& headers, const std::string& data, LLCurl::ResponderPtr responder); + bool post(const std::string& url, const headers_t& headers, const LLSD& data, LLCurl::ResponderPtr responder, S32 time_out = 0); + bool post(const std::string& url, const headers_t& headers, const std::string& data, LLCurl::ResponderPtr responder, S32 time_out = 0); S32 process(); S32 getQueued(); -- cgit v1.2.3 From cd923af21f4fa6e251dea47ffb53ace934a382d1 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 28 Jul 2011 00:26:30 -0500 Subject: SH-2183 Fix for multi-threaded curl not playing nice with mesh upload. --- indra/llmessage/llcurl.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'indra/llmessage') diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index 9484f572f6..b7208f3e19 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -1006,6 +1006,10 @@ S32 LLCurlRequest::getQueued() curlmulti_set_t::iterator curiter = iter++; LLCurl::Multi* multi = *curiter; queued += multi->mQueued; + if (multi->mPerformState != LLCurl::Multi::PERFORM_STATE_READY) + { + ++queued; + } } return queued; } -- cgit v1.2.3 From fbd5bd7adc205acecc49c7e9887efa3bca6552d0 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 1 Aug 2011 17:50:43 -0500 Subject: SH-2183 Add a debug setting to control whether or not to use multiple threads in LLCurl --- indra/llmessage/llcurl.cpp | 101 +++++++++++++++++++++++++++++++-------------- indra/llmessage/llcurl.h | 4 +- 2 files changed, 74 insertions(+), 31 deletions(-) (limited to 'indra/llmessage') diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index b7208f3e19..ece539bb48 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -26,6 +26,7 @@ * $/LicenseInfo$ */ + #if LL_WINDOWS #define SAFE_SSL 1 #elif LL_DARWIN @@ -84,6 +85,8 @@ S32 gCurlMultiCount = 0; std::vector LLCurl::sSSLMutex; std::string LLCurl::sCAPath; std::string LLCurl::sCAFile; +bool LLCurl::sMultiThreaded = false; + void check_curl_code(CURLcode code) { @@ -601,6 +604,7 @@ public: S32 process(); void perform(); + void doPerform(); virtual void run(); @@ -634,7 +638,14 @@ LLCurl::Multi::Multi() mPerformState(PERFORM_STATE_READY) { mQuitting = false; - mSignal = new LLCondition(NULL); + if (LLCurl::sMultiThreaded) + { + mSignal = new LLCondition(NULL); + } + else + { + mSignal = NULL; + } mCurlMultiHandle = curl_multi_init(); if (!mCurlMultiHandle) @@ -681,37 +692,51 @@ CURLMsg* LLCurl::Multi::info_read(S32* msgs_in_queue) void LLCurl::Multi::perform() { - if (mPerformState == PERFORM_STATE_READY) + if (LLCurl::sMultiThreaded) + { + if (mPerformState == PERFORM_STATE_READY) + { + mSignal->signal(); + } + } + else { - mSignal->signal(); + doPerform(); } } void LLCurl::Multi::run() { + llassert(LLCurl::sMultiThreaded); + while (!mQuitting) { mSignal->wait(); mPerformState = PERFORM_STATE_PERFORMING; if (!mQuitting) { - S32 q = 0; - for (S32 call_count = 0; - call_count < MULTI_PERFORM_CALL_REPEAT; - call_count += 1) - { - CURLMcode code = curl_multi_perform(mCurlMultiHandle, &q); - if (CURLM_CALL_MULTI_PERFORM != code || q == 0) - { - check_curl_multi_code(code); - break; - } - - } - mQueued = q; - mPerformState = PERFORM_STATE_COMPLETED; + doPerform(); + } + } +} + +void LLCurl::Multi::doPerform() +{ + S32 q = 0; + for (S32 call_count = 0; + call_count < MULTI_PERFORM_CALL_REPEAT; + call_count += 1) + { + CURLMcode code = curl_multi_perform(mCurlMultiHandle, &q); + if (CURLM_CALL_MULTI_PERFORM != code || q == 0) + { + check_curl_multi_code(code); + break; } + } + mQueued = q; + mPerformState = PERFORM_STATE_COMPLETED; } S32 LLCurl::Multi::process() @@ -839,10 +864,13 @@ LLCurlRequest::~LLCurlRequest() { LLCurl::Multi* multi = *iter; multi->mQuitting = true; - while (!multi->isStopped()) + if (LLCurl::sMultiThreaded) { - multi->mSignal->signal(); - apr_sleep(1000); + while (!multi->isStopped()) + { + multi->mSignal->signal(); + apr_sleep(1000); + } } } for_each(mMultiSet.begin(), mMultiSet.end(), DeletePointer()); @@ -852,7 +880,10 @@ void LLCurlRequest::addMulti() { llassert_always(mThreadID == LLThread::currentID()); LLCurl::Multi* multi = new LLCurl::Multi(); - multi->start(); + if (LLCurl::sMultiThreaded) + { + multi->start(); + } mMultiSet.insert(multi); mActiveMulti = multi; mActiveRequestCount = 0; @@ -983,10 +1014,13 @@ S32 LLCurlRequest::process() { mMultiSet.erase(curiter); multi->mQuitting = true; - while (!multi->isStopped()) + if (LLCurl::sMultiThreaded) { - multi->mSignal->signal(); - apr_sleep(1000); + while (!multi->isStopped()) + { + multi->mSignal->signal(); + apr_sleep(1000); + } } delete multi; @@ -1023,7 +1057,10 @@ LLCurlEasyRequest::LLCurlEasyRequest() mResultReturned(false) { mMulti = new LLCurl::Multi(); - mMulti->start(); + if (LLCurl::sMultiThreaded) + { + mMulti->start(); + } mEasy = mMulti->allocEasy(); if (mEasy) { @@ -1035,10 +1072,13 @@ LLCurlEasyRequest::LLCurlEasyRequest() LLCurlEasyRequest::~LLCurlEasyRequest() { mMulti->mQuitting = true; - while (!mMulti->isStopped()) + if (LLCurl::sMultiThreaded) { - mMulti->mSignal->signal(); - apr_sleep(1000); + while (!mMulti->isStopped()) + { + mMulti->mSignal->signal(); + apr_sleep(1000); + } } delete mMulti; } @@ -1234,8 +1274,9 @@ unsigned long LLCurl::ssl_thread_id(void) } #endif -void LLCurl::initClass() +void LLCurl::initClass(bool multi_threaded) { + sMultiThreaded = multi_threaded; // Do not change this "unless you are familiar with and mean to control // internal operations of libcurl" // - http://curl.haxx.se/libcurl/c/curl_global_init.html diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h index 56d086c30a..b2c7b36a76 100644 --- a/indra/llmessage/llcurl.h +++ b/indra/llmessage/llcurl.h @@ -55,6 +55,8 @@ public: class Easy; class Multi; + static bool sMultiThreaded; + struct TransferInfo { TransferInfo() : mSizeDownload(0.0), mTotalTime(0.0), mSpeedDownload(0.0) {} @@ -159,7 +161,7 @@ public: /** * @ brief Initialize LLCurl class */ - static void initClass(); + static void initClass(bool multi_threaded = false); /** * @ brief Cleanup LLCurl class -- cgit v1.2.3 From aa0e35142a35d293acc439e3194260bb4468e728 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 2 Aug 2011 12:23:50 -0500 Subject: SH-2183 Only apply multi-threaded curl on the main thread. --- indra/llmessage/llcurl.cpp | 3 ++- indra/llmessage/llcurl.h | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'indra/llmessage') diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index ece539bb48..d48991e5f7 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -85,7 +85,8 @@ S32 gCurlMultiCount = 0; std::vector LLCurl::sSSLMutex; std::string LLCurl::sCAPath; std::string LLCurl::sCAFile; -bool LLCurl::sMultiThreaded = false; + +bool ll_thread_local LLCurl::sMultiThreaded = false; void check_curl_code(CURLcode code) diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h index b2c7b36a76..52810bac73 100644 --- a/indra/llmessage/llcurl.h +++ b/indra/llmessage/llcurl.h @@ -41,6 +41,7 @@ #include "llbuffer.h" #include "lliopipe.h" #include "llsd.h" +#include "llthread.h" class LLMutex; @@ -55,7 +56,7 @@ public: class Easy; class Multi; - static bool sMultiThreaded; + static bool ll_thread_local sMultiThreaded; struct TransferInfo { -- cgit v1.2.3 From 9883c33993f7a548c876b43494ffd5835473a211 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 2 Aug 2011 12:47:35 -0500 Subject: SH-2183 Thread local storage initialization is unreliable. --- indra/llmessage/llcurl.cpp | 25 +++++++++++++++---------- indra/llmessage/llcurl.h | 2 +- 2 files changed, 16 insertions(+), 11 deletions(-) (limited to 'indra/llmessage') diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index d48991e5f7..1a86a69a04 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -75,6 +75,7 @@ static const S32 MULTI_PERFORM_CALL_REPEAT = 5; static const S32 CURL_REQUEST_TIMEOUT = 30; // seconds static const S32 MAX_ACTIVE_REQUEST_COUNT = 100; +static // DEBUG // S32 gCurlEasyCount = 0; S32 gCurlMultiCount = 0; @@ -86,8 +87,8 @@ std::vector LLCurl::sSSLMutex; std::string LLCurl::sCAPath; std::string LLCurl::sCAFile; -bool ll_thread_local LLCurl::sMultiThreaded = false; - +bool LLCurl::sMultiThreaded = false; +static U32 sMainThreadID = 0; void check_curl_code(CURLcode code) { @@ -618,6 +619,7 @@ public: LLCondition* mSignal; bool mQuitting; + bool mThreaded; private: void easyFree(Easy*); @@ -639,7 +641,9 @@ LLCurl::Multi::Multi() mPerformState(PERFORM_STATE_READY) { mQuitting = false; - if (LLCurl::sMultiThreaded) + + mThreaded = LLCurl::sMultiThreaded && LLThread::currentID() == sMainThreadID; + if (mThreaded) { mSignal = new LLCondition(NULL); } @@ -693,7 +697,7 @@ CURLMsg* LLCurl::Multi::info_read(S32* msgs_in_queue) void LLCurl::Multi::perform() { - if (LLCurl::sMultiThreaded) + if (mThreaded) { if (mPerformState == PERFORM_STATE_READY) { @@ -708,7 +712,7 @@ void LLCurl::Multi::perform() void LLCurl::Multi::run() { - llassert(LLCurl::sMultiThreaded); + llassert(mThreaded); while (!mQuitting) { @@ -865,7 +869,7 @@ LLCurlRequest::~LLCurlRequest() { LLCurl::Multi* multi = *iter; multi->mQuitting = true; - if (LLCurl::sMultiThreaded) + if (multi->mThreaded) { while (!multi->isStopped()) { @@ -881,7 +885,7 @@ void LLCurlRequest::addMulti() { llassert_always(mThreadID == LLThread::currentID()); LLCurl::Multi* multi = new LLCurl::Multi(); - if (LLCurl::sMultiThreaded) + if (multi->mThreaded) { multi->start(); } @@ -1015,7 +1019,7 @@ S32 LLCurlRequest::process() { mMultiSet.erase(curiter); multi->mQuitting = true; - if (LLCurl::sMultiThreaded) + if (multi->mThreaded) { while (!multi->isStopped()) { @@ -1058,7 +1062,7 @@ LLCurlEasyRequest::LLCurlEasyRequest() mResultReturned(false) { mMulti = new LLCurl::Multi(); - if (LLCurl::sMultiThreaded) + if (mMulti->mThreaded) { mMulti->start(); } @@ -1073,7 +1077,7 @@ LLCurlEasyRequest::LLCurlEasyRequest() LLCurlEasyRequest::~LLCurlEasyRequest() { mMulti->mQuitting = true; - if (LLCurl::sMultiThreaded) + if (mMulti->mThreaded) { while (!mMulti->isStopped()) { @@ -1277,6 +1281,7 @@ unsigned long LLCurl::ssl_thread_id(void) void LLCurl::initClass(bool multi_threaded) { + sMainThreadID = LLThread::currentID(); sMultiThreaded = multi_threaded; // Do not change this "unless you are familiar with and mean to control // internal operations of libcurl" diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h index 52810bac73..f7518c8e5c 100644 --- a/indra/llmessage/llcurl.h +++ b/indra/llmessage/llcurl.h @@ -56,7 +56,7 @@ public: class Easy; class Multi; - static bool ll_thread_local sMultiThreaded; + static bool sMultiThreaded; struct TransferInfo { -- cgit v1.2.3