Revision
17254
Author
math.parent
Date
2010-04-08 15:38:24 -0500 (Thu, 08 Apr 2010)

Log Message

Skinny: solve deadlocks and more

- Solve deadlock:
  + associate all skinny_profile_find_session with the corresponding
    switch_core_session_rwunlock
  + lock the newly created session in skinny_create_ingoing_session
  + enhance rwlocks debugging
- Shared lines:
  + Inform shared lines on answering
  + Answering line has info after other shared lines

Modified Paths

Diff

Modified: freeswitch/trunk/src/mod/endpoints/mod_skinny/mod_skinny.c (17253 => 17254)


--- freeswitch/trunk/src/mod/endpoints/mod_skinny/mod_skinny.c	2010-04-08 19:49:49 UTC (rev 17253)
+++ freeswitch/trunk/src/mod/endpoints/mod_skinny/mod_skinny.c	2010-04-08 20:38:24 UTC (rev 17254)
@@ -235,14 +235,22 @@
 	return helper.channel_uuid;
 }
 
+#ifdef SWITCH_DEBUG_RWLOCKS
+switch_core_session_t * skinny_profile_perform_find_session(skinny_profile_t *profile, listener_t *listener, uint32_t *line_instance_p, uint32_t call_id, const char *file, const char *func, int line)
+#else
 switch_core_session_t * skinny_profile_find_session(skinny_profile_t *profile, listener_t *listener, uint32_t *line_instance_p, uint32_t call_id)
+#endif
 {
 	char *uuid;
 	switch_core_session_t *result = NULL;
 	uuid = skinny_profile_find_session_uuid(profile, listener, line_instance_p, call_id);
 
 	if(!zstr(uuid)) {
+#ifdef SWITCH_DEBUG_RWLOCKS
+		result = switch_core_session_perform_locate(uuid, file, func, line);
+#else
 		result = switch_core_session_locate(uuid);
+#endif
 		if(!result) {
 			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, 
 				"Unable to find session %s on %s:%d, line %d\n",
@@ -650,7 +658,6 @@
 		/* TODO: DefineTimeDate */
 		send_set_speaker_mode(listener, SKINNY_SPEAKER_OFF);
 		send_set_ringer(listener, SKINNY_RING_OFF, SKINNY_RING_FOREVER, 0, call_id);
-
 	}
 	return 0;
 }

Modified: freeswitch/trunk/src/mod/endpoints/mod_skinny/mod_skinny.h (17253 => 17254)


--- freeswitch/trunk/src/mod/endpoints/mod_skinny/mod_skinny.h	2010-04-08 19:49:49 UTC (rev 17253)
+++ freeswitch/trunk/src/mod/endpoints/mod_skinny/mod_skinny.h	2010-04-08 20:38:24 UTC (rev 17254)
@@ -189,7 +189,12 @@
 switch_status_t skinny_profile_find_listener_by_device_name(skinny_profile_t *profile, const char *device_name, listener_t **listener);
 switch_status_t skinny_profile_find_listener_by_device_name_and_instance(skinny_profile_t *profile, const char *device_name, uint32_t device_instance, listener_t **listener);
 char * skinny_profile_find_session_uuid(skinny_profile_t *profile, listener_t *listener, uint32_t *line_instance_p, uint32_t call_id);
+#ifdef SWITCH_DEBUG_RWLOCKS
+switch_core_session_t * skinny_profile_perform_find_session(skinny_profile_t *profile, listener_t *listener, uint32_t *line_instance_p, uint32_t call_id, const char *file, const char *func, int line);
+#define skinny_profile_find_session(profile, listener, line_instance_p, call_id) skinny_profile_perform_find_session(profile, listener, line_instance_p, call_id, __FILE__, __SWITCH_FUNC__, __LINE__)
+#else
 switch_core_session_t * skinny_profile_find_session(skinny_profile_t *profile, listener_t *listener, uint32_t *line_instance_p, uint32_t call_id);
+#endif
 switch_status_t dump_device(skinny_profile_t *profile, const char *device_name, switch_stream_handle_t *stream);
 
 /*****************************************************************************/

Modified: freeswitch/trunk/src/mod/endpoints/mod_skinny/skinny_protocol.c (17253 => 17254)


--- freeswitch/trunk/src/mod/endpoints/mod_skinny/skinny_protocol.c	2010-04-08 19:49:49 UTC (rev 17253)
+++ freeswitch/trunk/src/mod/endpoints/mod_skinny/skinny_protocol.c	2010-04-08 20:38:24 UTC (rev 17254)
@@ -446,13 +446,13 @@
 
 	line_instance = *line_instance_p;
 	if((nsession = skinny_profile_find_session(listener->profile, listener, line_instance_p, 0))) {
-	    switch_core_session_rwunlock(nsession);
 	    if(skinny_line_get_state(listener, *line_instance_p, 0) == SKINNY_OFF_HOOK) {
 	        /* Reuse existing session */
 	        *session = nsession;
 	        return SWITCH_STATUS_SUCCESS;
 	    }
 	    skinny_session_hold_line(nsession, listener, *line_instance_p);
+	    switch_core_session_rwunlock(nsession);
 	}
 	*line_instance_p = line_instance;
 	if(*line_instance_p == 0) {
@@ -494,7 +494,11 @@
 		    "Error Creating Session thread\n");
 		goto error;
 	}
