S60 Open C
Threads, Processes, IPC, and Synchronization

Threads, Processes, IPC, and Synchronization

Table of Contents

How to avoid deadlock using POSIX APIs

 


How to avoid deadlock using POSIX APIs

Symbian C++ provides, for example the RSemaphore, RMutex, and RFastLock classes for synchronization. These classes have methods like Wait( ) and Signal() to lock and unlock the resource. If the locks are not handled properly, a deadlock may occur. An example of a deadlock is as given below. The example assumes that there are two threads in a process and there are two locks to protect two resources.

Thread 1             Thread 2     
========             ========        
…                    …     
…                    …   
Lock A               Lock B     
…                    …     
…                    …   
Lock B               Lock A     
…                    …     
…                    …   
UnLock B             UnLock A   
UnLock A             UnLock B    
  1. Thread 1 acquires Lock A and a context switch occurs to Thread 2.
  2. Thread 2 acquires Lock B and a context switch occurs back to Thread 1.
  3. Thread 1 tries to acquire Lock B and blocks since Thread 2 has already locked it.
  4. Now a context switch happens to Thread 2, which tries to acquire Lock A and blocks since Thread 1 has already locked it.

Thus both threads will block indefinitely, leading to a deadlock.

There are many ways to avoid the deadlock by using the locks carefully. One of the easiest ways is to check the lock before blocking, and if the lock is open, then lock it; else return back instead of blocking. This operation has to be done atomically. Thus the operating system should provide a suitable API for this. At the moment, Symbian OS does not have any such API.

POSIX defines the following APIs that can be used to avoid such a situation:

  • sem_trywait() returns 0 if it is successful in locking the semaphore. If the semaphore is already locked, then it returns -1 and sets the errno to EAGAIN.
  • pthread_mutex_trylock() returns 0 if it is successful in locking the mutex. If the mutex is already locked, it returns EBUSY. (None of the pthread APIs set the errno.)

With this API, the solution might look as follows:

Thread 1                     Thread 2  
=======                      ========     
…                            …     
…                            …  
Lock A                       Lock B     
…                            …     
…                            … 
begin1:                     begin2:  
  TryLock B                    TryLock A  
  If failed to Lock            If failed to Lock  
  then  Unlock A               then  Unlock B        
    sleep (10)                   sleep (10)        
    Lock A                       Lock B        
    Goto begin1:                 Goto begin2:     
    …                            …     
    …                            …   
  UnLock B                    UnLock A   
  UnLock A                    UnLock B  

Similarly, there are two more useful APIs in POSIX:

  • sem_timedwait() Tries to lock the semaphore. If the lock is open, sem_timedwait() locks it and returns successfully; otherwise it waits until time-out expires.
  • pthread_mutex_timedlock() Tries to lock the mutex. If the lock is open, pthread_mutex_timedlock() locks it and returns successfully; otherwise it waits until time-out expires.

There are no equivalent APIs for the above in Symbian OS.

Give feedback of this section


Back to top


Copyright ©2008 Nokia Corporation. All rights reserved. This documentation can be used in the connection with this Product to help and support the user.