Skip to content

Commit bbd712e

Browse files
committed
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
1 parent 4a34a11 commit bbd712e

File tree

3 files changed

+50
-21
lines changed

3 files changed

+50
-21
lines changed

indra/llimage/llimageworker.cpp

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,10 @@ class ImageRequest
3535
{
3636
public:
3737
ImageRequest(const LLPointer<LLImageFormatted>& image,
38-
S32 discard, BOOL needs_aux,
39-
const LLPointer<LLImageDecodeThread::Responder>& responder);
38+
S32 discard,
39+
BOOL needs_aux,
40+
const LLPointer<LLImageDecodeThread::Responder>& responder,
41+
U32 request_id);
4042
virtual ~ImageRequest();
4143

4244
/*virtual*/ bool processRequest();
@@ -48,6 +50,7 @@ class ImageRequest
4850
// input
4951
LLPointer<LLImageFormatted> mFormattedImage;
5052
S32 mDiscardLevel;
53+
U32 mRequestId;
5154
BOOL mNeedsAux;
5255
// output
5356
LLPointer<LLImageRaw> mDecodedImageRaw;
@@ -62,6 +65,7 @@ class ImageRequest
6265

6366
// MAIN THREAD
6467
LLImageDecodeThread::LLImageDecodeThread(bool /*threaded*/)
68+
: mDecodeCount(0)
6569
{
6670
mThreadPool.reset(new LL::ThreadPool("ImageDecode", 8));
6771
mThreadPool->start();
@@ -92,9 +96,10 @@ LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(
9296
{
9397
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
9498

99+
U32 decode_id = ++mDecodeCount;
95100
// Instantiate the ImageRequest right in the lambda, why not?
96101
bool posted = mThreadPool->getQueue().post(
97-
[req = ImageRequest(image, discard, needs_aux, responder)]
102+
[req = ImageRequest(image, discard, needs_aux, responder, decode_id)]
98103
() mutable
99104
{
100105
auto done = req.processRequest();
@@ -103,13 +108,10 @@ LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(
103108
if (! posted)
104109
{
105110
LL_DEBUGS() << "Tried to start decoding on shutdown" << LL_ENDL;
106-
// should this return 0?
111+
return 0;
107112
}
108113

109-
// It's important to our consumer (LLTextureFetchWorker) that we return a
110-
// nonzero handle. It is NOT important that the nonzero handle be unique:
111-
// nothing is ever done with it except to compare it to zero, or zero it.
112-
return 17;
114+
return decode_id;
113115
}
114116

115117
void LLImageDecodeThread::shutdown()
@@ -123,15 +125,18 @@ LLImageDecodeThread::Responder::~Responder()
123125

124126
//----------------------------------------------------------------------------
125127

126-
ImageRequest::ImageRequest(const LLPointer<LLImageFormatted>& image,
127-
S32 discard, BOOL needs_aux,
128-
const LLPointer<LLImageDecodeThread::Responder>& responder)
128+
ImageRequest::ImageRequest(const LLPointer<LLImageFormatted>& image,
129+
S32 discard,
130+
BOOL needs_aux,
131+
const LLPointer<LLImageDecodeThread::Responder>& responder,
132+
U32 request_id)
129133
: mFormattedImage(image),
130134
mDiscardLevel(discard),
131135
mNeedsAux(needs_aux),
132136
mDecodedRaw(FALSE),
133137
mDecodedAux(FALSE),
134-
mResponder(responder)
138+
mResponder(responder),
139+
mRequestId(request_id)
135140
{
136141
}
137142

@@ -199,7 +204,7 @@ void ImageRequest::finishRequest(bool completed)
199204
if (mResponder.notNull())
200205
{
201206
bool success = completed && mDecodedRaw && (!mNeedsAux || mDecodedAux);
202-
mResponder->completed(success, mDecodedImageRaw, mDecodedImageAux);
207+
mResponder->completed(success, mDecodedImageRaw, mDecodedImageAux, mRequestId);
203208
}
204209
// Will automatically be deleted
205210
}

indra/llimage/llimageworker.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class LLImageDecodeThread
3939
protected:
4040
virtual ~Responder();
4141
public:
42-
virtual void completed(bool success, LLImageRaw* raw, LLImageRaw* aux) = 0;
42+
virtual void completed(bool success, LLImageRaw* raw, LLImageRaw* aux, U32 request_id) = 0;
4343
};
4444

4545
public:
@@ -53,13 +53,15 @@ class LLImageDecodeThread
5353
const LLPointer<Responder>& responder);
5454
size_t getPending();
5555
size_t update(F32 max_time_ms);
56+
S32 getTotalDecodeCount() { return mDecodeCount; }
5657
void shutdown();
5758

5859
private:
5960
// As of SL-17483, LLImageDecodeThread is no longer itself an
6061
// LLQueuedThread - instead this is the API by which we submit work to the
6162
// "ImageDecode" ThreadPool.
6263
std::unique_ptr<LL::ThreadPool> mThreadPool;
64+
LLAtomicU32 mDecodeCount;
6365
};
6466

6567
#endif

indra/newview/lltexturefetch.cpp

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -348,13 +348,13 @@ class LLTextureFetchWorker : public LLWorkerClass, public LLCore::HttpHandler
348348
}
349349

