- Timestamp:
- Sep 15, 2010 7:42:14 AM (14 years ago)
- Location:
- pjproject/trunk/pjsip
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip/include/pjsip/sip_transaction.h
r3138 r3311 87 87 pjsip_endpoint *endpt; /**< Endpoint instance. */ 88 88 pj_mutex_t *mutex; /**< Mutex for this tsx. */ 89 pj_mutex_t *mutex_b; /**< Second mutex to avoid 90 deadlock. It is used to 91 protect timer. */ 89 92 90 93 /* -
pjproject/trunk/pjsip/src/pjsip/sip_transaction.c
r3262 r3311 951 951 952 952 953 /* Lock transaction for accessing the timeout timer only. */ 954 static void lock_timer(pjsip_transaction *tsx) 955 { 956 pj_mutex_lock(tsx->mutex_b); 957 } 958 959 /* Unlock timer */ 960 static void unlock_timer(pjsip_transaction *tsx) 961 { 962 pj_mutex_unlock(tsx->mutex_b); 963 } 964 953 965 /* Create and initialize basic transaction structure. 954 966 * This function is called by both UAC and UAS creation. … … 989 1001 } 990 1002 1003 status = pj_mutex_create_simple(pool, tsx->obj_name, &tsx->mutex_b); 1004 if (status != PJ_SUCCESS) { 1005 pj_mutex_destroy(tsx->mutex); 1006 pjsip_endpt_release_pool(mod_tsx_layer.endpt, pool); 1007 return status; 1008 } 1009 991 1010 *p_tsx = tsx; 992 1011 return PJ_SUCCESS; … … 1042 1061 } 1043 1062 1063 pj_mutex_destroy(tsx->mutex_b); 1044 1064 pj_mutex_destroy(tsx->mutex); 1045 1065 … … 1150 1170 } 1151 1171 1172 lock_timer(tsx); 1173 1152 1174 /* Cancel timeout timer. */ 1153 1175 if (tsx->timeout_timer.id != 0) { … … 1160 1182 &timeout); 1161 1183 1184 unlock_timer(tsx); 1162 1185 1163 1186 } else if (state == PJSIP_TSX_STATE_DESTROYED) { … … 1558 1581 unsigned millisec) 1559 1582 { 1560 struct tsx_lock_data lck;1561 1583 pj_time_val timeout; 1562 1584 … … 1566 1588 PJ_EINVALIDOP); 1567 1589 1568 lock_tsx(tsx, &lck); 1590 /* Note: must not call lock_tsx() as that would introduce deadlock. 1591 * See #1121. 1592 */ 1593 lock_timer(tsx); 1569 1594 1570 1595 /* Transaction must not have got final response */ 1571 1596 PJ_ASSERT_ON_FAIL(tsx->status_code < 200, 1572 { unlock_t sx(tsx, &lck); return PJ_EINVALIDOP; });1597 { unlock_timer(tsx); return PJ_EINVALIDOP; }); 1573 1598 1574 1599 if (tsx->timeout_timer.id != 0) { … … 1586 1611 1587 1612 1588 unlock_t sx(tsx, &lck);1613 unlock_timer(tsx); 1589 1614 1590 1615 return PJ_SUCCESS; … … 1805 1830 /* And reset timeout timer */ 1806 1831 if (tsx->timeout_timer.id) { 1832 lock_timer(tsx); 1833 1807 1834 pjsip_endpt_cancel_timer(tsx->endpt, &tsx->timeout_timer); 1808 1835 tsx->timeout_timer.id = TIMER_INACTIVE; … … 1811 1838 pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer, 1812 1839 &timeout_timer_val); 1840 1841 unlock_timer(tsx); 1813 1842 } 1814 1843 … … 2208 2237 * timeout. 2209 2238 */ 2239 lock_timer(tsx); 2210 2240 tsx->timeout_timer.id = TIMER_ACTIVE; 2211 2241 pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer, 2212 2242 &timeout_timer_val); 2243 unlock_timer(tsx); 2213 2244 2214 2245 /* Start Timer A (or timer E) for retransmission only if unreliable … … 2300 2331 2301 2332 if (tsx->timeout_timer.id != 0) { 2333 lock_timer(tsx); 2302 2334 pjsip_endpt_cancel_timer(tsx->endpt, &tsx->timeout_timer); 2303 2335 tsx->timeout_timer.id = 0; 2336 unlock_timer(tsx); 2304 2337 } 2305 2338 … … 2322 2355 2323 2356 /* Cancel timeout timer */ 2357 lock_timer(tsx); 2324 2358 pjsip_endpt_cancel_timer(tsx->endpt, &tsx->timeout_timer); 2359 unlock_timer(tsx); 2325 2360 2326 2361 } else { … … 2573 2608 } 2574 2609 2610 lock_timer(tsx); 2575 2611 tsx->timeout_timer.id = TIMER_ACTIVE; 2576 2612 pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer, 2577 2613 &timeout); 2614 unlock_timer(tsx); 2578 2615 2579 2616 /* Set state to "Completed" */ … … 2603 2640 * non-reliable transports, and zero for reliable transports. 2604 2641 */ 2642 lock_timer(tsx); 2605 2643 if (tsx->method.id == PJSIP_INVITE_METHOD) { 2606 2644 /* Start timer H for INVITE */ … … 2620 2658 &zero_time); 2621 2659 } 2660 unlock_timer(tsx); 2622 2661 2623 2662 /* For INVITE, if unreliable transport is used, retransmission … … 2747 2786 2748 2787 /* Stop timeout timer B/F. */ 2788 lock_timer(tsx); 2749 2789 pjsip_endpt_cancel_timer( tsx->endpt, &tsx->timeout_timer ); 2790 unlock_timer(tsx); 2750 2791 2751 2792 /* For INVITE, the state moves to Terminated state (because ACK is … … 2771 2812 timeout.sec = timeout.msec = 0; 2772 2813 } 2814 lock_timer(tsx); 2773 2815 tsx->timeout_timer.id = TIMER_ACTIVE; 2774 2816 pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer, 2775 2817 &timeout); 2818 unlock_timer(tsx); 2776 2819 2777 2820 /* Cancel retransmission timer */ … … 2865 2908 2866 2909 /* Stop timer B. */ 2910 lock_timer(tsx); 2867 2911 tsx->timeout_timer.id = 0; 2868 2912 pjsip_endpt_cancel_timer( tsx->endpt, &tsx->timeout_timer ); 2913 unlock_timer(tsx); 2869 2914 2870 2915 /* Generate and send ACK (for INVITE) */ … … 2913 2958 timeout.sec = timeout.msec = 0; 2914 2959 } 2960 lock_timer(tsx); 2915 2961 tsx->timeout_timer.id = TIMER_ACTIVE; 2916 2962 pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer, &timeout); 2963 unlock_timer(tsx); 2917 2964 2918 2965 } else { … … 2972 3019 2973 3020 /* Reschedule timeout timer. */ 3021 lock_timer(tsx); 2974 3022 pjsip_endpt_cancel_timer( tsx->endpt, &tsx->timeout_timer ); 2975 3023 tsx->timeout_timer.id = TIMER_ACTIVE; … … 2987 3035 pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer, 2988 3036 &timeout); 3037 unlock_timer(tsx); 2989 3038 2990 3039 /* Move state to "Confirmed" */
Note: See TracChangeset
for help on using the changeset viewer.