Ignore:
Timestamp:
Aug 10, 2006 9:44:26 PM (18 years ago)
Author:
bennylp
Message:

Attempt to fix the race condition in dialog locking.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjsip/src/pjsip/sip_dialog.c

    r635 r671  
    8181    pj_list_init(&dlg->inv_hdr); 
    8282 
    83     status = pj_mutex_create_recursive(pool, "dlg%p", &dlg->mutex); 
     83    status = pj_mutex_create_recursive(pool, "dlg%p", &dlg->mutex_); 
    8484    if (status != PJ_SUCCESS) 
    8585        goto on_error; 
     
    9090 
    9191on_error: 
    92     if (dlg->mutex) 
    93         pj_mutex_destroy(dlg->mutex); 
     92    if (dlg->mutex_) 
     93        pj_mutex_destroy(dlg->mutex_); 
    9494    pjsip_endpt_release_pool(endpt, pool); 
    9595    return status; 
     
    9898static void destroy_dialog( pjsip_dialog *dlg ) 
    9999{ 
    100     if (dlg->mutex) 
    101         pj_mutex_destroy(dlg->mutex); 
     100    if (dlg->mutex_) { 
     101        pj_mutex_destroy(dlg->mutex_); 
     102        dlg->mutex_ = NULL; 
     103    } 
    102104    pjsip_endpt_release_pool(dlg->endpt, dlg->pool); 
    103105} 
     
    607609 
    608610    /* Destroy this dialog. */ 
    609     pj_mutex_destroy(dlg->mutex); 
    610     pjsip_endpt_release_pool(dlg->endpt, dlg->pool); 
     611    destroy_dialog(dlg); 
    611612 
    612613    return PJ_SUCCESS; 
     
    639640    PJ_ASSERT_RETURN(dlg, PJ_EINVAL); 
    640641 
    641     pj_mutex_lock(dlg->mutex); 
     642    pjsip_dlg_inc_lock(dlg); 
    642643 
    643644    /* Clear route set. */ 
     
    645646 
    646647    if (!route_set) { 
    647         pj_mutex_unlock(dlg->mutex); 
     648        pjsip_dlg_dec_lock(dlg); 
    648649        return PJ_SUCCESS; 
    649650    } 
     
    659660    } 
    660661 
    661     pj_mutex_unlock(dlg->mutex); 
    662  
     662    pjsip_dlg_dec_lock(dlg); 
    663663    return PJ_SUCCESS; 
    664664} 
     
    673673    PJ_ASSERT_RETURN(dlg && mod, PJ_EINVAL); 
    674674 
    675     pj_mutex_lock(dlg->mutex); 
     675    pjsip_dlg_inc_lock(dlg); 
    676676    ++dlg->sess_count; 
    677     pj_mutex_unlock(dlg->mutex); 
     677    pjsip_dlg_dec_lock(dlg); 
    678678 
    679679    PJ_LOG(5,(dlg->obj_name, "Session count inc to %d by %.*s", 
     
    685685/* 
    686686 * Lock dialog and increment session counter temporarily 
    687  * to prevent it from being deleted. 
     687 * to prevent it from being deleted. In addition, it must lock 
     688 * the user agent's dialog table first, to prevent deadlock. 
    688689 */ 
    689690PJ_DEF(void) pjsip_dlg_inc_lock(pjsip_dialog *dlg) 
    690691{ 
    691     pj_mutex_lock(dlg->mutex); 
     692    pjsip_ua_lock_dlg_table(); 
     693 
     694    pj_mutex_lock(dlg->mutex_); 
    692695    dlg->sess_count++; 
     696 
     697    pjsip_ua_unlock_dlg_table(); 
    693698} 
    694699 
     
    700705PJ_DEF(void) pjsip_dlg_dec_lock(pjsip_dialog *dlg) 
    701706{ 
     707    pjsip_ua_lock_dlg_table(); 
     708 
    702709    pj_assert(dlg->sess_count > 0); 
    703710    --dlg->sess_count; 
    704711 
    705712    if (dlg->sess_count==0 && dlg->tsx_count==0) { 
    706         pj_mutex_unlock(dlg->mutex); 
    707         pj_mutex_lock(dlg->mutex); 
     713        pj_mutex_unlock(dlg->mutex_); 
     714        pj_mutex_lock(dlg->mutex_); 
    708715        unregister_and_destroy_dialog(dlg); 
    709716    } else { 
    710         pj_mutex_unlock(dlg->mutex); 
    711     } 
     717        pj_mutex_unlock(dlg->mutex_); 
     718    } 
     719 
     720    pjsip_ua_unlock_dlg_table(); 
    712721} 
    713722 
     
    725734              dlg->sess_count-1, (int)mod->name.slen, mod->name.ptr)); 
    726735 
    727     pj_mutex_lock(dlg->mutex); 
     736    pjsip_dlg_inc_lock(dlg); 
     737    --dlg->sess_count; 
    728738    pjsip_dlg_dec_lock(dlg); 
    729739 
     
    749759              (int)mod->name.slen, mod->name.ptr, mod_data)); 
    750760 
    751     pj_mutex_lock(dlg->mutex); 
     761    pjsip_dlg_inc_lock(dlg); 
    752762 
    753763    /* Usages are sorted on priority, lowest number first. 
     
    758768        if (dlg->usage[index] == mod) { 
    759769            pj_assert(!"This module is already registered"); 
    760             pj_mutex_unlock(dlg->mutex); 
     770            pjsip_dlg_dec_lock(dlg); 
    761771            return PJSIP_ETYPEEXISTS; 
    762772        } 
     
    778788    ++dlg->usage_cnt; 
    779789 
    780     pj_mutex_unlock(dlg->mutex); 
     790    pjsip_dlg_dec_lock(dlg); 
    781791 
    782792    return PJ_SUCCESS; 
     
    897907 
    898908    /* Lock dialog. */ 
    899     pj_mutex_lock(dlg->mutex); 
     909    pjsip_dlg_inc_lock(dlg); 
    900910 
    901911    /* Use outgoing CSeq and increment it by one. */ 
     
    922932 
    923933    /* Unlock dialog. */ 
    924     pj_mutex_unlock(dlg->mutex); 
     934    pjsip_dlg_dec_lock(dlg); 
    925935 
    926936    *p_tdata = tdata; 
     
    11141124 
    11151125    /* Lock the dialog. */ 
    1116     pj_mutex_lock(dlg->mutex); 
     1126    pjsip_dlg_inc_lock(dlg); 
    11171127 
    11181128    dlg_beautify_response(dlg, st_code, tdata); 
    11191129 
    11201130    /* Unlock the dialog. */ 
    1121     pj_mutex_unlock(dlg->mutex); 
     1131    pjsip_dlg_dec_lock(dlg); 
    11221132 
    11231133    /* Done. */ 
Note: See TracChangeset for help on using the changeset viewer.