Changeset 6037
- Timestamp:
- Jul 10, 2019 7:15:08 AM (5 years ago)
- Location:
- pjproject/trunk/pjsip
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip/include/pjsip/sip_dialog.h
r5456 r6037 142 142 char obj_name[PJ_MAX_OBJ_NAME]; /**< Standard id. */ 143 143 pj_pool_t *pool; /**< Dialog's pool. */ 144 pj_mutex_t *mutex_; /**< Dialog's mutex. Do not call!!145 Use pjsip_dlg_inc_lock() instead! */146 144 pjsip_user_agent *ua; /**< User agent instance. */ 147 145 pjsip_endpoint *endpt; /**< Endpoint instance. */ 146 pj_grp_lock_t *grp_lock_; /**< Dialog's grp lock. Do not call!! 147 Use pjsip_dlg_inc_lock() instead! */ 148 148 149 149 /** The dialog set which this dialog belongs (opaque type). */ … … 192 192 const void *via_tp; /**< Via transport. */ 193 193 }; 194 195 /** 196 * The parameter for \a pjsip_dlg_create_uac2(). 197 */ 198 typedef struct pjsip_dlg_create_uac_param { 199 /** 200 * The user agent module instance. 201 */ 202 pjsip_user_agent *ua; 203 204 /** 205 * Dialog local URI (i.e. From header). 206 */ 207 pj_str_t local_uri; 208 209 /** 210 * Optional dialog local Contact to be put as Contact header value, 211 * hence the format must follow RFC 3261 Section 20.10: 212 * When the header field value contains a display name, the URI including 213 * all URI parameters is enclosed in "<" and ">". If no "<" and ">" are 214 * present, all parameters after the URI are header parameters, not 215 * URI parameters. The display name can be tokens, or a quoted string, 216 * if a larger character set is desired. If this argument is NULL, 217 * the Contact will be taken from the local URI. 218 */ 219 pj_str_t local_contact; 220 221 /** 222 * Dialog remote URI (i.e. To header). 223 */ 224 pj_str_t remote_uri; 225 226 /** 227 * Optional initial remote target. If this argument is NULL, the initial 228 * target will be set to remote URI. 229 */ 230 pj_str_t target; 231 232 /** 233 * Optional group lock to use by this dialog. If the value is NULL, 234 * the dialog will create its own group lock. 235 */ 236 pj_grp_lock_t *grp_lock; 237 238 } pjsip_dlg_create_uac_param; 194 239 195 240 … … 249 294 pjsip_dialog **p_dlg); 250 295 296 /** 297 * Variant of pjsip_dlg_create_uac() with additional parameter to specify 298 * the group lock to use. Group lock can be used to synchronize locking 299 * among several objects to prevent deadlock, and to synchronize the 300 * lifetime of objects sharing the same group lock. 301 * 302 * See \a pjsip_dlg_create_uac() for general info about this function. 303 * 304 * @param param The parameter, refer to 305 * \a pjsip_dlg_create_uac_param 306 * @param p_dlg Pointer to receive the dialog. 307 * 308 * @return PJ_SUCCESS on success. 309 */ 310 PJ_DECL(pj_status_t) pjsip_dlg_create_uac2( 311 const pjsip_dlg_create_uac_param *create_param, 312 pjsip_dialog **p_dlg); 313 251 314 252 315 #if !DEPRECATED_FOR_TICKET_1902 … … 539 602 PJ_DECL(void) pjsip_dlg_dec_lock( pjsip_dialog *dlg ); 540 603 604 /** 605 * Get the group lock for the SIP dialog. Note that prior to calling this 606 * method, it is recommended to hold reference to the dialog 607 * (e.g: call #pjsip_dlg_inc_session() or #pjsip_dlg_inc_lock()). 608 * 609 * @param dlg The dialog. 610 * 611 * @return The group lock. 612 */ 613 PJ_DECL(pj_grp_lock_t *) pjsip_dlg_get_lock( pjsip_dialog *dlg ); 614 541 615 542 616 /** -
pjproject/trunk/pjsip/src/pjsip/sip_dialog.c
r5689 r6037 62 62 } 63 63 64 static void dlg_on_destroy( void *arg ) 65 { 66 pjsip_dialog *dlg = (pjsip_dialog *)arg; 67 68 PJ_LOG(5,(dlg->obj_name, "Dialog destroyed!")); 69 70 pjsip_endpt_release_pool(dlg->endpt, dlg->pool); 71 } 72 64 73 static pj_status_t create_dialog( pjsip_user_agent *ua, 74 pj_grp_lock_t *grp_lock, 65 75 pjsip_dialog **p_dlg) 66 76 { … … 99 109 goto on_error; 100 110 101 status = pj_mutex_create_recursive(pool, dlg->obj_name, &dlg->mutex_); 102 if (status != PJ_SUCCESS) 103 goto on_error; 111 if (grp_lock) { 112 dlg->grp_lock_ = grp_lock; 113 } else { 114 status = pj_grp_lock_create(pool, NULL, &dlg->grp_lock_); 115 if (status != PJ_SUCCESS) { 116 goto on_error; 117 } 118 } 119 120 pj_grp_lock_add_ref(dlg->grp_lock_); 121 pj_grp_lock_add_handler(dlg->grp_lock_, pool, dlg, &dlg_on_destroy); 104 122 105 123 pjsip_target_set_init(&dlg->target_set); … … 109 127 110 128 on_error: 111 if (dlg->mutex_)112 pj_mutex_destroy(dlg->mutex_);113 129 pjsip_endpt_release_pool(endpt, pool); 114 130 return status; … … 117 133 static void destroy_dialog( pjsip_dialog *dlg, pj_bool_t unlock_mutex ) 118 134 { 119 if (dlg->mutex_) {120 if (unlock_mutex) pj_mutex_unlock(dlg->mutex_);121 pj_mutex_destroy(dlg->mutex_);122 dlg->mutex_ = NULL;123 }124 135 if (dlg->tp_sel.type != PJSIP_TPSELECTOR_NONE) { 125 136 pjsip_tpselector_dec_ref(&dlg->tp_sel); … … 127 138 } 128 139 pjsip_auth_clt_deinit(&dlg->auth_sess); 129 pjsip_endpt_release_pool(dlg->endpt, dlg->pool); 130 } 131 140 141 pj_grp_lock_dec_ref(dlg->grp_lock_); 142 143 if (unlock_mutex) 144 pj_grp_lock_release(dlg->grp_lock_); 145 } 132 146 133 147 /* … … 141 155 pjsip_dialog **p_dlg) 142 156 { 157 PJ_ASSERT_RETURN(ua && local_uri && remote_uri && p_dlg, PJ_EINVAL); 158 159 pjsip_dlg_create_uac_param create_param; 160 pj_bzero(&create_param, sizeof(create_param)); 161 162 create_param.ua = ua; 163 create_param.local_uri = *local_uri; 164 create_param.remote_uri = *remote_uri; 165 if (local_contact) 166 create_param.local_contact = *local_contact; 167 168 if (target) 169 create_param.target = *target; 170 171 return pjsip_dlg_create_uac2(&create_param, p_dlg); 172 } 173 174 PJ_DEF(pj_status_t) pjsip_dlg_create_uac2( 175 const pjsip_dlg_create_uac_param *create_param, 176 pjsip_dialog **p_dlg) 177 { 143 178 pj_status_t status; 144 179 pj_str_t tmp; … … 146 181 147 182 /* Check arguments. */ 148 PJ_ASSERT_RETURN(ua && local_uri && remote_uri && p_dlg, PJ_EINVAL); 183 PJ_ASSERT_RETURN(create_param->ua && create_param->local_uri.slen && 184 create_param->remote_uri.slen && p_dlg, PJ_EINVAL); 149 185 150 186 /* Create dialog instance. */ 151 status = create_dialog( ua, &dlg);187 status = create_dialog(create_param->ua, create_param->grp_lock, &dlg); 152 188 if (status != PJ_SUCCESS) 153 189 return status; 154 190 155 191 /* Parse target. */ 156 pj_strdup_with_null(dlg->pool, &tmp, target ? target : remote_uri); 192 pj_strdup_with_null(dlg->pool, &tmp, create_param->target.slen ? 193 &create_param->target : &create_param->remote_uri); 157 194 dlg->target = pjsip_parse_uri(dlg->pool, tmp.ptr, tmp.slen, 0); 158 195 if (!dlg->target) { … … 204 241 /* Init local info. */ 205 242 dlg->local.info = pjsip_from_hdr_create(dlg->pool); 206 pj_strdup_with_null(dlg->pool, &dlg->local.info_str, local_uri); 243 pj_strdup_with_null(dlg->pool, &dlg->local.info_str, 244 &create_param->local_uri); 207 245 dlg->local.info->uri = pjsip_parse_uri(dlg->pool, 208 246 dlg->local.info_str.ptr, … … 226 264 /* Init local contact. */ 227 265 pj_strdup_with_null(dlg->pool, &tmp, 228 local_contact ? local_contact : local_uri); 266 create_param->local_contact.slen ? 267 &create_param->local_contact : &create_param->local_uri); 229 268 dlg->local.contact = (pjsip_contact_hdr*) 230 269 pjsip_parse_hdr(dlg->pool, &HCONTACT, tmp.ptr, … … 237 276 /* Init remote info. */ 238 277 dlg->remote.info = pjsip_to_hdr_create(dlg->pool); 239 pj_strdup_with_null(dlg->pool, &dlg->remote.info_str, remote_uri); 278 pj_strdup_with_null(dlg->pool, &dlg->remote.info_str, 279 &create_param->remote_uri); 240 280 dlg->remote.info->uri = pjsip_parse_uri(dlg->pool, 241 281 dlg->remote.info_str.ptr, … … 293 333 294 334 /* Register this dialog to user agent. */ 295 status = pjsip_ua_register_dlg( ua, dlg );335 status = pjsip_ua_register_dlg( create_param->ua, dlg ); 296 336 if (status != PJ_SUCCESS) 297 337 goto on_error; 298 338 299 300 339 /* Done! */ 301 340 *p_dlg = dlg; 302 303 341 304 342 PJ_LOG(5,(dlg->obj_name, "UAC dialog created")); … … 350 388 351 389 /* Create dialog instance. */ 352 status = create_dialog(ua, &dlg);390 status = create_dialog(ua, NULL, &dlg); 353 391 if (status != PJ_SUCCESS) 354 392 return status; … … 565 603 destroy_dialog(dlg, PJ_FALSE); 566 604 } 567 605 568 606 return status; 569 607 } … … 681 719 682 720 /* Create the dialog. */ 683 status = create_dialog((pjsip_user_agent*)first_dlg->ua, &dlg);721 status = create_dialog((pjsip_user_agent*)first_dlg->ua, NULL, &dlg); 684 722 if (status != PJ_SUCCESS) 685 723 return status; … … 772 810 773 811 /* 774 * Destroy dialog.812 * Unregister and destroy dialog. 775 813 */ 776 814 static pj_status_t unregister_and_destroy_dialog( pjsip_dialog *dlg, … … 797 835 } 798 836 799 /* Log */800 PJ_LOG(5,(dlg->obj_name, "Dialog destroyed"));801 802 837 /* Destroy this dialog. */ 803 838 destroy_dialog(dlg, unlock_mutex); … … 879 914 880 915 /* 881 * Lock dialog and increment session count ertemporarily916 * Lock dialog and increment session count temporarily 882 917 * to prevent it from being deleted. In addition, it must lock 883 918 * the user agent's dialog table first, to prevent deadlock. … … 888 923 dlg->sess_count)); 889 924 890 pj_ mutex_lock(dlg->mutex_);925 pj_grp_lock_acquire(dlg->grp_lock_); 891 926 dlg->sess_count++; 892 927 … … 895 930 } 896 931 897 /* Try to acquire dialog's mutex, but bail out if mutexcan not be932 /* Try to acquire dialog's group lock, but bail out if group lock can not be 898 933 * acquired immediately. 899 934 */ … … 905 940 dlg->sess_count)); 906 941 907 status = pj_ mutex_trylock(dlg->mutex_);942 status = pj_grp_lock_tryacquire(dlg->grp_lock_); 908 943 if (status != PJ_SUCCESS) { 909 944 PJ_LOG(6,(dlg->obj_name, "pjsip_dlg_try_inc_lock() failed")); … … 921 956 922 957 /* 923 * Unlock dialog and decrement sessioncounter.958 * Unlock dialog and decrement reference counter. 924 959 * It may delete the dialog! 925 960 */ … … 935 970 936 971 if (dlg->sess_count==0 && dlg->tsx_count==0) { 937 pj_ mutex_unlock(dlg->mutex_);938 pj_ mutex_lock(dlg->mutex_);939 /* We are holding the dialog mutexhere, so before we destroy972 pj_grp_lock_release(dlg->grp_lock_); 973 pj_grp_lock_acquire(dlg->grp_lock_); 974 /* We are holding the dialog group lock here, so before we destroy 940 975 * the dialog, make sure that we unlock it first to avoid 941 976 * undefined behaviour on some platforms. See ticket #1886. … … 943 978 unregister_and_destroy_dialog(dlg, PJ_TRUE); 944 979 } else { 945 pj_ mutex_unlock(dlg->mutex_);980 pj_grp_lock_release(dlg->grp_lock_); 946 981 } 947 982 … … 950 985 951 986 952 953 /* 954 * Decrement session counter. 987 /* 988 * Decrement session count. 955 989 */ 956 990 PJ_DEF(pj_status_t) pjsip_dlg_dec_session( pjsip_dialog *dlg, … … 970 1004 pj_log_pop_indent(); 971 1005 return PJ_SUCCESS; 1006 } 1007 1008 PJ_DEF(pj_grp_lock_t *) pjsip_dlg_get_lock(pjsip_dialog *dlg) 1009 { 1010 PJ_ASSERT_RETURN(dlg, NULL); 1011 return dlg->grp_lock_; 972 1012 } 973 1013 -
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_media.c
r6004 r6037 1119 1119 * https://trac.pjsip.org/repos/ticket/1737 1120 1120 */ 1121 ++dlg->sess_count;1121 pjsip_dlg_inc_session(dlg, &pjsua_var.mod); 1122 1122 pjsip_dlg_dec_lock(dlg); 1123 1123 } … … 1127 1127 if (dlg) { 1128 1128 pjsip_dlg_inc_lock(dlg); 1129 --dlg->sess_count;1129 pjsip_dlg_dec_session(dlg, &pjsua_var.mod); 1130 1130 } 1131 1131 if (has_pjsua_lock)
Note: See TracChangeset
for help on using the changeset viewer.