Changes between Version 2 and Version 3 of Group_Lock


Ignore:
Timestamp:
Feb 25, 2013 9:14:52 AM (11 years ago)
Author:
bennylp
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Group_Lock

    v2 v3  
    9797 
    9898 
    99 === Synchronization with External Locks === 
     99=== Synchronization with External Locks === #chain 
    100100 
    101 Often it is necessary to synchronize the group lock with an external lock. By external, it means a lock owned by object outside the group, and it’s not possible to to add that object to the group. The PJSUA lock and ioqueue locks are examples of such locks. Synchronizing these locks will guarantee the lock ordering of the locks hence deadlock will be avoided. 
     101Often it is necessary to synchronize the group lock with an external lock. By external, it means a lock owned by object outside the group, and it’s not possible to to add that object to the group. The PJSUA lock is an example of such locks. It is not possible for PJSUA to use the group lock of ICE, for example, simply because there can be many of them. And ICE sessions come and goe (hence their group locks will be destroyed), while PJSUA lock needs to live forever. An alternative approach exists, i.e. for PJSUA to instantiate a group lock and make ICE (and other objects that potentially can use group lock) use this group lock as their lock. But by using this approach, effectively we are making the whole library single threaded, which is not efficient. 
     102 
     103The synchronization feature solves this problem by "chaining" the external lock to the group lock. Once lock A is ''chained'' to the group lock, then every time the group lock is acquired, lock A will be acquired too, and always in the same order, hence preventing the deadlock. And better yet, the code that uses lock A does not need to be aware about the group lock. It can continue to use only lock A, and still the lock ordering is obeyed. 
     104 
     105Consider the following example with PJSUA lock. (Note: this example is currently only hypothetical since it's not yet implemented) 
     106 
     107 1. The PJSUA-LIB library continues to use an internal lock object for it's synchronization. 
     108 2. ICE object creates group lock, and chain PJSUA-LIB's lock to its group lock at the first position (hence PJSUA-LIB's lock will be locked first when group lock is acquired). 
     109 3. An operation is performed in PJSUA-LIB, and PJSUA-LIB acquires PJSUA lock. This is done using existing lock API since PJSUA-LIB is not made aware about group lock. At some point during this operation, ICE operation is performed and ultimately the ICE group lock is acquired. All of these operations will cause locks to be acquired with the order that is depicted below: 
     110  {{{ 
     111pjsua --> { pjsua --> ice } 
     112  }}} 
     113 Note: the locks inside curly brackets are the group lock's total lock, which consists of pjsua as an external (chained) lock in the first position and it's own lock (marked as "ice" that is created by the group lock). 
     114 4. From a worker thread, an event occurs in ICE (such as incoming packet), which cause ice group lock to be acquired. The processing then calls a high level PJSUA-LIB callback, which acquires PJSUA's lock. The whole lock order then is depicted below. 
     115  {{{ 
     116{ pjsua --> ice } --> pjsua 
     117  }}} 
     118 
     119As shown above, the lock order between "pjsua" and "ice" is maintained uniformly, hence deadlock is avoided. 
     120 
     121For a more complete solution, the PJSUA-LIB's lock itself can be changed to a group lock, which can be synchronized to external lock such as application lock, hence making the whole system deadlock proof. 
    102122 
    103123Use the API below to synchronize an external lock with the group lock: