[commit] r2273 - freeswitch/branches/bennylp/src/mod/endpoints/mod_pjsip
Author: bennylp Date: Sat Aug 12 13:59:21 2006 New Revision: 2273 Modified: freeswitch/branches/bennylp/src/mod/endpoints/mod_pjsip/mod_pjsip.c Log: As good as it gets: less crashes, less deadlocks Modified: freeswitch/branches/bennylp/src/mod/endpoints/mod_pjsip/mod_pjsip.c ============================================================================== --- freeswitch/branches/bennylp/src/mod/endpoints/mod_pjsip/mod_pjsip.c (original) +++ freeswitch/branches/bennylp/src/mod/endpoints/mod_pjsip/mod_pjsip.c Sat Aug 12 13:59:21 2006 @@ -83,6 +83,7 @@ int max_calls; int calls; + int thread_cnt; int flags; switch_hash_t *call_hash; @@ -418,15 +419,17 @@ /* Hangup PJSIP call */ if (tech_pvt->sip_invite && tech_pvt->sip_invite->state < PJSIP_INV_STATE_DISCONNECTED) { - status = pjsip_inv_end_session( tech_pvt->sip_invite, 200, NULL, &txdata ); - if( status == PJ_SUCCESS ) { + pjsip_dlg_inc_lock(tech_pvt->sip_dialog); + status = pjsip_inv_end_session( tech_pvt->sip_invite, PJSIP_SC_DECLINE, NULL, &txdata ); + if( status == PJ_SUCCESS && txdata) { add_server_header(txdata); status = pjsip_inv_send_msg( tech_pvt->sip_invite, txdata ); } if (status != PJ_SUCCESS) { - perror_(tech_pvt->sip_invite->dlg->obj_name, "Unable to hangup", status); + perror_(THIS_FILE, "Unable to hangup", status); } + pjsip_dlg_dec_lock(tech_pvt->sip_dialog); } if (switch_test_flag( tech_pvt, TFLAG_USING_CODEC ) ) { @@ -494,6 +497,9 @@ tech_pvt = switch_core_session_get_private( session ); assert( tech_pvt != NULL ); + if ( tech_pvt->sip_invite == NULL ) + return SWITCH_STATUS_SUCCESS; + PJ_LOG(4,(THIS_FILE, "* Answering call %s", tech_pvt->call_id)); if( !switch_test_flag( tech_pvt, TFLAG_ANSWERED ) && @@ -502,17 +508,17 @@ pjsip_tx_data *txdata; pj_status_t status; - assert( tech_pvt->sip_invite != NULL ); PJ_LOG(4,(THIS_FILE, "* Sending 200 on INVITE to %s (%s)", tech_pvt->call_id, switch_channel_get_name( channel ) )); /* create SIP 200 with SDP */ status = pjsip_inv_answer( tech_pvt->sip_invite, 200, NULL, NULL, &txdata ); - if( status != PJ_SUCCESS ) { - perror_(tech_pvt->sip_invite->dlg->obj_name, "pjsip_inv_answer error", status); - - pjsip_inv_terminate( tech_pvt->sip_invite, 500, PJ_TRUE ); + if( status != PJ_SUCCESS || tech_pvt->sip_invite==NULL || txdata==NULL) { + if (tech_pvt->sip_invite) { + perror_(tech_pvt->sip_invite->dlg->obj_name, "pjsip_inv_answer error", status); + pjsip_inv_terminate( tech_pvt->sip_invite, 500, PJ_TRUE ); + } switch_core_session_destroy( &session ); TRACE_((THIS_FILE, "LEAVE pjsip_answer_channel")); return SWITCH_STATUS_GENERR; @@ -540,6 +546,16 @@ struct private_object *tech_pvt; switch_channel_t *channel; +#if 0 + pj_thread_desc tmp_desc; + + if (!pj_thread_is_registered()) { + /* Kidz.. don't do this at home! */ + pj_thread_t *thread; + pj_thread_register("kill%p", tmp_desc, &thread); + } +#endif + TRACE_((THIS_FILE, "ENTER pjsip_kill_channel")); assert( session != NULL ); @@ -698,6 +714,8 @@ if (switch_test_flag(tech_pvt, TFLAG_IO)) { switch_status_t status; + if (tech_pvt->rtp_session == NULL) + return SWITCH_STATUS_FALSE; assert(tech_pvt->rtp_session != NULL); tech_pvt->read_frame.datalen = 0; @@ -800,6 +818,10 @@ return SWITCH_STATUS_SUCCESS; } + if (!tech_pvt->rtp_session) { + return SWITCH_STATUS_SUCCESS; + } + if (switch_test_flag(tech_pvt, TFLAG_BYE)) { TRACE_((THIS_FILE, "switch_channel_hangup(%x) called by pjsip_write_frame()", channel)); switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING); @@ -817,7 +839,9 @@ } samples = frames * tech_pvt->read_codec.implementation->samples_per_frame; - switch_rtp_write_frame( tech_pvt->rtp_session, frame, samples ); + if (tech_pvt->rtp_session) { + switch_rtp_write_frame( tech_pvt->rtp_session, frame, samples ); + } switch_clear_flag_locked(tech_pvt, TFLAG_WRITING); return status; @@ -976,7 +1000,6 @@ sip_uri = pjsip_uri_get_uri(rxdata->msg_info.to->uri); pj_strdup_with_null( dialog->pool, &destination, &sip_uri->user); - PJ_LOG(3,(dialog->obj_name, "Destination set to %s", destination.ptr)); } else { destination = pj_str("unknown"); } @@ -1281,18 +1304,16 @@ switch( inv->state ) { case PJSIP_INV_STATE_DISCONNECTED: - /* Remove association between PJSIP call and channel, to prevent - * other channels from re-entering PJSIP for the context of this INVITE - * (which is guaranteed to cause deadlock!) - */ pjsip_dlg_inc_lock(inv->dlg); - switch_mutex_lock(tech_pvt->flag_mutex); - inv->mod_data[globals.mod_app.id] = NULL; - tech_pvt->sip_invite = NULL; - tech_pvt->sip_dialog = NULL; - switch_mutex_unlock(tech_pvt->flag_mutex); + //switch_mutex_lock(tech_pvt->flag_mutex); + //inv->mod_data[globals.mod_app.id] = NULL; + //tech_pvt->sip_invite = NULL; + //tech_pvt->sip_dialog = NULL; + //switch_mutex_unlock(tech_pvt->flag_mutex); + pjsip_on_hangup(session); + PJ_LOG(4,(THIS_FILE, "* Call %s (%s) has been disconnected", tech_pvt->call_id, switch_channel_get_name( channel ) )); @@ -1382,6 +1403,10 @@ int ms, rate; pj_sockaddr addr; + +//#define ASSERT_FAIL() assert(!"call_on_media_update failed"); +#define ASSERT_FAIL() + TRACE_((THIS_FILE, "ENTER call_on_media_update")); tech_pvt = inv->mod_data[globals.mod_app.id]; @@ -1414,6 +1439,7 @@ PJ_LOG(1,(THIS_FILE, "SDP negotiation failed for call %s, reason: %s", tech_pvt->call_id, tmp )); switch_channel_hangup( channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ); TRACE_((THIS_FILE, "LEAVE call_on_media_update")); + ASSERT_FAIL() return; } @@ -1470,6 +1496,7 @@ switch_clear_flag_locked( tech_pvt, TFLAG_IO ); switch_channel_hangup( channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ); TRACE_((THIS_FILE, "LEAVE call_on_media_update")); + ASSERT_FAIL() return; } @@ -1488,6 +1515,7 @@ perror_(THIS_FILE, "Failed to initialize read codec", -1); switch_channel_hangup( channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ); TRACE_((THIS_FILE, "LEAVE call_on_media_update")); + ASSERT_FAIL() return; } @@ -1499,6 +1527,7 @@ perror_(THIS_FILE, "ERROR: Failed to initialize write codec", -1 ); switch_channel_hangup( channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ); TRACE_((THIS_FILE, "LEAVE call_on_media_update")); + ASSERT_FAIL() return; } @@ -1797,8 +1826,10 @@ } switch_mutex_lock(tech_pvt->flag_mutex); - switch_rtp_destroy( &tech_pvt->rtp_session ); - tech_pvt->rtp_session = NULL; + if (tech_pvt->rtp_session) { + switch_rtp_destroy( &tech_pvt->rtp_session ); + tech_pvt->rtp_session = NULL; + } switch_mutex_unlock(tech_pvt->flag_mutex); TRACE_((THIS_FILE, "LEAVE stop_rtp")); @@ -1913,6 +1944,9 @@ } } } + else if (!strcmp(var, "thread-cnt")) { + profile->thread_cnt = atoi( val ); + } else { switch_log_printf( SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unknown option %s (ignored)\n", var ); } @@ -2051,21 +2085,25 @@ /* PJSIP worker thread */ static int pjsip_worker_thread(void *arg) { + PJ_LOG(3,(THIS_FILE, "PJSIP Worker Thread starting..")); + while ( globals.running > 0 ) { pj_time_val timeout = { 1, 0 }; TRACE_((THIS_FILE, "ENTER pjsip_endpt_handle_events")); pjsip_endpt_handle_events( globals.sip_endpt, &timeout ); TRACE_((THIS_FILE, "LEAVE pjsip_endpt_handle_events")); } + + + PJ_LOG(3,(THIS_FILE, "PJSIP Worker Thread quitting..")); return 0; } SWITCH_MOD_DECLARE(switch_status_t) switch_module_runtime(void) { - enum { WORKER_COUNT=0 }; pj_thread_t *worker_threads[16]; - int i; + int thread_cnt=0, i; switch_hash_index_t *p_entry; pj_status_t status; @@ -2133,6 +2171,9 @@ switch_hash_this( p_entry, NULL, NULL, &val ); profile = val; + if (profile->thread_cnt > thread_cnt) + thread_cnt = profile->thread_cnt; + if( switch_test_flag( profile, PFLAG_TRANSPORT_UDP ) ) { pjsip_transport *transport; @@ -2237,7 +2278,7 @@ globals.running = 1; /* Create PJSIP from worker threads */ - for (i=0; i<WORKER_COUNT; ++i) { + for (i=0; i<thread_cnt; ++i) { status = pj_thread_create(pjsip_pool, "sip%p", &pjsip_worker_thread, NULL, 0, 0, &worker_threads[i]); if (status != PJ_SUCCESS) { perror_(THIS_FILE, "Unable to create thread!", status); @@ -2257,7 +2298,7 @@ globals.running = 0; /* Wait for all worker threads to quit */ - for (i=0; i<WORKER_COUNT; ++i) { + for (i=0; i<thread_cnt; ++i) { status = pj_thread_join(worker_threads[i]); }
participants (1)
-
Freeswitch SVN