[Freeswitch-svn] [commit] r2273 - freeswitch/branches/bennylp/src/mod/endpoints/mod_pjsip
Freeswitch SVN
bennylp at freeswitch.org
Sat Aug 12 13:59:22 EDT 2006
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]);
}
More information about the Freeswitch-svn
mailing list