Changeset 5241 for pjproject/trunk/pjsip/src/pjsip/sip_transaction.c
- Timestamp:
- Feb 5, 2016 4:29:17 AM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip/src/pjsip/sip_transaction.c
r5147 r5241 139 139 #define TRANSPORT_ERR_TIMER 3 140 140 141 /* Flags for tsx_set_state() */ 142 enum 143 { 144 NO_NOTIFY = 1, 145 NO_SCHEDULE_HANDLER = 2, 146 }; 141 147 142 148 /* Prototypes. */ … … 170 176 pjsip_tsx_state_e state, 171 177 pjsip_event_id_e event_src_type, 172 void *event_src ); 173 static void tsx_set_state_no_notify( pjsip_transaction *tsx, 174 pjsip_tsx_state_e state, 175 pjsip_event_id_e event_src_type, 176 void *event_src ); 178 void *event_src, 179 int flag); 177 180 static void tsx_set_status_code(pjsip_transaction *tsx, 178 181 int code, const pj_str_t *reason); … … 1104 1107 if (tsx->state < PJSIP_TSX_STATE_TERMINATED) { 1105 1108 pjsip_tsx_state_e prev_state; 1109 pj_time_val timeout = { 0, 0 }; 1106 1110 1107 1111 pj_grp_lock_acquire(tsx->grp_lock); … … 1123 1127 * https://trac.pjsip.org/repos/ticket/1646 1124 1128 */ 1125 tsx_set_state_no_notify( tsx, PJSIP_TSX_STATE_TERMINATED, 1126 PJSIP_EVENT_TRANSPORT_ERROR, NULL); 1129 /* Also don't schedule tsx handler, otherwise we'll get race 1130 * condition of TU notifications due to delayed TERMINATED 1131 * state TU notification. It happened in multiple worker threads 1132 * environment between TERMINATED & DESTROYED! See: 1133 * https://trac.pjsip.org/repos/ticket/1902 1134 */ 1135 tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, 1136 PJSIP_EVENT_TRANSPORT_ERROR, NULL, 1137 NO_NOTIFY | NO_SCHEDULE_HANDLER); 1127 1138 pj_grp_lock_release(tsx->grp_lock); 1128 1139 … … 1139 1150 (*tsx->tsx_user->on_tsx_state)(tsx, &e); 1140 1151 } 1152 1153 /* Now let's schedule the tsx handler */ 1154 tsx_schedule_timer(tsx, &tsx->timeout_timer, &timeout, 1155 TIMEOUT_TIMER); 1141 1156 } 1142 1157 } else { … … 1168 1183 pjsip_tsx_state_e state, 1169 1184 pjsip_event_id_e event_src_type, 1170 void *event_src ) 1185 void *event_src, 1186 int flag) 1171 1187 { 1172 1188 pjsip_tsx_state_e prev_state = tsx->state; … … 1193 1209 * rx event. 1194 1210 */ 1195 if (event_src_type==PJSIP_EVENT_RX_MSG && tsx->tsx_user) { 1211 if (event_src_type==PJSIP_EVENT_RX_MSG && tsx->tsx_user && 1212 (flag & NO_NOTIFY)==0) 1213 { 1196 1214 pjsip_rx_data *rdata = (pjsip_rx_data*) event_src; 1197 1215 … … 1207 1225 1208 1226 /* Inform TU about state changed. */ 1209 if (tsx->tsx_user && tsx->tsx_user->on_tsx_state) { 1227 if (tsx->tsx_user && tsx->tsx_user->on_tsx_state && 1228 (flag & NO_NOTIFY) == 0) 1229 { 1210 1230 pjsip_event e; 1211 1231 PJSIP_EVENT_INIT_TSX_STATE(e, tsx, event_src_type, event_src, … … 1219 1239 */ 1220 1240 if (state == PJSIP_TSX_STATE_TERMINATED) { 1221 pj_time_val timeout = { 0, 0};1241 pj_time_val timeout = { 0, 0 }; 1222 1242 1223 1243 /* If we're still waiting for a message to be sent.. */ … … 1237 1257 lock_timer(tsx); 1238 1258 tsx_cancel_timer(tsx, &tsx->timeout_timer); 1239 tsx_schedule_timer( tsx, &tsx->timeout_timer, &timeout, TIMEOUT_TIMER); 1259 if ((flag & NO_SCHEDULE_HANDLER) == 0) { 1260 tsx_schedule_timer(tsx, &tsx->timeout_timer, &timeout, 1261 TIMEOUT_TIMER); 1262 } 1240 1263 unlock_timer(tsx); 1241 1264 … … 1250 1273 1251 1274 pj_log_pop_indent(); 1252 }1253 1254 /* Set transaction state without notifying tsx_user */1255 static void tsx_set_state_no_notify( pjsip_transaction *tsx,1256 pjsip_tsx_state_e state,1257 pjsip_event_id_e event_src_type,1258 void *event_src )1259 {1260 pjsip_module *tsx_user = tsx->tsx_user;1261 tsx->tsx_user = NULL;1262 tsx_set_state(tsx, state, event_src_type, event_src);1263 tsx->tsx_user = tsx_user;1264 1275 } 1265 1276 … … 1627 1638 if (tsx->state < PJSIP_TSX_STATE_TERMINATED) { 1628 1639 tsx_set_status_code(tsx, code, NULL); 1629 tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, PJSIP_EVENT_USER, NULL); 1640 tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, PJSIP_EVENT_USER, 1641 NULL, 0); 1630 1642 } 1631 1643 pj_grp_lock_release(tsx->grp_lock); … … 1838 1850 if (tsx->transport_flag & TSX_HAS_PENDING_DESTROY) { 1839 1851 tsx_set_state( tsx, PJSIP_TSX_STATE_DESTROYED, 1840 PJSIP_EVENT_UNKNOWN, NULL );1852 PJSIP_EVENT_UNKNOWN, NULL, 0 ); 1841 1853 pj_grp_lock_release(tsx->grp_lock); 1842 1854 return; … … 1913 1925 { 1914 1926 tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, 1915 PJSIP_EVENT_TRANSPORT_ERROR, send_state->tdata); 1927 PJSIP_EVENT_TRANSPORT_ERROR, 1928 send_state->tdata, 0); 1916 1929 } 1917 1930 /* Don't forget to destroy if we have pending destroy flag … … 1921 1934 { 1922 1935 tsx_set_state( tsx, PJSIP_TSX_STATE_DESTROYED, 1923 PJSIP_EVENT_TRANSPORT_ERROR, send_state->tdata); 1936 PJSIP_EVENT_TRANSPORT_ERROR, 1937 send_state->tdata, 0); 1924 1938 } 1925 1939 … … 2123 2137 tsx_set_status_code(tsx, PJSIP_SC_TSX_TRANSPORT_ERROR, &err); 2124 2138 tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, 2125 PJSIP_EVENT_TRANSPORT_ERROR, NULL );2139 PJSIP_EVENT_TRANSPORT_ERROR, NULL, 0 ); 2126 2140 2127 2141 return status; … … 2355 2369 PJSIP_REQUEST_MSG); 2356 2370 tsx_set_state( tsx, PJSIP_TSX_STATE_TRYING, PJSIP_EVENT_RX_MSG, 2357 event->body.rx_msg.rdata );2371 event->body.rx_msg.rdata, 0); 2358 2372 2359 2373 } else { … … 2410 2424 /* Move state. */ 2411 2425 tsx_set_state( tsx, PJSIP_TSX_STATE_CALLING, 2412 PJSIP_EVENT_TX_MSG, tdata );2426 PJSIP_EVENT_TX_MSG, tdata, 0); 2413 2427 } 2414 2428 … … 2451 2465 /* Inform TU. */ 2452 2466 tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, 2453 PJSIP_EVENT_TIMER, &tsx->timeout_timer );2467 PJSIP_EVENT_TIMER, &tsx->timeout_timer, 0); 2454 2468 2455 2469 /* Transaction is destroyed */ … … 2570 2584 2571 2585 tsx_set_state( tsx, PJSIP_TSX_STATE_PROCEEDING, 2572 PJSIP_EVENT_TX_MSG, event->body.tx_msg.tdata );2586 PJSIP_EVENT_TX_MSG, event->body.tx_msg.tdata, 0); 2573 2587 2574 2588 } … … 2651 2665 2652 2666 tsx_set_state( tsx, PJSIP_TSX_STATE_PROCEEDING, 2653 PJSIP_EVENT_TX_MSG, tdata );2667 PJSIP_EVENT_TX_MSG, tdata, 0 ); 2654 2668 2655 2669 /* Retransmit provisional response every 1 minute if this is … … 2685 2699 */ 2686 2700 tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, 2687 PJSIP_EVENT_TX_MSG, tdata );2701 PJSIP_EVENT_TX_MSG, tdata, 0 ); 2688 2702 2689 2703 /* Transaction is destroyed. */ … … 2743 2757 /* Set state to "Completed" */ 2744 2758 tsx_set_state( tsx, PJSIP_TSX_STATE_COMPLETED, 2745 PJSIP_EVENT_TX_MSG, tdata );2759 PJSIP_EVENT_TX_MSG, tdata, 0 ); 2746 2760 } 2747 2761 … … 2802 2816 /* Inform TU */ 2803 2817 tsx_set_state( tsx, PJSIP_TSX_STATE_COMPLETED, 2804 PJSIP_EVENT_TX_MSG, tdata );2818 PJSIP_EVENT_TX_MSG, tdata, 0 ); 2805 2819 2806 2820 } else { … … 2836 2850 2837 2851 tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, 2838 PJSIP_EVENT_TIMER, &tsx->timeout_timer );2852 PJSIP_EVENT_TIMER, &tsx->timeout_timer, 0); 2839 2853 2840 2854 return PJ_EBUG; … … 2901 2915 /* Inform the message to TU. */ 2902 2916 tsx_set_state( tsx, PJSIP_TSX_STATE_PROCEEDING, 2903 PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata );2917 PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata, 0 ); 2904 2918 2905 2919 } else if (PJSIP_IS_STATUS_IN_CLASS(tsx->status_code,200)) { … … 2915 2929 if (tsx->method.id == PJSIP_INVITE_METHOD) { 2916 2930 tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, 2917 PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata );2931 PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata, 0 ); 2918 2932 //return PJSIP_ETSXDESTROYED; 2919 2933 … … 2942 2956 /* Move state to Completed, inform TU. */ 2943 2957 tsx_set_state( tsx, PJSIP_TSX_STATE_COMPLETED, 2944 PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata );2958 PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata, 0 ); 2945 2959 } 2946 2960 … … 2950 2964 /* Inform TU. */ 2951 2965 tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, 2952 PJSIP_EVENT_TIMER, &tsx->timeout_timer );2966 PJSIP_EVENT_TIMER, &tsx->timeout_timer, 0); 2953 2967 2954 2968 … … 3041 3055 /* Inform TU. */ 3042 3056 tsx_set_state( tsx, PJSIP_TSX_STATE_COMPLETED, 3043 PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata );3057 PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata, 0); 3044 3058 3045 3059 /* Generate and send ACK for INVITE. */ … … 3152 3166 /* Move state to "Confirmed" */ 3153 3167 tsx_set_state( tsx, PJSIP_TSX_STATE_CONFIRMED, 3154 PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata );3168 PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata, 0 ); 3155 3169 } 3156 3170 … … 3176 3190 3177 3191 tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, 3178 PJSIP_EVENT_TIMER, &tsx->timeout_timer );3192 PJSIP_EVENT_TIMER, &tsx->timeout_timer, 0 ); 3179 3193 3180 3194 //return PJSIP_ETSXDESTROYED; … … 3183 3197 /* Transaction terminated, it can now be deleted. */ 3184 3198 tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, 3185 PJSIP_EVENT_TIMER, &tsx->timeout_timer );3199 PJSIP_EVENT_TIMER, &tsx->timeout_timer, 0 ); 3186 3200 //return PJSIP_ETSXDESTROYED; 3187 3201 } … … 3216 3230 /* Move to Terminated state. */ 3217 3231 tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, 3218 PJSIP_EVENT_TIMER, event->body.timer.entry );3232 PJSIP_EVENT_TIMER, event->body.timer.entry, 0 ); 3219 3233 3220 3234 /* Transaction has been destroyed. */ … … 3291 3305 /* Move to Terminated state. */ 3292 3306 tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, 3293 PJSIP_EVENT_TIMER, &tsx->timeout_timer );3307 PJSIP_EVENT_TIMER, &tsx->timeout_timer, 0 ); 3294 3308 3295 3309 /* Transaction has been destroyed. */ … … 3322 3336 /* Destroy this transaction */ 3323 3337 tsx_set_state(tsx, PJSIP_TSX_STATE_DESTROYED, 3324 event->type, event->body.user.user1 );3338 event->type, event->body.user.user1, 0 ); 3325 3339 3326 3340 return PJ_SUCCESS;
Note: See TracChangeset
for help on using the changeset viewer.