How to stop the thread created in CImageDecoder?

Login to reply to this topic.
Mon, 2005-01-31 12:04
Joined: 2005-01-18
Forum posts: 8
Dear All,

In my app, I used the CImageDecoder to decode a bmp file with the EOptionAlwaysThread parameter to call the member function Convert() of  CImageDecoder  class. After finish the decoding, the app cannot be terminated exactly.

The following is my code fragment:

class CImageHandler : public CActive
{
public:
   static CImageHandler* NewL(RFs& fs);
  ~CImageHandler();

private:
   CImageHandler(RFs& fs);
   
public:
   // It is the caller's responsobility to delete the return pointer
   CFbsBitmap* LoadFileL(const TDesC& aFilename);

private:
   // Active object interface
   void RunL();
   void DoCancel();

private:
   CImageDecoder* iLoadUtil;
   RFs&           iFs;          
   
};

//////////////////////////
CImageHandler* CImageHandler::NewL(RFs& fs)
{
  CImageHandler* p=new (ELeave) CImageHandler(fs);
  CActiveScheduler::Add(p);
  return p;
}

CImageHandler::CImageHandler(RFs& fs) :
CActive(CActive::EPriorityStandard), iFs(fs)
{
}

CImageHandler::~CImageHandler()
{
   Cancel();
   Deque();
  delete iLoadUtil;
   
}


//the decoder function
CFbsBitmap* CImageHandler::LoadFileL(const TDesC& aFilename)
{
   ASSERT(!IsActive());
   if(IsActive())
       return NULL;

   delete iLoadUtil;
   iLoadUtil = NULL;
   iLoadUtil = CImageDecoder::FileNewL(iFs, aFilename,
                    CImageDecoder::EOptionAlwaysThread);            
   
   // Bitmap
   CFbsBitmap* pBitmap = new CFbsBitmap();
   if(pBitmap)
   {
        //some line to create the CFbsBitmap
        ......
        iLoadUtil->Convert(&iStatus, *pBitmap, 0);
       SetActive();
       User::WaitForRequest(iStatus);
       if(iStatus.Int() != KErrNone)
      {
          delete pBitmap;
          pBitmap = NULL;
       }
               
     }

    return pBitmap;
}


void CImageHandler::RunL()
{

}
   
void CImageHandler::DoCancel()
{
   // Cancel everything possible
   if(iLoadUtil)
       iLoadUtil->Cancel();
}

/////////////////////////////////////////////

I use the User::WaitForRequest(iStatus) function to wait the thread decode the file synchronously.
The app can run in success, but cannot exit.
I had done my best but I still failed to find the reason. Pleas help me.

Thanks in advance.

Mon, 2005-01-31 12:34
Joined: 2004-07-28
Forum posts: 1379
How to stop the thread created in CImageDecoder?
Why are you doing this in an active object???  Your calling wait for request, so why try and wrap it up in an AO, and wait on the AO's iStatus member?

Try this

Code:
class CImageHandler : public CBase
{
public:
static CImageHandler* NewL(RFs& fs);
~CImageHandler();

private:
CImageHandler(RFs& fs);

public:
CFbsBitmap* LoadFileL(const TDesC& aFilename);

private:
CImageDecoder* iLoadUtil;
RFs& iFs;
};


And

Code:

CImageHandler* CImageHandler::NewL(RFs& fs)
{
CImageHandler* p=new (ELeave) CImageHandler(fs);
return p;
}

CImageHandler::CImageHandler(RFs& fs) :
iFs(fs)
{
}

CImageHandler::~CImageHandler()
{
delete iLoadUtil;
}


//the decoder function
CFbsBitmap* CImageHandler::LoadFileL(const TDesC& aFilename)
{

delete iLoadUtil;
iLoadUtil = NULL;
iLoadUtil = CImageDecoder::FileNewL(iFs, aFilename,
CImageDecoder::EOptionAlwaysThread);

// Bitmap
CFbsBitmap* pBitmap = new CFbsBitmap();
if(pBitmap)
{
//some line to create the CFbsBitmap

TRequestStatus stat = KRequestPending;
iLoadUtil->Convert(&stat, *pBitmap, 0);
User::WaitForRequest(stat);
if(stat.Int() != KErrNone)
{
delete pBitmap;
pBitmap = NULL;
}

}

return pBitmap;
}


Or, make it really asyncronous and don't call waitforrequest - RunL will then be called when the conversion has been completed.

didster

Mon, 2005-01-31 14:00
Joined: 2004-07-17
Forum posts: 110
How to stop the thread created in CImageDecoder?
Use the active object properly, don't try to decode the image synchronously. The CImageDecoder API was not designed to be used in this way.

BTW you need to provide more info about what happens when you try to exit your app, otherwise we can't really help with that. One other thing, you don't need to call Deque() in the destructor. That is done for you by the base class.
Mon, 2005-01-31 14:33
Joined: 2004-07-28
Forum posts: 1379
How to stop the thread created in CImageDecoder?
I agree you should be using AO's - but you can do it syncronously using EOptionAlwaysThread which does the conversion in it's own thread.

The discussion on why this was added is here:  http://www.symbian.com/developer/techlib/v70sdocs/doc_source/DevGuides/cpp/MultiMedia/ImageConverterLibrary/ICLGuide_AdvancedFeatures.html

didster

Mon, 2005-01-31 21:05
Joined: 2004-07-17
Forum posts: 110
How to stop the thread created in CImageDecoder?
That's interesting. I hadn't seen that document.

The point is that if you do the decoding synchronously using your applications main thread you are guaranteed to freeze the application and that's a very bad idea, unless of course you deliberately want to annoy the hell out of the person who is using your app. You should always give the user the option of cancelling the operation and you simply can't do that if you are doing the decoding synchronously.
Tue, 2005-02-01 02:10
Joined: 2005-01-18
Forum posts: 8
How to stop the thread created in CImageDecoder?
Thank for your help very much! Especially didSter. Cheezy The bug was fixed and my app can be terminated exactly.
Wed, 2005-08-03 16:01
Joined: 2005-06-08
Forum posts: 53
Re: How to stop the thread created in CImageDecoder?
Thanks for this post.

Now i solved my problem, too.

in synchronous Situation ( no CActive class):
use:

CImageDecoder::EOptionAlwaysThread instand CImageDecoder::EOptionNone
Code:
imageDecoder = CImageDecoder::FileNewL(ff, _L("c:\\maptest2.png"), MimeType, CImageDecoder::EOptionAlwaysThread);
iBitmap = new (ELeave) CFbsBitmap();
iBitmap->Create(imageDecoder->FrameInfo().iOverallSizeInPixels, imageDecoder->FrameInfo().iFrameDisplayMode);//EColor4K);

TRequestStatus status;//iState = EDecoding;
imageDecoder->Convert( &status, *iBitmap );
User::WaitForRequest(status);
Thanks again!!
  • Login to reply to this topic.