Changeset 1401


Ignore:
Timestamp:
Jun 28, 2007 7:20:26 AM (12 years ago)
Author:
bennylp
Message:

Fixed ticket #351: Possible deadlock in pjsua-api presence subscription (thanks Paul Levin)

Location:
pjproject/trunk/pjsip
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjsip/include/pjsua-lib/pjsua_internal.h

    r1311 r1401  
    134134    unsigned             port;      /**< Buddy port.                    */ 
    135135    pj_bool_t            monitor;   /**< Should we monitor?             */ 
     136    pjsip_dialog        *dlg;       /**< The underlying dialog.         */ 
    136137    pjsip_evsub         *sub;       /**< Buddy presence subscription    */ 
    137138    pjsip_pres_status    status;    /**< Buddy presence status.         */ 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_pres.c

    r1398 r1401  
    2424 
    2525#ifndef PJSUA_PRES_TIMER 
    26 #   define PJSUA_PRES_TIMER     120 
     26#   define PJSUA_PRES_TIMER     2 
    2727#endif 
    2828 
     
    7171 
    7272    return PJ_SUCCESS; 
    73  
    7473} 
    7574 
     
    208207    pjsua_var.buddy_cnt++; 
    209208 
     209    PJSUA_UNLOCK(); 
     210 
    210211    pjsua_buddy_subscribe_pres(index, cfg->subscribe); 
    211  
    212     PJSUA_UNLOCK(); 
    213212 
    214213    return PJ_SUCCESS; 
     
    225224                     PJ_EINVAL); 
    226225 
    227     PJSUA_LOCK(); 
    228  
    229226    if (pjsua_var.buddy[buddy_id].uri.slen == 0) { 
    230         PJSUA_UNLOCK(); 
    231227        return PJ_SUCCESS; 
    232228    } 
     
    234230    /* Unsubscribe presence */ 
    235231    pjsua_buddy_subscribe_pres(buddy_id, PJ_FALSE); 
     232 
     233    PJSUA_LOCK(); 
    236234 
    237235    /* Remove buddy */ 
     
    263261    buddy = &pjsua_var.buddy[buddy_id]; 
    264262    buddy->monitor = subscribe; 
     263 
     264    PJSUA_UNLOCK(); 
     265 
    265266    pjsua_pres_refresh(); 
    266  
    267     PJSUA_UNLOCK(); 
    268267 
    269268    return PJ_SUCCESS; 
     
    10151014    pjsua_acc *acc; 
    10161015    pj_str_t contact; 
    1017     pjsip_dialog *dlg; 
    10181016    pjsip_tx_data *tdata; 
    10191017    pj_status_t status; 
     
    10401038                                   &contact, 
    10411039                                   &buddy->uri, 
    1042                                    NULL, &dlg); 
     1040                                   NULL, &buddy->dlg); 
    10431041    if (status != PJ_SUCCESS) { 
    10441042        pjsua_perror(THIS_FILE, "Unable to create dialog",  
     
    10471045    } 
    10481046 
    1049     status = pjsip_pres_create_uac( dlg, &pres_callback,  
     1047    status = pjsip_pres_create_uac( buddy->dlg, &pres_callback,  
    10501048                                    PJSIP_EVSUB_NO_EVENT_ID, &buddy->sub); 
    10511049    if (status != PJ_SUCCESS) { 
     
    10531051        pjsua_perror(THIS_FILE, "Unable to create presence client",  
    10541052                     status); 
    1055         pjsip_dlg_terminate(dlg); 
     1053        pjsip_dlg_terminate(buddy->dlg); 
    10561054        return; 
    10571055    } 
     
    10641062 
    10651063        pjsua_init_tpselector(acc->cfg.transport_id, &tp_sel); 
    1066         pjsip_dlg_set_transport(dlg, &tp_sel); 
     1064        pjsip_dlg_set_transport(buddy->dlg, &tp_sel); 
    10671065    } 
    10681066 
    10691067    /* Set route-set */ 
    10701068    if (!pj_list_empty(&acc->route_set)) { 
    1071         pjsip_dlg_set_route_set(dlg, &acc->route_set); 
     1069        pjsip_dlg_set_route_set(buddy->dlg, &acc->route_set); 
    10721070    } 
    10731071 
    10741072    /* Set credentials */ 
    10751073    if (acc->cred_cnt) { 
    1076         pjsip_auth_clt_set_credentials( &dlg->auth_sess,  
     1074        pjsip_auth_clt_set_credentials( &buddy->dlg->auth_sess,  
    10771075                                        acc->cred_cnt, acc->cred); 
    10781076    } 
     
    11381136 
    11391137 
     1138/* Lock all buddies */ 
     1139#define LOCK_BUDDIES    unsigned cnt_ = 0; \ 
     1140                        pjsip_dialog *dlg_list_[PJSUA_MAX_BUDDIES]; \ 
     1141                        unsigned i_; \ 
     1142                        for (i_=0; i_<PJ_ARRAY_SIZE(pjsua_var.buddy);++i_) { \ 
     1143                            if (pjsua_var.buddy[i_].sub) { \ 
     1144                                dlg_list_[cnt_++] = pjsua_var.buddy[i_].dlg; \ 
     1145                                pjsip_dlg_inc_lock(pjsua_var.buddy[i_].dlg); \ 
     1146                            } \ 
     1147                        } \ 
     1148                        PJSUA_LOCK(); 
     1149 
     1150/* Unlock all buddies */ 
     1151#define UNLOCK_BUDDIES  PJSUA_UNLOCK(); \ 
     1152                        for (i_=0; i_<cnt_; ++i_) { \ 
     1153                            pjsip_dlg_dec_lock(dlg_list_[i_]); \ 
     1154                        } 
     1155                         
     1156 
     1157 
    11401158/* It does what it says.. */ 
    11411159static void refresh_client_subscriptions(void) 
     
    11431161    unsigned i; 
    11441162 
     1163    LOCK_BUDDIES; 
     1164 
    11451165    for (i=0; i<PJ_ARRAY_SIZE(pjsua_var.buddy); ++i) { 
    11461166 
     
    11561176        } 
    11571177    } 
     1178 
     1179    UNLOCK_BUDDIES; 
    11581180} 
    11591181 
     
    11641186    pj_time_val delay = { PJSUA_PRES_TIMER, 0 }; 
    11651187 
    1166     PJ_UNUSED_ARG(th); 
    1167  
    1168     PJSUA_LOCK(); 
    1169  
    11701188    entry->id = PJ_FALSE; 
    11711189    refresh_client_subscriptions(); 
     
    11741192    entry->id = PJ_TRUE; 
    11751193 
    1176     PJSUA_UNLOCK(); 
     1194    PJ_UNUSED_ARG(th); 
    11771195} 
    11781196 
Note: See TracChangeset for help on using the changeset viewer.