Changeset 729 for pjproject


Ignore:
Timestamp:
Sep 19, 2006 1:37:53 PM (18 years ago)
Author:
bennylp
Message:

Fixed race-condition/deadlock problems in the dialog/user agent layer
all the way up to PJSUA-API:

  • standardized locking order: dialog then user agent, and dialog then PJSUA
  • any threads that attempt to acquire mutexes in different order than above MUST employ retry mechanism (for an example, see acquire_call() in pjsua_call.c). This retry mechanism has also been used in the UA layer (sip_ua_layer.c) since it needs to lock user agent layer first before the dialog.
  • introduced pjsip_dlg_try_inc_lock() and PJSUA_TRY_LOCK() to accomodate above.
  • pjsua tested on Quad Xeon with 4 threads and 200 cps, so far so good.
Location:
pjproject/trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjsip-apps/src/pjsua/pjsua_app.c

    r721 r729  
    11971197    PJ_UNUSED_ARG(timer_heap); 
    11981198 
     1199    if (call_id == PJSUA_INVALID_ID) { 
     1200        PJ_LOG(1,(THIS_FILE, "Invalid call ID in timer callback")); 
     1201        return; 
     1202    } 
     1203     
    11991204    /* Add warning header */ 
    12001205    pjsua_msg_data_init(&msg_data); 
  • pjproject/trunk/pjsip/include/pjsip/sip_dialog.h

    r671 r729  
    357357 
    358358/** 
     359 * Try to acquire dialog's lock, but return immediately if lock can not 
     360 * be acquired. 
     361 * 
     362 * @param dlg               The dialog. 
     363 * 
     364 * @return                  PJ_SUCCESS if lock has been acquired. 
     365 */ 
     366PJ_DECL(pj_status_t) pjsip_dlg_try_inc_lock( pjsip_dialog *dlg ); 
     367 
     368/** 
    359369 * Unlock dialog and decrement temporary session counter. After this function 
    360370 * is called, dialog may be destroyed. 
  • pjproject/trunk/pjsip/include/pjsip/sip_ua_layer.h

    r671 r729  
    8282 
    8383/** 
    84  * Lock the dialog's hash table. This function is normally called by 
    85  * dialog code only. 
    86  * 
    87  * @return              PJ_SUCCESS on success or the appropriate error code. 
    88  */ 
    89 PJ_DECL(pj_status_t) pjsip_ua_lock_dlg_table(void); 
    90  
    91  
    92 /** 
    93  * Unlock the dialog's hash table. This function is normally called by 
    94  * dialog code only. 
    95  * 
    96  * @return              PJ_SUCCESS on success or the appropriate error code. 
    97  */ 
    98 PJ_DECL(pj_status_t) pjsip_ua_unlock_dlg_table(void); 
    99  
    100  
    101 /** 
    10284 * Destroy the user agent layer. 
    10385 * 
  • pjproject/trunk/pjsip/include/pjsua-lib/pjsua_internal.h

    r685 r729  
    258258 
    259259 
    260 #if 0 
    261 #define PJSUA_LOCK()        pj_mutex_lock(pjsua_var.mutex); 
    262 #define PJSUA_UNLOCK()      pj_mutex_unlock(pjsua_var.mutex); 
     260#if 1 
     261#define PJSUA_LOCK()        pj_mutex_lock(pjsua_var.mutex) 
     262#define PJSUA_TRY_LOCK()    pj_mutex_trylock(pjsua_var.mutex) 
     263#define PJSUA_UNLOCK()      pj_mutex_unlock(pjsua_var.mutex) 
    263264#else 
    264265#define PJSUA_LOCK() 
     266#define PJSUA_TRY_LOCK()    PJ_SUCCESS 
    265267#define PJSUA_UNLOCK() 
    266268#endif 
  • pjproject/trunk/pjsip/src/pjsip/sip_dialog.c

    r675 r729  
    693693              dlg->sess_count)); 
    694694 
    695     pjsip_ua_lock_dlg_table(); 
    696  
    697695    pj_mutex_lock(dlg->mutex_); 
    698696    dlg->sess_count++; 
    699697 
    700     //pjsip_ua_unlock_dlg_table(); 
    701  
    702698    PJ_LOG(6,(dlg->obj_name, "Leaving pjsip_dlg_inc_lock(), sess_count=%d",  
    703699              dlg->sess_count)); 
    704700} 
    705701 
     702/* Try to acquire dialog's mutex, but bail out if mutex can not be 
     703 * acquired immediately. 
     704 */ 
     705PJ_DEF(pj_status_t) pjsip_dlg_try_inc_lock(pjsip_dialog *dlg) 
     706{ 
     707    pj_status_t status; 
     708 
     709    PJ_LOG(6,(dlg->obj_name,"Entering pjsip_dlg_try_inc_lock(), sess_count=%d",  
     710              dlg->sess_count)); 
     711 
     712    status = pj_mutex_trylock(dlg->mutex_); 
     713    if (status != PJ_SUCCESS) { 
     714        PJ_LOG(6,(dlg->obj_name, "pjsip_dlg_try_inc_lock() failed")); 
     715        return status; 
     716    } 
     717 
     718    dlg->sess_count++; 
     719 
     720    PJ_LOG(6,(dlg->obj_name, "Leaving pjsip_dlg_try_inc_lock(), sess_count=%d",  
     721              dlg->sess_count)); 
     722 
     723    return PJ_SUCCESS; 
     724} 
     725 
    706726 
    707727/* 
     
    713733    PJ_LOG(6,(dlg->obj_name, "Entering pjsip_dlg_dec_lock(), sess_count=%d",  
    714734              dlg->sess_count)); 
    715  
    716     //pjsip_ua_lock_dlg_table(); 
    717735 
    718736    pj_assert(dlg->sess_count > 0); 
     
    726744        pj_mutex_unlock(dlg->mutex_); 
    727745    } 
    728  
    729     pjsip_ua_unlock_dlg_table(); 
    730746 
    731747    PJ_LOG(6,(THIS_FILE, "Leaving pjsip_dlg_dec_lock() (dlg=%p)", dlg)); 
  • pjproject/trunk/pjsip/src/pjsip/sip_ua_layer.c

    r673 r729  
    210210 
    211211 
    212 /** 
    213  * Lock the dialog's hash table. This function is normally called by 
    214  * dialog code only. 
    215  * 
    216  * @return              PJ_SUCCESS on success or the appropriate error code. 
    217  */ 
    218 PJ_DEF(pj_status_t) pjsip_ua_lock_dlg_table(void) 
    219 { 
    220     return pj_mutex_lock(mod_ua.mutex); 
    221 } 
    222  
    223  
    224 /** 
    225  * Unlock the dialog's hash table. This function is normally called by 
    226  * dialog code only. 
    227  * 
    228  * @return              PJ_SUCCESS on success or the appropriate error code. 
    229  */ 
    230 PJ_DEF(pj_status_t) pjsip_ua_unlock_dlg_table(void) 
    231 { 
    232     return pj_mutex_unlock(mod_ua.mutex); 
    233 } 
    234  
    235  
    236212/* 
    237213 * Get the endpoint where this UA is currently registered. 
     
    500476    pj_str_t *from_tag; 
    501477    pjsip_dialog *dlg; 
     478    pj_status_t status; 
    502479 
    503480    /* Optimized path: bail out early if request is not CANCEL and it doesn't 
     
    509486        return PJ_FALSE; 
    510487    } 
     488 
     489retry_on_deadlock: 
    511490 
    512491    /* Lock user agent before looking up the dialog hash table. */ 
     
    586565    rdata->endpt_info.mod_data[mod_ua.mod.id] = dlg; 
    587566 
    588     /* Lock the dialog */ 
     567    /* Try to lock the dialog */ 
    589568    PJ_LOG(6,(dlg->obj_name, "UA layer acquiring dialog lock for request")); 
    590     pjsip_dlg_inc_lock(dlg); 
     569    status = pjsip_dlg_try_inc_lock(dlg); 
     570    if (status != PJ_SUCCESS) { 
     571        /* Failed to acquire dialog mutex immediately, this could be  
     572         * because of deadlock. Release UA mutex, yield, and retry  
     573         * the whole thing once again. 
     574         */ 
     575        pj_mutex_unlock(mod_ua.mutex); 
     576        pj_thread_sleep(0); 
     577        goto retry_on_deadlock; 
     578    } 
     579 
     580    /* Done with processing in UA layer, release lock */ 
     581    pj_mutex_unlock(mod_ua.mutex); 
    591582 
    592583    /* Pass to dialog. */ 
     
    596587    pjsip_dlg_dec_lock(dlg); 
    597588 
    598     /* Done processing in the UA */ 
    599     pj_mutex_unlock(mod_ua.mutex); 
    600  
    601589    /* Report as handled. */ 
    602590    return PJ_TRUE; 
     
    610598    pjsip_transaction *tsx; 
    611599    struct dlg_set *dlg_set; 
    612     pjsip_dialog *dlg = NULL; 
     600    pjsip_dialog *dlg; 
     601    pj_status_t status; 
    613602 
    614603    /* 
     
    621610     * the response is a forked response. 
    622611     */ 
     612 
     613retry_on_deadlock: 
     614 
     615    dlg = NULL; 
    623616 
    624617    /* Lock user agent dlg table before we're doing anything. */ 
     
    783776    rdata->endpt_info.mod_data[mod_ua.mod.id] = dlg; 
    784777 
    785     /* Acquire lock to the dialog. */ 
     778    /* Attempt to acquire lock to the dialog. */ 
    786779    PJ_LOG(6,(dlg->obj_name, "UA layer acquiring dialog lock for response")); 
    787     pjsip_dlg_inc_lock(dlg); 
     780    status = pjsip_dlg_try_inc_lock(dlg); 
     781    if (status != PJ_SUCCESS) { 
     782        /* Failed to acquire dialog mutex. This could indicate a deadlock 
     783         * situation, and for safety, try to avoid deadlock by releasing 
     784         * UA mutex, yield, and retry the whole processing once again. 
     785         */ 
     786        pj_mutex_unlock(mod_ua.mutex); 
     787        pj_thread_sleep(0); 
     788        goto retry_on_deadlock; 
     789    } 
     790 
     791    /* We're done with processing in the UA layer, we can release the mutex */ 
     792    pj_mutex_unlock(mod_ua.mutex); 
    788793 
    789794    /* Pass the response to the dialog. */ 
     
    792797    /* Unlock the dialog. This may destroy the dialog. */ 
    793798    pjsip_dlg_dec_lock(dlg); 
    794  
    795     /* Unlock dialog hash table. */ 
    796     pj_mutex_unlock(mod_ua.mutex); 
    797799 
    798800    /* Done. */ 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c

    r719 r729  
    384384        return PJ_FALSE; 
    385385 
     386    PJSUA_LOCK(); 
    386387 
    387388    /* Verify that we can handle the request. */ 
     
    408409        } 
    409410 
     411        PJSUA_UNLOCK(); 
    410412        return PJ_TRUE; 
    411413    }  
     
    428430        PJ_LOG(2,(THIS_FILE,  
    429431                  "Unable to accept incoming call (too many calls)")); 
     432        PJSUA_UNLOCK(); 
    430433        return PJ_TRUE; 
    431434    } 
     
    446449        pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata, 500, NULL, 
    447450                                      NULL, NULL); 
     451        PJSUA_UNLOCK(); 
    448452        return PJ_TRUE; 
    449453    } 
     
    463467        pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata, 500, NULL, 
    464468                                      NULL, NULL); 
     469        PJSUA_UNLOCK(); 
    465470        return PJ_TRUE; 
    466471    } 
     
    472477        pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata, 500, NULL, 
    473478                                      NULL, NULL); 
    474  
     479        PJSUA_UNLOCK(); 
    475480        return PJ_TRUE; 
    476481    } 
     
    500505        pjsip_dlg_terminate(dlg); 
    501506         */ 
     507        PJSUA_UNLOCK(); 
    502508        return PJ_TRUE; 
    503509    } 
     
    521527        pjsip_dlg_respond(dlg, rdata, 500, NULL, NULL, NULL); 
    522528        pjsip_inv_terminate(inv, 500, PJ_FALSE); 
     529        PJSUA_UNLOCK(); 
    523530        return PJ_TRUE; 
    524531 
     
    537544 
    538545    /* This INVITE request has been handled. */ 
     546    PJSUA_UNLOCK(); 
    539547    return PJ_TRUE; 
    540548} 
     
    566574 
    567575 
     576/* Acquire lock to the specified call_id */ 
     577static pj_status_t acquire_call(const char *title, 
     578                                pjsua_call_id call_id, 
     579                                pjsua_call **p_call) 
     580{ 
     581    enum { MAX_RETRY=50 }; 
     582    unsigned retry; 
     583    pjsua_call *call; 
     584    pj_bool_t has_pjsua_lock; 
     585    pj_status_t status; 
     586 
     587    for (retry=0; retry<MAX_RETRY; ++retry) { 
     588         
     589        has_pjsua_lock = PJ_FALSE; 
     590 
     591        status = PJSUA_TRY_LOCK(); 
     592        if (status != PJ_SUCCESS) { 
     593            pj_thread_sleep(retry/10); 
     594            continue; 
     595        } 
     596 
     597        has_pjsua_lock = PJ_TRUE; 
     598        call = &pjsua_var.calls[call_id]; 
     599 
     600        if (call->inv == NULL) { 
     601            PJSUA_UNLOCK(); 
     602            PJ_LOG(3,(THIS_FILE, "Invalid call_id %d in %s", call_id, title)); 
     603            return PJSIP_ESESSIONTERMINATED; 
     604        } 
     605 
     606        status = pjsip_dlg_try_inc_lock(call->inv->dlg); 
     607        if (status != PJ_SUCCESS) { 
     608            PJSUA_UNLOCK(); 
     609            pj_thread_sleep(retry/10); 
     610            continue; 
     611        } 
     612 
     613        PJSUA_UNLOCK(); 
     614 
     615        break; 
     616    } 
     617 
     618    if (status != PJ_SUCCESS) { 
     619        if (has_pjsua_lock == PJ_FALSE) 
     620            PJ_LOG(1,(THIS_FILE, "Timed-out trying to acquire PJSUA mutex " 
     621                                 "(possibly system has deadlocked) in %s", 
     622                                 title)); 
     623        else 
     624            PJ_LOG(1,(THIS_FILE, "Timed-out trying to acquire dialog mutex " 
     625                                 "(possibly system has deadlocked) in %s", 
     626                                 title)); 
     627        return PJ_ETIMEDOUT; 
     628    } 
     629     
     630    *p_call = call; 
     631 
     632    return PJ_SUCCESS; 
     633} 
     634 
     635 
    568636/* 
    569637 * Get the conference port identification associated with the call. 
     
    571639PJ_DEF(pjsua_conf_port_id) pjsua_call_get_conf_port(pjsua_call_id call_id) 
    572640{ 
     641    pjsua_call *call; 
     642    pjsua_conf_port_id port_id; 
     643    pj_status_t status; 
     644 
    573645    PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,  
    574646                     PJ_EINVAL); 
    575     return pjsua_var.calls[call_id].conf_slot; 
    576 } 
     647 
     648    status = acquire_call("pjsua_call_get_conf_port()", call_id, &call); 
     649    if (status != PJ_SUCCESS) 
     650        return -1; 
     651 
     652    port_id = call->conf_slot; 
     653 
     654    pjsip_dlg_dec_lock(call->inv->dlg); 
     655 
     656    return port_id; 
     657} 
     658 
    577659 
    578660 
     
    584666{ 
    585667    pjsua_call *call; 
     668    pj_status_t status; 
    586669 
    587670    PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls, 
     
    590673    pj_bzero(info, sizeof(*info)); 
    591674 
    592     PJSUA_LOCK(); 
    593  
    594     call = &pjsua_var.calls[call_id]; 
    595  
    596     if (call->inv == NULL) { 
    597         PJSUA_UNLOCK(); 
    598         return PJ_SUCCESS; 
    599     } 
    600  
    601     pjsip_dlg_inc_lock(call->inv->dlg); 
    602  
     675    status = acquire_call("pjsua_call_get_info()", call_id, &call); 
     676    if (status != PJ_SUCCESS) { 
     677        return status; 
     678    } 
    603679 
    604680    /* id and role */ 
     
    697773 
    698774    pjsip_dlg_dec_lock(call->inv->dlg); 
    699     PJSUA_UNLOCK(); 
    700775 
    701776    return PJ_SUCCESS; 
     
    743818                     PJ_EINVAL); 
    744819 
    745     PJSUA_LOCK(); 
    746  
    747     call = &pjsua_var.calls[call_id]; 
    748  
    749     if (call->inv == NULL) { 
    750         PJ_LOG(3,(THIS_FILE, "Call %d already disconnected", call_id)); 
    751         PJSUA_UNLOCK(); 
    752         return PJSIP_ESESSIONTERMINATED; 
    753     } 
     820    status = acquire_call("pjsua_call_answer()", call_id, &call); 
     821    if (status != PJ_SUCCESS) 
     822        return status; 
    754823 
    755824    if (call->res_time.sec == 0) 
     
    761830        pjsua_perror(THIS_FILE, "Error creating response",  
    762831                     status); 
    763         PJSUA_UNLOCK(); 
     832        pjsip_dlg_dec_lock(call->inv->dlg); 
    764833        return status; 
    765834    } 
     
    774843                     status); 
    775844 
    776     PJSUA_UNLOCK(); 
     845    pjsip_dlg_dec_lock(call->inv->dlg); 
    777846 
    778847    return status; 
     
    794863 
    795864 
     865    if (call_id<0 || call_id>=(int)pjsua_var.ua_cfg.max_calls) { 
     866        PJ_LOG(1,(THIS_FILE, "pjsua_call_hangup(): invalid call id %d", 
     867                             call_id)); 
     868    } 
     869     
    796870    PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls, 
    797871                     PJ_EINVAL); 
    798872 
    799     PJSUA_LOCK(); 
    800  
    801     call = &pjsua_var.calls[call_id]; 
    802  
    803     if (!call->inv) { 
    804         PJ_LOG(3,(THIS_FILE,"Invalid call or call has been disconnected")); 
    805         PJSUA_UNLOCK(); 
    806         return PJ_EINVAL; 
    807     } 
     873    status = acquire_call("pjsua_call_hangup()", call_id, &call); 
     874    if (status != PJ_SUCCESS) 
     875        return status; 
    808876 
    809877    if (code==0) { 
     
    821889                     "Failed to create end session message",  
    822890                     status); 
    823         PJSUA_UNLOCK(); 
     891        pjsip_dlg_dec_lock(call->inv->dlg); 
    824892        return status; 
    825893    } 
     
    830898     */ 
    831899    if (tdata == NULL) { 
    832         PJSUA_UNLOCK(); 
     900        pjsip_dlg_dec_lock(call->inv->dlg); 
    833901        return PJ_SUCCESS; 
    834902    } 
     
    843911                     "Failed to send end session message",  
    844912                     status); 
    845         PJSUA_UNLOCK(); 
     913        pjsip_dlg_dec_lock(call->inv->dlg); 
    846914        return status; 
    847915    } 
    848916 
    849     PJSUA_UNLOCK(); 
     917    pjsip_dlg_dec_lock(call->inv->dlg); 
    850918 
    851919    return PJ_SUCCESS; 
     
    867935                     PJ_EINVAL); 
    868936 
    869     PJSUA_LOCK(); 
    870  
    871     call = &pjsua_var.calls[call_id]; 
    872      
    873     if (!call->inv) { 
    874         PJ_LOG(3,(THIS_FILE,"Call has been disconnected")); 
    875         PJSUA_UNLOCK(); 
    876         return PJSIP_ESESSIONTERMINATED; 
    877     } 
     937    status = acquire_call("pjsua_call_set_hold()", call_id, &call); 
     938    if (status != PJ_SUCCESS) 
     939        return status; 
     940 
    878941 
    879942    if (call->inv->state != PJSIP_INV_STATE_CONFIRMED) { 
    880943        PJ_LOG(3,(THIS_FILE, "Can not hold call that is not confirmed")); 
    881         PJSUA_UNLOCK(); 
     944        pjsip_dlg_dec_lock(call->inv->dlg); 
    882945        return PJSIP_ESESSIONSTATE; 
    883946    } 
     
    885948    status = create_inactive_sdp(call, &sdp); 
    886949    if (status != PJ_SUCCESS) { 
    887         PJSUA_UNLOCK(); 
     950        pjsip_dlg_dec_lock(call->inv->dlg); 
    888951        return status; 
    889952    } 
     
    893956    if (status != PJ_SUCCESS) { 
    894957        pjsua_perror(THIS_FILE, "Unable to create re-INVITE", status); 
    895         PJSUA_UNLOCK(); 
     958        pjsip_dlg_dec_lock(call->inv->dlg); 
    896959        return status; 
    897960    } 
     
    904967    if (status != PJ_SUCCESS) { 
    905968        pjsua_perror(THIS_FILE, "Unable to send re-INVITE", status); 
    906         PJSUA_UNLOCK(); 
     969        pjsip_dlg_dec_lock(call->inv->dlg); 
    907970        return status; 
    908971    } 
    909972 
    910     PJSUA_UNLOCK(); 
     973    pjsip_dlg_dec_lock(call->inv->dlg); 
    911974 
    912975    return PJ_SUCCESS; 
     
    930993                     PJ_EINVAL); 
    931994 
    932     PJSUA_LOCK(); 
    933  
    934     call = &pjsua_var.calls[call_id]; 
    935  
    936     if (!call->inv) { 
    937         PJ_LOG(3,(THIS_FILE,"Call has been disconnected")); 
    938         PJSUA_UNLOCK(); 
    939         return PJSIP_ESESSIONTERMINATED; 
    940     } 
    941  
     995    status = acquire_call("pjsua_call_reinvite()", call_id, &call); 
     996    if (status != PJ_SUCCESS) 
     997        return status; 
    942998 
    943999    if (call->inv->state != PJSIP_INV_STATE_CONFIRMED) { 
    9441000        PJ_LOG(3,(THIS_FILE, "Can not re-INVITE call that is not confirmed")); 
    945         PJSUA_UNLOCK(); 
     1001        pjsip_dlg_dec_lock(call->inv->dlg); 
    9461002        return PJSIP_ESESSIONSTATE; 
    9471003    } 
     
    9551011        pjsua_perror(THIS_FILE, "Unable to get SDP from media endpoint",  
    9561012                     status); 
    957         PJSUA_UNLOCK(); 
     1013        pjsip_dlg_dec_lock(call->inv->dlg); 
    9581014        return status; 
    9591015    } 
     
    9631019    if (status != PJ_SUCCESS) { 
    9641020        pjsua_perror(THIS_FILE, "Unable to create re-INVITE", status); 
    965         PJSUA_UNLOCK(); 
     1021        pjsip_dlg_dec_lock(call->inv->dlg); 
    9661022        return status; 
    9671023    } 
     
    9741030    if (status != PJ_SUCCESS) { 
    9751031        pjsua_perror(THIS_FILE, "Unable to send re-INVITE", status); 
    976         PJSUA_UNLOCK(); 
     1032        pjsip_dlg_dec_lock(call->inv->dlg); 
    9771033        return status; 
    9781034    } 
    9791035 
    980     PJSUA_UNLOCK(); 
     1036    pjsip_dlg_dec_lock(call->inv->dlg); 
    9811037 
    9821038    return PJ_SUCCESS; 
     
    10001056                     PJ_EINVAL); 
    10011057     
    1002     PJSUA_LOCK(); 
    1003  
    1004     call = &pjsua_var.calls[call_id]; 
    1005  
    1006     if (!call->inv) { 
    1007         PJ_LOG(3,(THIS_FILE,"Call has been disconnected")); 
    1008         PJSUA_UNLOCK(); 
    1009         return PJSIP_ESESSIONTERMINATED; 
    1010     } 
     1058    pjsip_dlg_dec_lock(call->inv->dlg); 
     1059    status = acquire_call("pjsua_call_xfer()", call_id, &call); 
     1060    if (status != PJ_SUCCESS) 
     1061        return status; 
     1062 
    10111063    
    10121064    /* Create xfer client subscription. 
     
    10171069    if (status != PJ_SUCCESS) { 
    10181070        pjsua_perror(THIS_FILE, "Unable to create xfer", status); 
    1019         PJSUA_UNLOCK(); 
     1071        pjsip_dlg_dec_lock(call->inv->dlg); 
    10201072        return status; 
    10211073    } 
     
    10271079    if (status != PJ_SUCCESS) { 
    10281080        pjsua_perror(THIS_FILE, "Unable to create REFER request", status); 
    1029         PJSUA_UNLOCK(); 
     1081        pjsip_dlg_dec_lock(call->inv->dlg); 
    10301082        return status; 
    10311083    } 
     
    10381090    if (status != PJ_SUCCESS) { 
    10391091        pjsua_perror(THIS_FILE, "Unable to send REFER request", status); 
    1040         PJSUA_UNLOCK(); 
     1092        pjsip_dlg_dec_lock(call->inv->dlg); 
    10411093        return status; 
    10421094    } 
     
    10471099     */ 
    10481100 
    1049     PJSUA_UNLOCK(); 
     1101    pjsip_dlg_dec_lock(call->inv->dlg); 
    10501102 
    10511103    return PJ_SUCCESS; 
     
    10661118                     PJ_EINVAL); 
    10671119     
    1068     PJSUA_LOCK(); 
     1120    status = acquire_call("pjsua_call_dial_dtmf()", call_id, &call); 
     1121    if (status != PJ_SUCCESS) 
     1122        return status; 
    10691123 
    10701124    call = &pjsua_var.calls[call_id]; 
     
    10721126    if (!call->session) { 
    10731127        PJ_LOG(3,(THIS_FILE, "Media is not established yet!")); 
    1074         PJSUA_UNLOCK(); 
     1128        pjsip_dlg_dec_lock(call->inv->dlg); 
    10751129        return PJ_EINVALIDOP; 
    10761130    } 
     
    10781132    status = pjmedia_session_dial_dtmf( call->session, 0, digits); 
    10791133 
    1080     PJSUA_UNLOCK(); 
     1134    pjsip_dlg_dec_lock(call->inv->dlg); 
    10811135 
    10821136    return status; 
     
    11041158                     PJ_EINVAL); 
    11051159 
    1106     PJSUA_LOCK(); 
    1107  
    1108     call = &pjsua_var.calls[call_id]; 
    1109  
    1110     if (!call->inv) { 
    1111         PJ_LOG(3,(THIS_FILE,"Call has been disconnected")); 
    1112         PJSUA_UNLOCK(); 
    1113         return PJSIP_ESESSIONTERMINATED; 
    1114     } 
    1115  
    1116     /* Lock dialog. */ 
    1117     pjsip_dlg_inc_lock(call->inv->dlg); 
    1118  
     1160    status = acquire_call("pjsua_call_send_im", call_id, &call); 
     1161    if (status != PJ_SUCCESS) 
     1162        return status; 
     1163     
    11191164    /* Set default media type if none is specified */ 
    11201165    if (mime_type == NULL) { 
     
    11681213on_return: 
    11691214    pjsip_dlg_dec_lock(call->inv->dlg); 
    1170     PJSUA_UNLOCK(); 
    11711215    return status; 
    11721216} 
     
    11841228    pj_status_t status; 
    11851229 
    1186  
    11871230    PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls, 
    11881231                     PJ_EINVAL); 
    11891232 
    1190     PJSUA_LOCK(); 
    1191  
    1192     call = &pjsua_var.calls[call_id]; 
    1193  
    1194     if (!call->inv) { 
    1195         PJ_LOG(3,(THIS_FILE,"Call has been disconnected")); 
    1196         PJSUA_UNLOCK(); 
    1197         return PJSIP_ESESSIONTERMINATED; 
    1198     } 
    1199  
    1200     /* Lock dialog. */ 
    1201     pjsip_dlg_inc_lock(call->inv->dlg); 
    1202      
     1233    status = acquire_call("pjsua_call_send_typing_ind", call_id, &call); 
     1234    if (status != PJ_SUCCESS) 
     1235        return status; 
     1236 
    12031237    /* Create request message. */ 
    12041238    status = pjsip_dlg_create_request( call->inv->dlg, &pjsip_message_method, 
     
    12251259on_return: 
    12261260    pjsip_dlg_dec_lock(call->inv->dlg); 
    1227     PJSUA_UNLOCK(); 
    12281261    return status; 
    12291262} 
     
    15021535    char tmp[128]; 
    15031536    char *p, *end; 
     1537    pj_status_t status; 
    15041538    int len; 
    15051539 
     
    15071541                     PJ_EINVAL); 
    15081542 
    1509     PJSUA_LOCK(); 
    1510  
    1511     call = &pjsua_var.calls[call_id]; 
     1543    status = acquire_call("pjsua_call_dump()", call_id, &call); 
     1544    if (status != PJ_SUCCESS) 
     1545        return status; 
    15121546 
    15131547    *buffer = '\0'; 
     
    15151549    end = buffer + maxlen; 
    15161550    len = 0; 
    1517  
    1518     if (call->inv == NULL) { 
    1519         PJSUA_UNLOCK(); 
    1520         return PJ_EINVALIDOP; 
    1521     } 
    15221551 
    15231552    print_call(indent, call_id, tmp, sizeof(tmp)); 
     
    15701599        dump_media_session(indent, p, end-p, call->session); 
    15711600 
    1572     PJSUA_UNLOCK(); 
     1601    pjsip_dlg_dec_lock(call->inv->dlg); 
    15731602 
    15741603    return PJ_SUCCESS; 
Note: See TracChangeset for help on using the changeset viewer.