350350
// Threads: Tid
351-
virtual void completed(bool success, LLImageRaw* raw, LLImageRaw* aux)
351+
virtual void completed(bool success, LLImageRaw* raw, LLImageRaw* aux, U32 request_id)
352352
{
353353
LL_PROFILE_ZONE_SCOPED;
354354
LLTextureFetchWorker* worker = mFetcher->getWorker(mID);
355355
if (worker)
356356
{
357-
worker->callbackDecoded(success, raw, aux);
357+
worker->callbackDecoded(success, raw, aux, request_id);
358358
}
359359
}
360360
private:
@@ -398,7 +398,7 @@ class LLTextureFetchWorker : public LLWorkerClass, public LLCore::HttpHandler
398398
void callbackCacheWrite(bool success);
399399

400400
// Threads: Tid
401-
void callbackDecoded(bool success, LLImageRaw* raw, LLImageRaw* aux);
401+
void callbackDecoded(bool success, LLImageRaw* raw, LLImageRaw* aux, S32 decode_id);
402402

403403
// Threads: T*
404404
void setGetStatus(LLCore::HttpStatus status, const std::string& reason)
@@ -1800,8 +1800,22 @@ bool LLTextureFetchWorker::doWork(S32 param)
18001800
setState(DECODE_IMAGE_UPDATE);
18011801
LL_DEBUGS(LOG_TXT) << mID << ": Decoding. Bytes: " << mFormattedImage->getDataSize() << " Discard: " << discard
18021802
<< " All Data: " << mHaveAllData << LL_ENDL;
1803-
mDecodeHandle = LLAppViewer::getImageDecodeThread()->decodeImage(mFormattedImage, discard, mNeedsAux,
1804-
new DecodeResponder(mFetcher, mID, this));
1803+
1804+
// In case worked manages to request decode, be shut down,
1805+
// then init and request decode again with first decode
1806+
// still in progress, assign a sufficiently unique id
1807+
mDecodeHandle = LLAppViewer::getImageDecodeThread()->decodeImage(mFormattedImage,
1808+
discard,
1809+
mNeedsAux,
1810+
new DecodeResponder(mFetcher, mID, this));
1811+
if (mDecodeHandle == 0)
1812+
{
1813+
// Abort, failed to put into queue.
1814+
// Happens if viewer is shutting down
1815+
setState(DONE);
1816+
LL_DEBUGS(LOG_TXT) << mID << " DECODE_IMAGE abort: failed to post for decoding" << LL_ENDL;
1817+
return true;
1818+
}
18051819
// fall though
18061820
}
18071821

@@ -2305,16 +2319,24 @@ void LLTextureFetchWorker::callbackCacheWrite(bool success)
23052319
//////////////////////////////////////////////////////////////////////////////
23062320

23072321
// Threads: Tid
2308-
void LLTextureFetchWorker::callbackDecoded(bool success, LLImageRaw* raw, LLImageRaw* aux)
2322+
void LLTextureFetchWorker::callbackDecoded(bool success, LLImageRaw* raw, LLImageRaw* aux, S32 decode_id)
23092323
{
23102324
LLMutexLock lock(&mWorkMutex); // +Mw
23112325
if (mDecodeHandle == 0)
23122326
{
23132327
return; // aborted, ignore
23142328
}
2329+
if (mDecodeHandle != decode_id)
2330+
{
2331+
// Queue doesn't support canceling old requests.
2332+
// This shouldn't normally happen, but in case it's possible that a worked
2333+
// will request decode, be aborted, reinited then start a new decode
2334+
LL_DEBUGS(LOG_TXT) << mID << " received obsolete decode's callback" << LL_ENDL;
2335+
return; // ignore
2336+
}
23152337
if (mState != DECODE_IMAGE_UPDATE)
23162338
{
2317-
// LL_WARNS(LOG_TXT) << "Decode callback for " << mID << " with state = " << mState << LL_ENDL;
2339+
LL_DEBUGS(LOG_TXT) << "Decode callback for " << mID << " with state = " << mState << LL_ENDL;
23182340
mDecodeHandle = 0;
23192341
return;
23202342
}

0 commit comments

Comments
 (0)