diff options
| author | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2024-01-23 02:23:28 +0200 | 
|---|---|---|
| committer | Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> | 2024-01-23 13:01:39 +0200 | 
| commit | da48bd943923958952ea77eed858ba8372d58d9a (patch) | |
| tree | afd55253b2150a4f894fa1a8dc55f124636ab04b | |
| parent | 4a34a1196627c7e9998edde725d5e839f3ef61b9 (diff) | |
SL-18721 Shutdown fixes #2
Set DONE if decode thread is down instead of waiting for an update.
Decodes can't be canceled, so fix potential situation where we get two
responses
| -rw-r--r-- | indra/llimage/llimageworker.cpp | 31 | ||||
| -rw-r--r-- | indra/llimage/llimageworker.h | 4 | ||||
| -rw-r--r-- | indra/newview/lltexturefetch.cpp | 36 | 
3 files changed, 50 insertions, 21 deletions
| diff --git a/indra/llimage/llimageworker.cpp b/indra/llimage/llimageworker.cpp index c1ee052997..fd59daad3d 100644 --- a/indra/llimage/llimageworker.cpp +++ b/indra/llimage/llimageworker.cpp @@ -35,8 +35,10 @@ class ImageRequest  {  public:  	ImageRequest(const LLPointer<LLImageFormatted>& image, -				 S32 discard, BOOL needs_aux, -				 const LLPointer<LLImageDecodeThread::Responder>& responder); +                 S32 discard, +                 BOOL needs_aux, +                 const LLPointer<LLImageDecodeThread::Responder>& responder, +                 U32 request_id);  	virtual ~ImageRequest();  	/*virtual*/ bool processRequest(); @@ -48,6 +50,7 @@ private:  	// input  	LLPointer<LLImageFormatted> mFormattedImage;  	S32 mDiscardLevel; +    U32 mRequestId;  	BOOL mNeedsAux;  	// output  	LLPointer<LLImageRaw> mDecodedImageRaw; @@ -62,6 +65,7 @@ private:  // MAIN THREAD  LLImageDecodeThread::LLImageDecodeThread(bool /*threaded*/) +    : mDecodeCount(0)  {      mThreadPool.reset(new LL::ThreadPool("ImageDecode", 8));      mThreadPool->start(); @@ -92,9 +96,10 @@ LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(  {      LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; +    U32 decode_id = ++mDecodeCount;      // Instantiate the ImageRequest right in the lambda, why not?      bool posted = mThreadPool->getQueue().post( -        [req = ImageRequest(image, discard, needs_aux, responder)] +        [req = ImageRequest(image, discard, needs_aux, responder, decode_id)]          () mutable          {              auto done = req.processRequest(); @@ -103,13 +108,10 @@ LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(      if (! posted)      {          LL_DEBUGS() << "Tried to start decoding on shutdown" << LL_ENDL; -        // should this return 0? +        return 0;      } -    // It's important to our consumer (LLTextureFetchWorker) that we return a -    // nonzero handle. It is NOT important that the nonzero handle be unique: -    // nothing is ever done with it except to compare it to zero, or zero it. -    return 17; +    return decode_id;  }  void LLImageDecodeThread::shutdown() @@ -123,15 +125,18 @@ LLImageDecodeThread::Responder::~Responder()  //---------------------------------------------------------------------------- -ImageRequest::ImageRequest(const LLPointer<LLImageFormatted>& image,  -							S32 discard, BOOL needs_aux, -							const LLPointer<LLImageDecodeThread::Responder>& responder) +ImageRequest::ImageRequest(const LLPointer<LLImageFormatted>& image, +                           S32 discard, +                           BOOL needs_aux, +                           const LLPointer<LLImageDecodeThread::Responder>& responder, +                           U32 request_id)  	: mFormattedImage(image),  	  mDiscardLevel(discard),  	  mNeedsAux(needs_aux),  	  mDecodedRaw(FALSE),  	  mDecodedAux(FALSE), -	  mResponder(responder) +	  mResponder(responder), +	  mRequestId(request_id)  {  } @@ -199,7 +204,7 @@ void ImageRequest::finishRequest(bool completed)  	if (mResponder.notNull())  	{  		bool success = completed && mDecodedRaw && (!mNeedsAux || mDecodedAux); -		mResponder->completed(success, mDecodedImageRaw, mDecodedImageAux); +		mResponder->completed(success, mDecodedImageRaw, mDecodedImageAux, mRequestId);  	}  	// Will automatically be deleted  } diff --git a/indra/llimage/llimageworker.h b/indra/llimage/llimageworker.h index ca4c0d93d0..b4ab9432e6 100644 --- a/indra/llimage/llimageworker.h +++ b/indra/llimage/llimageworker.h @@ -39,7 +39,7 @@ public:  	protected:  		virtual ~Responder();  	public: -		virtual void completed(bool success, LLImageRaw* raw, LLImageRaw* aux) = 0; +		virtual void completed(bool success, LLImageRaw* raw, LLImageRaw* aux, U32 request_id) = 0;  	};  public: @@ -53,6 +53,7 @@ public:  						 const LLPointer<Responder>& responder);  	size_t getPending();  	size_t update(F32 max_time_ms); +    S32 getTotalDecodeCount() { return mDecodeCount; }  	void shutdown();  private: @@ -60,6 +61,7 @@ private:  	// LLQueuedThread - instead this is the API by which we submit work to the  	// "ImageDecode" ThreadPool.  	std::unique_ptr<LL::ThreadPool> mThreadPool; +    LLAtomicU32 mDecodeCount;  };  #endif diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 38c9b3717d..40bbe2b934 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -348,13 +348,13 @@ private:  		}  		// Threads:  Tid -		virtual void completed(bool success, LLImageRaw* raw, LLImageRaw* aux) +		virtual void completed(bool success, LLImageRaw* raw, LLImageRaw* aux, U32 request_id)  		{              LL_PROFILE_ZONE_SCOPED;  			LLTextureFetchWorker* worker = mFetcher->getWorker(mID);  			if (worker)  			{ - 				worker->callbackDecoded(success, raw, aux); + 				worker->callbackDecoded(success, raw, aux, request_id);  			}  		}  	private: @@ -398,7 +398,7 @@ public:  	void callbackCacheWrite(bool success);  	// Threads:  Tid -	void callbackDecoded(bool success, LLImageRaw* raw, LLImageRaw* aux); +	void callbackDecoded(bool success, LLImageRaw* raw, LLImageRaw* aux, S32 decode_id);  	// Threads:  T*  	void setGetStatus(LLCore::HttpStatus status, const std::string& reason) @@ -1800,8 +1800,22 @@ bool LLTextureFetchWorker::doWork(S32 param)  		setState(DECODE_IMAGE_UPDATE);  		LL_DEBUGS(LOG_TXT) << mID << ": Decoding. Bytes: " << mFormattedImage->getDataSize() << " Discard: " << discard  						   << " All Data: " << mHaveAllData << LL_ENDL; -		mDecodeHandle = LLAppViewer::getImageDecodeThread()->decodeImage(mFormattedImage, discard, mNeedsAux, -																  new DecodeResponder(mFetcher, mID, this)); + +        // In case worked manages to request decode, be shut down, +        // then init and request decode again with first decode +        // still in progress, assign a sufficiently unique id +        mDecodeHandle = LLAppViewer::getImageDecodeThread()->decodeImage(mFormattedImage, +                                                                       discard, +                                                                       mNeedsAux, +                                                                       new DecodeResponder(mFetcher, mID, this)); +        if (mDecodeHandle == 0) +        { +            // Abort, failed to put into queue. +            // Happens if viewer is shutting down +            setState(DONE); +            LL_DEBUGS(LOG_TXT) << mID << " DECODE_IMAGE abort: failed to post for decoding" << LL_ENDL; +            return true; +        }  		// fall though  	} @@ -2305,16 +2319,24 @@ void LLTextureFetchWorker::callbackCacheWrite(bool success)  //////////////////////////////////////////////////////////////////////////////  // Threads:  Tid -void LLTextureFetchWorker::callbackDecoded(bool success, LLImageRaw* raw, LLImageRaw* aux) +void LLTextureFetchWorker::callbackDecoded(bool success, LLImageRaw* raw, LLImageRaw* aux, S32 decode_id)  {  	LLMutexLock lock(&mWorkMutex);										// +Mw  	if (mDecodeHandle == 0)  	{  		return; // aborted, ignore  	} +    if (mDecodeHandle != decode_id) +    { +        // Queue doesn't support canceling old requests. +        // This shouldn't normally happen, but in case it's possible that a worked +        // will request decode, be aborted, reinited then start a new decode +        LL_DEBUGS(LOG_TXT) << mID << " received obsolete decode's callback" << LL_ENDL; +        return; // ignore +    }  	if (mState != DECODE_IMAGE_UPDATE)  	{ -// 		LL_WARNS(LOG_TXT) << "Decode callback for " << mID << " with state = " << mState << LL_ENDL; +		LL_DEBUGS(LOG_TXT) << "Decode callback for " << mID << " with state = " << mState << LL_ENDL;  		mDecodeHandle = 0;  		return;  	} | 
