diff -r 30342f40acbf -r e1bea15f9a39 webengine/osswebengine/WebCore/platform/symbian/bitmap/SyncDecodeThread.cpp --- a/webengine/osswebengine/WebCore/platform/symbian/bitmap/SyncDecodeThread.cpp Thu Jul 15 19:53:20 2010 +0300 +++ b/webengine/osswebengine/WebCore/platform/symbian/bitmap/SyncDecodeThread.cpp Thu Aug 19 10:58:56 2010 +0300 @@ -40,7 +40,7 @@ TInt iMaskHandle; }; -enum DecoderState {ENewDecodeRequest, EDecodeInProgress, EDecoderIdle}; +enum DecoderState {ENewDecodeRequest, EDecodeInProgress, EDecoderIdle, EDecoderTerminate}; class CSynDecoder : public CActive { public: // Constructors and destructor @@ -51,6 +51,7 @@ void Open(const TDesC8& aData, TRequestStatus *status); void Lock() { iDecoderLock.Wait(); } void Release() { iDecoderLock.Signal(); } + void Terminate() { iDecodeState = EDecoderTerminate; } private: // From base class CActive void DoCancel(); @@ -70,7 +71,6 @@ CMaskedBitmap* iBitmap; RFastLock iDecoderLock; DecoderState iDecodeState; - RThread syncThread; friend class CSynDecodeThread; }; @@ -134,6 +134,7 @@ void CSynDecoder::SetIdle() { iDecodeState = EDecoderIdle; + iElem.iParentThreadId = 0; if(!IsActive()) { iStatus = KRequestPending; SetActive(); @@ -207,6 +208,12 @@ SignalParent(iStatus.Int()); SetIdle(); break; + case EDecoderTerminate: + // if any thread is waiting for decode, signal it + if( iElem.iParentThreadId ) + SignalParent(KErrCompletion); + CActiveScheduler::Stop(); + break; default: SetIdle(); } @@ -249,15 +256,32 @@ CSynDecodeThread::~CSynDecodeThread() { - CActiveScheduler::Stop(); - iDecoderThread.Close(); + // signal the thread to do cleanup and stop + iSyncDecoder->Terminate(); + TRequestStatus *ps = &(iSyncDecoder->iStatus); + iDecoderThread.RequestComplete(ps, KErrNone); + + iDecoderThread.Close(); } void CSynDecodeThread::ConstructL() { - _LIT(KThreadName, "ImgDecoder"); + _LIT(KThreadName, "iconDecoder"); RAllocator &allocator = User::Allocator(); - User::LeaveIfError(iDecoderThread.Create(KThreadName, CSynDecodeThread::ScaleInThread, KDefaultStackSize, &allocator, NULL)); + TInt err = iDecoderThread.Create(KThreadName, CSynDecodeThread::ScaleInThread, KDefaultStackSize, &allocator, NULL); + if(err == KErrAlreadyExists) { + // It may happen only in rare cases, if container browserengine..dll was unloaded and loaded again before + // syncDecodeThread could close itself (scheduled). In that case, we kill that thread since we can't reuse that + // and create a new one with same name. + RThread th; + th.Open(KThreadName); + th.Kill(KErrNone); + th.Close(); + + // Leave this time if problem still exists + User::LeaveIfError(iDecoderThread.Create(KThreadName, CSynDecodeThread::ScaleInThread, KDefaultStackSize, &allocator, NULL)); + } + iDecoderThread.SetPriority(EPriorityMore); TRequestStatus status = KRequestPending; iDecoderThread.Rendezvous(status);