-
+	if (switch_core_session_read_lock(nsession) != SWITCH_STATUS_SUCCESS) {
+		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(nsession), SWITCH_LOG_CRIT, 
+		    "Error Locking Session\n");
+		goto error;
+	}
 	if (!(tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(nsession),
 													          NULL, listener->profile->dialplan, 
 													          button->shortname, button->name, 
@@ -579,8 +583,6 @@
 	    skinny_session_start_media(session, listener, line_instance);
 	}
 
-	switch_core_session_rwunlock(session);
-
 	return SWITCH_STATUS_SUCCESS;
 }
 
@@ -603,8 +605,6 @@
 		line_instance, tech_pvt->call_id);
 	skinny_send_call_info(session, listener, line_instance);
 
-	switch_core_session_rwunlock(session);
-
 	return SWITCH_STATUS_SUCCESS;
 }
 
@@ -643,16 +643,14 @@
 	    if(!strcmp(device_name, helper->listener->device_name) 
 	            && (device_instance == helper->listener->device_instance)
 	            && (line_instance == helper->line_instance)) {/* the answering line */
-	       	
-	       	
+	       	/* nothing */
+	    } else {
+	    	send_define_current_time_date(listener);
+	        send_set_lamp(listener, SKINNY_BUTTON_LINE, line_instance, SKINNY_LAMP_ON);
+	        skinny_line_set_state(listener, line_instance, helper->tech_pvt->call_id, SKINNY_IN_USE_REMOTELY);
+	        send_select_soft_keys(listener, line_instance, helper->tech_pvt->call_id, 10, 0x0002);
+	        send_display_prompt_status(listener, 0, "\200\037", line_instance, helper->tech_pvt->call_id);
 	        send_set_ringer(listener, SKINNY_RING_OFF, SKINNY_RING_FOREVER, 0, helper->tech_pvt->call_id);
-	        send_set_speaker_mode(listener, SKINNY_SPEAKER_ON);
-	        send_set_lamp(listener, SKINNY_BUTTON_LINE, line_instance, SKINNY_LAMP_ON);
-	        skinny_line_set_state(listener, line_instance, helper->tech_pvt->call_id, SKINNY_OFF_HOOK);
-	        /* send_select_soft_keys(listener, line_instance, helper->tech_pvt->call_id, SKINNY_KEY_SET_OFF_HOOK, 0xffff); */
-	        /* display_prompt_status(listener, 0, "\200\000",
-		        line_instance, tech_pvt->call_id); */
-	        send_activate_call_plane(listener, line_instance);
 	    }
 	}
 	return 0;
@@ -671,6 +669,12 @@
 	channel = switch_core_session_get_channel(session);
 	tech_pvt = switch_core_session_get_private(session);
 
+    send_set_ringer(listener, SKINNY_RING_OFF, SKINNY_RING_FOREVER, 0, tech_pvt->call_id);
+    send_set_speaker_mode(listener, SKINNY_SPEAKER_ON);
+    send_set_lamp(listener, SKINNY_BUTTON_LINE, line_instance, SKINNY_LAMP_ON);
+    skinny_line_set_state(listener, line_instance, tech_pvt->call_id, SKINNY_OFF_HOOK);
+    send_activate_call_plane(listener, line_instance);
+
 	helper.tech_pvt = tech_pvt;
 	helper.listener = listener;
 	helper.line_instance = line_instance;
@@ -679,8 +683,6 @@
 
 	skinny_session_start_media(session, listener, line_instance);
 
-	switch_core_session_rwunlock(session);
-
 	return SWITCH_STATUS_SUCCESS;
 }
 
@@ -717,8 +719,6 @@
 	    tech_pvt->call_id);
 	skinny_send_call_info(session, listener, line_instance);
 
-	switch_core_session_rwunlock(session);
-
 	return SWITCH_STATUS_SUCCESS;
 }
 
@@ -739,8 +739,6 @@
 
 	switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
 
-	switch_core_session_rwunlock(session);
-
 	return SWITCH_STATUS_SUCCESS;
 }
 
@@ -2002,6 +2000,11 @@
 
 	    skinny_session_process_dest(session, listener, line_instance, NULL, '\0', 0);
 	}
+
+	if(session) {
+		switch_core_session_rwunlock(session);
+	}
+
 	return SWITCH_STATUS_SUCCESS;
 }
 
@@ -2037,6 +2040,11 @@
 		default:
 			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unknown Stimulus Type Received [%d]\n", request->data.stimulus.instance_type);
 	}
+
+	if(session) {
+		switch_core_session_rwunlock(session);
+	}
+
 	return SWITCH_STATUS_SUCCESS;
 }
 
@@ -2118,9 +2126,13 @@
 	    }
 		switch_channel_mark_answered(channel);
 
+	}
+end:
+
+	if(session) {
 		switch_core_session_rwunlock(session);
 	}
-end:
+
 	return status;
 }
 
@@ -2174,6 +2186,10 @@
 		switch_core_session_rwunlock(session);
 	}
 
+	if(session) {
+		switch_core_session_rwunlock(session);
+	}
+
 	return SWITCH_STATUS_SUCCESS;
 }
 
@@ -2195,9 +2211,12 @@
 		channel = switch_core_session_get_channel(session);
 
 		switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
+	}
 
+	if(session) {
 		switch_core_session_rwunlock(session);
 	}
+
 	return status;
 }