Changeset 1992 for pjproject/trunk
- Timestamp:
- Jun 6, 2008 10:52:48 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip/src/pjsip-ua/sip_reg.c
r1981 r1992 28 28 #include <pj/assert.h> 29 29 #include <pj/guid.h> 30 #include <pj/lock.h> 30 31 #include <pj/os.h> 31 32 #include <pj/pool.h> … … 64 65 pj_pool_t *pool; 65 66 pjsip_endpoint *endpt; 67 pj_lock_t *lock; 66 68 pj_bool_t _delete_flag; 67 69 pj_bool_t has_tsx; 68 pj_ int32_t busy;70 pj_atomic_t *busy_ctr; 69 71 enum regc_op current_op; 70 72 … … 130 132 regc->add_xuid_param = pjsip_cfg()->regc.add_xuid_param; 131 133 134 status = pj_lock_create_recursive_mutex(pool, pool->obj_name, 135 ®c->lock); 136 if (status != PJ_SUCCESS) { 137 pj_pool_release(pool); 138 return status; 139 } 140 141 status = pj_atomic_create(pool, 0, ®c->busy_ctr); 142 if (status != PJ_SUCCESS) { 143 pj_lock_destroy(regc->lock); 144 pj_pool_release(pool); 145 return status; 146 } 147 132 148 status = pjsip_auth_clt_init(®c->auth_sess, endpt, regc->pool, 0); 133 149 if (status != PJ_SUCCESS) … … 149 165 PJ_ASSERT_RETURN(regc, PJ_EINVAL); 150 166 151 if (regc->has_tsx || regc->busy) { 167 pj_lock_acquire(regc->lock); 168 if (regc->has_tsx || pj_atomic_get(regc->busy_ctr) != 0) { 152 169 regc->_delete_flag = 1; 153 170 regc->cb = NULL; 171 pj_lock_release(regc->lock); 154 172 } else { 155 173 pjsip_tpselector_dec_ref(®c->tp_sel); … … 162 180 regc->timer.id = 0; 163 181 } 182 pj_atomic_destroy(regc->busy_ctr); 183 pj_lock_release(regc->lock); 184 pj_lock_destroy(regc->lock); 185 regc->lock = NULL; 164 186 pjsip_endpt_release_pool(regc->endpt, regc->pool); 165 187 } … … 174 196 PJ_ASSERT_RETURN(regc && info, PJ_EINVAL); 175 197 198 pj_lock_acquire(regc->lock); 199 176 200 info->server_uri = regc->str_srv_url; 177 201 info->client_uri = regc->from_uri; 178 info->is_busy = ( regc->busy|| regc->has_tsx);202 info->is_busy = (pj_atomic_get(regc->busy_ctr) || regc->has_tsx); 179 203 info->auto_reg = regc->auto_reg; 180 204 info->interval = regc->expires; … … 194 218 info->next_reg = next_reg.sec; 195 219 } 220 221 pj_lock_release(regc->lock); 196 222 197 223 return PJ_SUCCESS; … … 505 531 PJ_ASSERT_RETURN(regc && p_tdata, PJ_EINVAL); 506 532 533 pj_lock_acquire(regc->lock); 534 507 535 status = create_request(regc, &tdata); 508 if (status != PJ_SUCCESS) 536 if (status != PJ_SUCCESS) { 537 pj_lock_release(regc->lock); 509 538 return status; 539 } 510 540 511 541 msg = tdata->msg; … … 540 570 regc->auto_reg = autoreg; 541 571 572 pj_lock_release(regc->lock); 573 542 574 /* Done */ 543 575 *p_tdata = tdata; … … 556 588 PJ_ASSERT_RETURN(regc && p_tdata, PJ_EINVAL); 557 589 590 pj_lock_acquire(regc->lock); 591 558 592 if (regc->timer.id != 0) { 559 593 pjsip_endpt_cancel_timer(regc->endpt, ®c->timer); … … 562 596 563 597 status = create_request(regc, &tdata); 564 if (status != PJ_SUCCESS) 598 if (status != PJ_SUCCESS) { 599 pj_lock_release(regc->lock); 565 600 return status; 601 } 566 602 567 603 msg = tdata->msg; … … 587 623 pjsip_msg_add_hdr(msg, hdr); 588 624 625 pj_lock_release(regc->lock); 626 589 627 *p_tdata = tdata; 590 628 return PJ_SUCCESS; … … 602 640 PJ_ASSERT_RETURN(regc && p_tdata, PJ_EINVAL); 603 641 642 pj_lock_acquire(regc->lock); 643 604 644 if (regc->timer.id != 0) { 605 645 pjsip_endpt_cancel_timer(regc->endpt, ®c->timer); … … 608 648 609 649 status = create_request(regc, &tdata); 610 if (status != PJ_SUCCESS) 650 if (status != PJ_SUCCESS) { 651 pj_lock_release(regc->lock); 611 652 return status; 653 } 612 654 613 655 msg = tdata->msg; … … 625 667 pjsip_msg_add_hdr(msg, hdr); 626 668 669 pj_lock_release(regc->lock); 670 627 671 *p_tdata = tdata; 628 672 return PJ_SUCCESS; … … 634 678 const pj_str_t contact[] ) 635 679 { 680 pj_status_t status; 681 636 682 PJ_ASSERT_RETURN(regc, PJ_EINVAL); 637 return set_contact( regc, contact_cnt, contact ); 683 684 pj_lock_acquire(regc->lock); 685 status = set_contact( regc, contact_cnt, contact ); 686 pj_lock_release(regc->lock); 687 688 return status; 638 689 } 639 690 … … 643 694 { 644 695 PJ_ASSERT_RETURN(regc, PJ_EINVAL); 696 697 pj_lock_acquire(regc->lock); 645 698 set_expires( regc, expires ); 699 pj_lock_release(regc->lock); 700 646 701 return PJ_SUCCESS; 647 702 } … … 685 740 686 741 /* Temporarily increase busy flag to prevent regc from being deleted 687 * in pjsip_regc_send() 742 * in pjsip_regc_send() or in the callback 688 743 */ 689 regc->busy++;744 pj_atomic_inc(regc->busy_ctr); 690 745 691 746 entry->id = 0; … … 701 756 } 702 757 703 regc->busy--;704 705 758 /* Delete the record if user destroy regc during the callback. */ 706 if ( regc->_delete_flag && regc->busy==0) {759 if (pj_atomic_dec_and_get(regc->busy_ctr)==0 && regc->_delete_flag) { 707 760 pjsip_regc_destroy(regc); 708 761 } … … 881 934 pjsip_regc *regc = (pjsip_regc*) token; 882 935 pjsip_transaction *tsx = event->body.tsx_state.tsx; 883 936 937 pj_atomic_inc(regc->busy_ctr); 938 pj_lock_acquire(regc->lock); 939 884 940 /* Decrement pending transaction counter. */ 885 941 pj_assert(regc->has_tsx); … … 915 971 916 972 if (status == PJ_SUCCESS) { 917 ++regc->busy;918 973 status = pjsip_regc_send(regc, tdata); 919 --regc->busy;920 974 } 921 975 … … 926 980 */ 927 981 if (regc->_delete_flag == 0) { 928 /* Increment busy flag temporarily to prevent regc from929 * being destroyed.982 /* Should be safe to release the lock temporarily. 983 * We do this to avoid deadlock. 930 984 */ 931 ++regc->busy; 932 985 pj_lock_release(regc->lock); 933 986 call_callback(regc, status, tsx->status_code, 934 987 &rdata->msg_info.msg->line.status.reason, 935 988 rdata, -1, 0, NULL); 936 937 /* Decrement busy flag */ 938 --regc->busy; 989 pj_lock_acquire(regc->lock); 939 990 } 940 991 } … … 994 1045 } 995 1046 996 /* Increment busy flag temporarily to prevent regc from997 * being destroyed.998 */999 ++regc->busy;1000 1001 1047 /* Update registration */ 1002 1048 if (expiration==NOEXP) expiration=-1; … … 1004 1050 1005 1051 /* Call callback. */ 1052 /* Should be safe to release the lock temporarily. 1053 * We do this to avoid deadlock. 1054 */ 1055 pj_lock_release(regc->lock); 1006 1056 call_callback(regc, PJ_SUCCESS, tsx->status_code, 1007 1057 (rdata ? &rdata->msg_info.msg->line.status.reason … … 1009 1059 rdata, expiration, 1010 1060 contact_cnt, contact); 1011 1012 /* Decrement busy flag */ 1013 --regc->busy; 1014 }1061 pj_lock_acquire(regc->lock); 1062 } 1063 1064 pj_lock_release(regc->lock); 1015 1065 1016 1066 /* Delete the record if user destroy regc during the callback. */ 1017 if ( regc->_delete_flag && regc->busy==0) {1067 if (pj_atomic_dec_and_get(regc->busy_ctr)==0 && regc->_delete_flag) { 1018 1068 pjsip_regc_destroy(regc); 1019 1069 } … … 1026 1076 pjsip_expires_hdr *expires_hdr; 1027 1077 pj_uint32_t cseq; 1078 1079 pj_atomic_inc(regc->busy_ctr); 1080 pj_lock_acquire(regc->lock); 1028 1081 1029 1082 /* Make sure we don't have pending transaction. */ … … 1032 1085 "transaction pending")); 1033 1086 pjsip_tx_data_dec_ref( tdata ); 1087 pj_lock_release(regc->lock); 1088 pj_atomic_dec(regc->busy_ctr); 1034 1089 return PJSIP_EBUSY; 1035 1090 } … … 1053 1108 pjsip_tx_data_set_transport(tdata, ®c->tp_sel); 1054 1109 1055 /* Increment pending transaction first, since transaction callback1056 * may be called even before send_request() returns!1057 */1058 1110 regc->has_tsx = PJ_TRUE; 1059 ++regc->busy;1060 1111 1061 1112 /* Set current operation based on the value of Expires header */ … … 1070 1121 PJ_LOG(4,(THIS_FILE, "Error sending request, status=%d", status)); 1071 1122 } 1072 --regc->busy; 1123 1124 pj_lock_release(regc->lock); 1073 1125 1074 1126 /* Delete the record if user destroy regc during the callback. */ 1075 if ( regc->_delete_flag && regc->busy==0) {1127 if (pj_atomic_dec_and_get(regc->busy_ctr)==0 && regc->_delete_flag) { 1076 1128 pjsip_regc_destroy(regc); 1077 1129 }
Note: See TracChangeset
for help on using the changeset viewer.