webengine/osswebengine/WebCore/platform/symbian/bitmap/SyncDecodeThread.cpp
branchRCL_3
changeset 48 79859ed3eea9
parent 47 e1bea15f9a39
child 49 919f36ff910f
equal deleted inserted replaced
47:e1bea15f9a39 48:79859ed3eea9
    18 
    18 
    19 #include "config.h"
    19 #include "config.h"
    20 #include <e32std.h> 
    20 #include <e32std.h> 
    21 #include "SyncDecodeThread.h"
    21 #include "SyncDecodeThread.h"
    22 #include "MaskedBitmap.h"
    22 #include "MaskedBitmap.h"
    23 #include <ImageConversion.h>
    23 #include <imageconversion.h>
    24 
    24 
    25 namespace TBidirectionalState {
    25 namespace TBidirectionalState {
    26     class TRunInfo;
    26     class TRunInfo;
    27 };
    27 };
    28 
    28 
    29 #include <EIKENV.H> 
    29 #include <eikenv.h> 
    30 
    30 
    31 #define KMaxHeapSize 0x1000000
    31 #define KMaxHeapSize 0x1000000
    32 
    32 
    33 class BmElem 
    33 class BmElem 
    34 {
    34 {
    38         TRequestStatus* iRequestStatus;
    38         TRequestStatus* iRequestStatus;
    39         TInt iBitmapHandle;
    39         TInt iBitmapHandle;
    40         TInt iMaskHandle;
    40         TInt iMaskHandle;
    41 };
    41 };
    42 
    42 
    43 enum DecoderState {ENewDecodeRequest, EDecodeInProgress, EDecoderIdle, EDecoderTerminate};
    43 enum DecoderState {ENewDecodeRequest, EDecodeInProgress, EDecoderIdle};
    44 class CSynDecoder : public CActive
    44 class CSynDecoder : public CActive
    45     {
    45     {
    46     public:  // Constructors and destructor
    46     public:  // Constructors and destructor
    47         static CSynDecoder* NewL();
    47         static CSynDecoder* NewL();
    48         virtual ~CSynDecoder();
    48         virtual ~CSynDecoder();
    49 
    49 
    50     public:
    50     public:
    51         void Open(const TDesC8& aData, TRequestStatus *status);
    51         void Open(const TDesC8& aData, TRequestStatus *status);
    52         void Lock() { iDecoderLock.Wait(); }
    52         void Lock() { iDecoderLock.Wait(); }
    53         void Release() { iDecoderLock.Signal(); }
    53         void Release() { iDecoderLock.Signal(); }
    54         void Terminate() { iDecodeState = EDecoderTerminate; }
       
    55 
    54 
    56     private: // From base class CActive
    55     private: // From base class CActive
    57         void DoCancel();
    56         void DoCancel();
    58         void RunL();
    57         void RunL();
    59         TInt RunError( TInt aError );
    58         TInt RunError( TInt aError );
    69         BmElem iElem;
    68         BmElem iElem;
    70         CImageDecoder* iDecoder;
    69         CImageDecoder* iDecoder;
    71         CMaskedBitmap* iBitmap;
    70         CMaskedBitmap* iBitmap;
    72         RFastLock iDecoderLock;
    71         RFastLock iDecoderLock;
    73         DecoderState iDecodeState;
    72         DecoderState iDecodeState;
       
    73         RThread syncThread;
    74 
    74 
    75 friend class CSynDecodeThread;        
    75 friend class CSynDecodeThread;        
    76     };
    76     };
    77 
    77 
    78 // FORWARD DECLARATIONS
    78 // FORWARD DECLARATIONS
   117 // -----------------------------------------------------------------------------
   117 // -----------------------------------------------------------------------------
   118 // Decode - Decode request submitted from client thread
   118 // Decode - Decode request submitted from client thread
   119 // -----------------------------------------------------------------------------
   119 // -----------------------------------------------------------------------------
   120 void CSynDecoder::Open(const TDesC8& aData, TRequestStatus *status)
   120 void CSynDecoder::Open(const TDesC8& aData, TRequestStatus *status)
   121 {
   121 {
   122     // FbsSession is needed for parent thread if it doesn't have already
       
   123     if(!RFbsSession::GetSession())
       
   124         RFbsSession::Connect();
       
   125 
       
   126     iElem.iRequestStatus = status;
   122     iElem.iRequestStatus = status;
   127     iElem.iData.Set(aData); 
   123     iElem.iData.Set(aData); 
   128     iElem.iParentThreadId = RThread().Id();
   124     iElem.iParentThreadId = RThread().Id();
   129     iElem.iBitmapHandle = 0;
   125     iElem.iBitmapHandle = 0;
   130     iElem.iMaskHandle = 0;    
   126     iElem.iMaskHandle = 0;    
   132 }
   128 }
   133 
   129 
   134 void CSynDecoder::SetIdle()
   130 void CSynDecoder::SetIdle()
   135 {
   131 {
   136     iDecodeState = EDecoderIdle;
   132     iDecodeState = EDecoderIdle;
   137     iElem.iParentThreadId = 0;
       
   138     if(!IsActive()) {
   133     if(!IsActive()) {
   139         iStatus = KRequestPending;
   134         iStatus = KRequestPending;
   140         SetActive();
   135         SetActive();
   141     }
   136     }
   142 }
   137 }
   206         }
   201         }
   207         
   202         
   208         SignalParent(iStatus.Int());
   203         SignalParent(iStatus.Int());
   209         SetIdle();
   204         SetIdle();
   210         break;
   205         break;
   211     case EDecoderTerminate:
       
   212         // if any thread is waiting for decode, signal it
       
   213         if( iElem.iParentThreadId )
       
   214             SignalParent(KErrCompletion);
       
   215         CActiveScheduler::Stop();
       
   216         break;
       
   217     default:
   206     default:
   218         SetIdle();
   207         SetIdle();
   219     }        
   208     }        
   220 }
   209 }
   221 
   210 
   254 {
   243 {
   255 }
   244 }
   256 
   245 
   257 CSynDecodeThread::~CSynDecodeThread()
   246 CSynDecodeThread::~CSynDecodeThread()
   258 {
   247 {
   259     // signal the thread to do cleanup and stop
   248     CActiveScheduler::Stop(); 
   260     iSyncDecoder->Terminate();
   249 	iDecoderThread.Close();
   261     TRequestStatus *ps = &(iSyncDecoder->iStatus);
       
   262     iDecoderThread.RequestComplete(ps, KErrNone);
       
   263     
       
   264 	iDecoderThread.Close();    
       
   265 }
   250 }
   266 
   251 
   267 void CSynDecodeThread::ConstructL()
   252 void CSynDecodeThread::ConstructL()
   268 {   
   253 {   
   269     _LIT(KThreadName, "iconDecoder");
   254     _LIT(KThreadName, "ImgDecoder");
   270     RAllocator &allocator = User::Allocator();
   255     RAllocator &allocator = User::Allocator();
   271     TInt err = iDecoderThread.Create(KThreadName, CSynDecodeThread::ScaleInThread, KDefaultStackSize, &allocator, NULL);
   256     User::LeaveIfError(iDecoderThread.Create(KThreadName, CSynDecodeThread::ScaleInThread, KDefaultStackSize, &allocator, NULL));
   272     if(err == KErrAlreadyExists) {
       
   273         // It may happen only in rare cases, if container browserengine..dll was unloaded and loaded again before
       
   274         // syncDecodeThread could close itself (scheduled). In that case, we kill that thread since we can't reuse that
       
   275         // and create a new one with same name.
       
   276         RThread th;
       
   277         th.Open(KThreadName);
       
   278         th.Kill(KErrNone);
       
   279         th.Close();
       
   280 
       
   281         // Leave this time if problem still exists
       
   282         User::LeaveIfError(iDecoderThread.Create(KThreadName, CSynDecodeThread::ScaleInThread, KDefaultStackSize, &allocator, NULL));
       
   283     }
       
   284 
       
   285     iDecoderThread.SetPriority(EPriorityMore);
   257     iDecoderThread.SetPriority(EPriorityMore);
   286     TRequestStatus status = KRequestPending;
   258     TRequestStatus status = KRequestPending;
   287     iDecoderThread.Rendezvous(status);
   259     iDecoderThread.Rendezvous(status);
   288     iDecoderThread.Resume();
   260     iDecoderThread.Resume();
   289     User::WaitForRequest(status);
   261     User::WaitForRequest(status);