webengine/osswebengine/WebCore/platform/symbian/bitmap/SyncDecodeThread.cpp
branchRCL_3
changeset 47 e1bea15f9a39
parent 27 6297cdf66332
child 48 79859ed3eea9
--- 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);