Use LockHeap and UnlockHeap!
Login to reply to this topic.
Wed, 2006-12-20 12:43
Joined: 2004-11-29
Forum posts: 1419
I'm getting a bit scared reading posts from a lot of developers that want to get raw access to CFbsBitmap bitmaps, and calls DataAddress() without calling LockHeap and UnlockHeap.

So I thought I would write something about why this is needed, and how it should be done.

With recent versions of Symbian, this problem will probably decrease, since the debug builds now throw a FBSCLI:22 panic if this is attempted.

But it is still VERY IMPORTANT that you do call LockHeap and UnlockHeap, also in older versions of Symbian.

So why is this needed?

The bitmap data of a CFbsBitmap is not stored in your applications heap, but in a shared heap, shared between all running processes on the phone.

To keep this heap tidy, the fbs server will sometimes compress this heap, and also if another thread needs to create a bitmap and there is no room, it might need to be expanded. When doing this, it will move around all bitmaps in its heap.

This has the result that at _any_time_ (from your applications point of view), your bitmap data can change what address it is stored at.

The ONLY way to make sure that your bitmap stays in place in memory, is to call LockHeap().

What can happen if I fail to do this?

If you only read from the bitmap, the problem is "only" local for your app, you will get a distorted image (often half of your image, half some other unrelated image, and some junk pixels (being the heap cell information))

It can also crash your app if you are unlucky.

If you write to the bitmap though, the problem is even worse, there is a very good chance you will corrupt the FBS servers heap, and this will CRASH the FBS server, makeing bitmaps unavailable for ALL threads in the phone... I don't think I need to go into detail what result this have for the whole system. (where do you think skin bitmaps that all apps use are stored for example?)

In EKA1, you were mostly safe if you just called DataAddress right before useing bitmaps, and didn't store the pointer for a long time, but this is still not 100% safe, and in EKA2 with better multitasking, and with more and more system services useing bitmaps in unexpected ways, this is anything but safe. (Good thing they added the panic)

Ok, so then I just LockHeap in the beginning of my app, do my stuff, and unlock it later sometime, maybe when I exit

NO!  This is almost as bad as not locking it. While you have locked the heap, no other threads can gain access to bitmaps. This will block all other threads attempting to do bitmap operations while you have it locked. And all normal apps use it, and some system services. You will hang your phone if you try to switch away from your app...

I don't call it in my 2nd edition app and its seems to work...

You are just "lucky". If you call DataAddress _right_ before useing the bitmap, you mostly have no problem, but it still is NOT safe.
If you just call DataAddress once... try switch away from your app, and start another app, maybe the gallery.. Then switch back to your app.. Does it still work?

So what do do then?

Keep your the time you lock the heap as short as possible. The locking is quick compared to any bitmap operation you might want to do, so there is nothing bad with calling it often.

Only call it right before you start your bitmap manipulation, and then call unlock as soon as you are done with that bitmap.


Thanks for reading  Afro

Thu, 2006-12-21 09:23
Joined: 2006-05-10
Forum posts: 64
Nice article  Cool

Regards,
  Damian

Confusion will be my epitaph..


copyright 2003-2009 NewLC SARL