Changeset 5573


Ignore:
Timestamp:
Mar 29, 2017 2:40:48 AM (3 years ago)
Author:
ming
Message:

Fixed #2002: Deadlock between PJSUA LOCK, transaction group lock, and UA mutex

Location:
pjproject/trunk/pjsip
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjsip/include/pjsip/sip_transaction.h

    r4420 r5573  
    180180 * is created by calling #pjsip_tsx_create_key() from an incoming message. 
    181181 * 
     182 * IMPORTANT: To prevent deadlock, application should use 
     183 * #pjsip_tsx_layer_find_tsx2() instead which only adds a reference to 
     184 * the transaction instead of locking it. 
     185 * 
    182186 * @param key       The key string to find the transaction. 
    183187 * @param lock      If non-zero, transaction will be locked before the 
     
    190194PJ_DECL(pjsip_transaction*) pjsip_tsx_layer_find_tsx( const pj_str_t *key, 
    191195                                                      pj_bool_t lock ); 
     196 
     197/** 
     198 * Find a transaction with the specified key. The transaction key normally 
     199 * is created by calling #pjsip_tsx_create_key() from an incoming message. 
     200 * 
     201 * @param key       The key string to find the transaction. 
     202 * @param add_ref   If non-zero, transaction's reference will be added 
     203 *                  by one before the function returns, to make sure that 
     204 *                  it's not deleted by other threads. 
     205 * 
     206 * @return          The matching transaction instance, or NULL if transaction 
     207 *                  can not be found. 
     208 */ 
     209PJ_DECL(pjsip_transaction*) pjsip_tsx_layer_find_tsx2( const pj_str_t *key, 
     210                                                       pj_bool_t add_ref ); 
    192211 
    193212/** 
  • pjproject/trunk/pjsip/src/pjsip-ua/sip_inv.c

    r5435 r5573  
    32763276    pjsip_tsx_create_key(rdata->tp_info.pool, &key, PJSIP_ROLE_UAS, 
    32773277                         pjsip_get_invite_method(), rdata); 
    3278     invite_tsx = pjsip_tsx_layer_find_tsx(&key, PJ_TRUE); 
     3278    invite_tsx = pjsip_tsx_layer_find_tsx2(&key, PJ_TRUE); 
    32793279 
    32803280    if (invite_tsx == NULL) { 
     
    33253325 
    33263326    if (invite_tsx) 
    3327         pj_grp_lock_release(invite_tsx->grp_lock); 
     3327        pj_grp_lock_dec_ref(invite_tsx->grp_lock); 
    33283328} 
    33293329 
  • pjproject/trunk/pjsip/src/pjsip/sip_transaction.c

    r5572 r5573  
    642642 * Find a transaction. 
    643643 */ 
    644 PJ_DEF(pjsip_transaction*) pjsip_tsx_layer_find_tsx( const pj_str_t *key, 
    645                                                      pj_bool_t lock ) 
     644static pjsip_transaction* find_tsx( const pj_str_t *key, pj_bool_t lock, 
     645                                    pj_bool_t add_ref ) 
    646646{ 
    647647    pjsip_transaction *tsx; 
     
    655655    /* Prevent the transaction to get deleted before we have chance to lock it. 
    656656     */ 
    657     if (tsx && lock) 
     657    if (tsx) 
    658658        pj_grp_lock_add_ref(tsx->grp_lock); 
    659659     
     
    667667    PJ_RACE_ME(5); 
    668668 
    669     if (tsx && lock) { 
    670         pj_grp_lock_acquire(tsx->grp_lock); 
    671         pj_grp_lock_dec_ref(tsx->grp_lock); 
     669    if (tsx) { 
     670        if (lock) 
     671            pj_grp_lock_acquire(tsx->grp_lock); 
     672 
     673        if (!add_ref) 
     674            pj_grp_lock_dec_ref(tsx->grp_lock); 
    672675    } 
    673676 
    674677    return tsx; 
     678} 
     679 
     680 
     681PJ_DEF(pjsip_transaction*) pjsip_tsx_layer_find_tsx( const pj_str_t *key, 
     682                                                     pj_bool_t lock ) 
     683{ 
     684    return find_tsx(key, lock, PJ_FALSE); 
     685} 
     686 
     687 
     688PJ_DEF(pjsip_transaction*) pjsip_tsx_layer_find_tsx2( const pj_str_t *key, 
     689                                                      pj_bool_t add_ref ) 
     690{ 
     691    return find_tsx(key, PJ_FALSE, add_ref); 
    675692} 
    676693 
  • pjproject/trunk/pjsip/src/pjsip/sip_ua_layer.c

    r5456 r5573  
    552552 
    553553        /* Lookup the INVITE transaction */ 
    554         tsx = pjsip_tsx_layer_find_tsx(&key, PJ_TRUE); 
     554        tsx = pjsip_tsx_layer_find_tsx2(&key, PJ_TRUE); 
    555555 
    556556        /* We should find the dialog attached to the INVITE transaction */ 
    557557        if (tsx) { 
    558558            dlg = (pjsip_dialog*) tsx->mod_data[mod_ua.mod.id]; 
    559             pj_grp_lock_release(tsx->grp_lock); 
     559            pj_grp_lock_dec_ref(tsx->grp_lock); 
    560560 
    561561            /* Dlg may be NULL on some extreme condition 
Note: See TracChangeset for help on using the changeset viewer.