From 3c05ebd28635e867f9726062b08cdbf4a7b53b22 Mon Sep 17 00:00:00 2001 From: Monty Brandenberg Date: Thu, 16 Dec 2010 16:42:26 -0800 Subject: ESC-237 No static init of LLAtomics and move TFRequest out of unnamed namespace. Linux startup crash appears to be due to static/global C++ init of LLAtomic types. The initializer with explicit value makes some runtime calls and it looks like these assume, at least on Linux, that apr_initialize() has been called. So move the static POST count to a member and provide accessors and increment/decrement. Command queue was built on a pointer to a class in anonymous namespace and that's not quite valid. Made it a nested class (really a nested forward declaration) while keeping the derived classes in anonymous. --- indra/newview/lltexturefetch.cpp | 42 ++++++++++++++++++---------------------- indra/newview/lltexturefetch.h | 16 +++++++++++++-- 2 files changed, 33 insertions(+), 25 deletions(-) (limited to 'indra') diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 25ad2fe717..4f63abb152 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -388,9 +388,6 @@ private: // Cross-thread messaging for asset metrics. -namespace -{ - /** * @brief Base class for cross-thread requests made of the fetcher * @@ -490,7 +487,7 @@ namespace * (i.e. deep copy) when necessary. * */ -class TFRequest // : public LLQueuedThread::QueuedRequest +class LLTextureFetch::TFRequest // : public LLQueuedThread::QueuedRequest { public: // Default ctors and assignment operator are correct. @@ -505,6 +502,8 @@ public: virtual bool doWork(LLTextureFetch * fetcher) = 0; }; +namespace +{ /** * @brief Implements a 'Set Region' cross-thread command. @@ -517,11 +516,11 @@ public: * * Corresponds to LLTextureFetch::commandSetRegion() */ -class TFReqSetRegion : public TFRequest +class TFReqSetRegion : public LLTextureFetch::TFRequest { public: TFReqSetRegion(U64 region_handle) - : TFRequest(), + : LLTextureFetch::TFRequest(), mRegionHandle(region_handle) {} TFReqSetRegion & operator=(const TFReqSetRegion &); // Not defined @@ -550,7 +549,7 @@ public: * * Corresponds to LLTextureFetch::commandSendMetrics() */ -class TFReqSendMetrics : public TFRequest +class TFReqSendMetrics : public LLTextureFetch::TFRequest { public: /** @@ -574,7 +573,7 @@ public: const LLUUID & session_id, const LLUUID & agent_id, LLViewerAssetStats * main_stats) - : TFRequest(), + : LLTextureFetch::TFRequest(), mCapsURL(caps_url), mSessionID(session_id), mAgentID(agent_id), @@ -593,14 +592,6 @@ public: LLViewerAssetStats * mMainStats; }; -/* - * Count of POST requests outstanding. We maintain the count - * indirectly in the CURL request responder's ctor and dtor and - * use it when determining whether or not to sleep the thread. Can't - * use the LLCurl module's request counter as it isn't thread compatible. - */ -LLAtomic32 curl_post_request_count = 0; - /* * Examines the merged viewer metrics report and if found to be too long, * will attempt to truncate it in some reasonable fashion. @@ -1834,6 +1825,7 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image mCurlGetRequest(NULL), mQAMode(qa_mode) { + mCurlPOSTRequestCount = 0; mMaxBandwidth = gSavedSettings.getF32("ThrottleBandwidthKBPS"); mTextureInfo.setUpLogging(gSavedSettings.getBOOL("LogTextureDownloadsToViewerLog"), gSavedSettings.getBOOL("LogTextureDownloadsToSimulator"), gSavedSettings.getU32("TextureLoggingThreshold")); } @@ -2149,7 +2141,7 @@ S32 LLTextureFetch::getPending() LLMutexLock lock(&mQueueMutex); res = mRequestQueue.size(); - res += curl_post_request_count; + res += mCurlPOSTRequestCount; res += mCommands.size(); } unlockData(); @@ -2175,7 +2167,7 @@ bool LLTextureFetch::runCondition() have_no_commands = mCommands.empty(); } - bool have_no_curl_requests(0 == curl_post_request_count); + bool have_no_curl_requests(0 == mCurlPOSTRequestCount); return ! (have_no_commands && have_no_curl_requests @@ -2769,7 +2761,7 @@ void LLTextureFetch::cmdEnqueue(TFRequest * req) unpause(); } -TFRequest * LLTextureFetch::cmdDequeue() +LLTextureFetch::TFRequest * LLTextureFetch::cmdDequeue() { TFRequest * ret = 0; @@ -2856,22 +2848,24 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher) class lcl_responder : public LLCurl::Responder { public: - lcl_responder(S32 expected_sequence, + lcl_responder(LLTextureFetch * fetcher, + S32 expected_sequence, volatile const S32 & live_sequence, volatile bool & reporting_break, volatile bool & reporting_started) : LLCurl::Responder(), + mFetcher(fetcher), mExpectedSequence(expected_sequence), mLiveSequence(live_sequence), mReportingBreak(reporting_break), mReportingStarted(reporting_started) { - curl_post_request_count++; + mFetcher->incrCurlPOSTCount(); } ~lcl_responder() { - curl_post_request_count--; + mFetcher->decrCurlPOSTCount(); } // virtual @@ -2896,6 +2890,7 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher) } private: + LLTextureFetch * mFetcher; S32 mExpectedSequence; volatile const S32 & mLiveSequence; volatile bool & mReportingBreak; @@ -2939,7 +2934,8 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher) fetcher->getCurlRequest().post(mCapsURL, headers, merged_llsd, - new lcl_responder(report_sequence, + new lcl_responder(fetcher, + report_sequence, report_sequence, LLTextureFetch::svMetricsDataBreak, reporting_started)); diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index a8fd3ce244..ad00a7ea36 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -33,6 +33,7 @@ #include "llworkerthread.h" #include "llcurl.h" #include "lltextureinfo.h" +#include "llapr.h" class LLViewerTexture; class LLTextureFetchWorker; @@ -42,8 +43,6 @@ class LLImageDecodeThread; class LLHost; class LLViewerAssetStats; -namespace { class TFRequest; } - // Interface class class LLTextureFetch : public LLWorkerThread { @@ -54,6 +53,8 @@ public: LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* imagedecodethread, bool threaded, bool qa_mode); ~LLTextureFetch(); + class TFRequest; + /*virtual*/ S32 update(U32 max_time_ms); void shutDownTextureCacheThread() ; //called in the main thread after the TextureCacheThread shuts down. void shutDownImageDecodeThread() ; //called in the main thread after the ImageDecodeThread shuts down. @@ -100,6 +101,10 @@ public: bool isQAMode() const { return mQAMode; } + // Curl POST counter maintenance + inline void incrCurlPOSTCount() { mCurlPOSTRequestCount++; } + inline void decrCurlPOSTCount() { mCurlPOSTRequestCount--; } + protected: void addToNetworkQueue(LLTextureFetchWorker* worker); void removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel); @@ -187,6 +192,13 @@ private: // If true, modifies some behaviors that help with QA tasks. const bool mQAMode; + + // Count of POST requests outstanding. We maintain the count + // indirectly in the CURL request responder's ctor and dtor and + // use it when determining whether or not to sleep the thread. Can't + // use the LLCurl module's request counter as it isn't thread compatible. + // *NOTE: Don't mix Atomic and static, apr_initialize must be called first. + LLAtomic32 mCurlPOSTRequestCount; public: // A probabilistically-correct indicator that the current -- cgit v1.2.3