[asterisk-commits] russell: branch russell/iax2_performance r55433 - in /team/russell/iax2_perfo...

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Mon Feb 19 10:08:36 MST 2007


Author: russell
Date: Mon Feb 19 11:08:35 2007
New Revision: 55433

URL: http://svn.digium.com/view/asterisk?view=rev&rev=55433
Log:
Merged revisions 55409-55410,55414 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/trunk

................
r55409 | dbailey | 2007-02-19 09:24:46 -0600 (Mon, 19 Feb 2007) | 11 lines

Merged revisions 55397 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r55397 | dbailey | 2007-02-19 08:52:59 -0600 (Mon, 19 Feb 2007) | 3 lines

Changed iax2 process thread to detached to correct memory leak due to left over thread context on thread exit.  
Modified module unload process to avoid deadlocks on pthread cancels

........

................
r55410 | file | 2007-02-19 09:57:24 -0600 (Mon, 19 Feb 2007) | 2 lines

Allow both an external application and SMDI to do voicemail notification at the same time. (issue #8625 reported by lters)

................
r55414 | file | 2007-02-19 10:01:52 -0600 (Mon, 19 Feb 2007) | 2 lines

Clarify last change for SMDI in CHANGES file.

................

Modified:
    team/russell/iax2_performance/   (props changed)
    team/russell/iax2_performance/CHANGES
    team/russell/iax2_performance/apps/app_voicemail.c
    team/russell/iax2_performance/channels/chan_iax2.c
    team/russell/iax2_performance/configs/voicemail.conf.sample

Propchange: team/russell/iax2_performance/
------------------------------------------------------------------------------
    automerge = *

Propchange: team/russell/iax2_performance/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.

Propchange: team/russell/iax2_performance/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Mon Feb 19 11:08:35 2007
@@ -1,1 +1,1 @@
-/trunk:1-55393
+/trunk:1-55429

Modified: team/russell/iax2_performance/CHANGES
URL: http://svn.digium.com/view/asterisk/team/russell/iax2_performance/CHANGES?view=diff&rev=55433&r1=55432&r2=55433
==============================================================================
--- team/russell/iax2_performance/CHANGES (original)
+++ team/russell/iax2_performance/CHANGES Mon Feb 19 11:08:35 2007
@@ -60,6 +60,7 @@
   * Added 'DBDel' and 'DBDelTree' manager commands.
   * Added 'o' and 'X' options to Chanspy.
   * Added the parkedcallreparking option to features.conf
+  * SMDI is now enabled in voicemail using the smdienable option.
 
 AMI - The manager (TCP/TLS/HTTP)
 --------------------------------

Modified: team/russell/iax2_performance/apps/app_voicemail.c
URL: http://svn.digium.com/view/asterisk/team/russell/iax2_performance/apps/app_voicemail.c?view=diff&rev=55433&r1=55432&r2=55433
==============================================================================
--- team/russell/iax2_performance/apps/app_voicemail.c (original)
+++ team/russell/iax2_performance/apps/app_voicemail.c Mon Feb 19 11:08:35 2007
@@ -2817,7 +2817,7 @@
 	else
 		ast_copy_string(ext_context, extension, sizeof(ext_context));
 
-	if (!strcasecmp(externnotify, "smdi")) {
+	if (smdi_iface) {
 		if (ast_app_has_voicemail(ext_context, NULL)) 
 			ast_smdi_mwi_set(smdi_iface, extension);
 		else
@@ -2835,7 +2835,9 @@
 			if (option_debug)
 				ast_log(LOG_DEBUG, "Successfully executed SMDI MWI change for %s on %s\n", extension, smdi_iface->name);
 		}
-	} else if (!ast_strlen_zero(externnotify)) {
+	}
+
+	if (!ast_strlen_zero(externnotify)) {
 		if (inboxcount(ext_context, &newvoicemails, &oldvoicemails)) {
 			ast_log(LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", extension);
 		} else {
@@ -7294,32 +7296,31 @@
 		}
 #endif
 		/* External voicemail notify application */
-		
 		if ((notifystr = ast_variable_retrieve(cfg, "general", "externnotify"))) {
 			ast_copy_string(externnotify, notifystr, sizeof(externnotify));
 			if (option_debug)
 				ast_log(LOG_DEBUG, "found externnotify: %s\n", externnotify);
-			if (!strcasecmp(externnotify, "smdi")) {
-				if (option_debug)
-					ast_log(LOG_DEBUG, "Using SMDI for external voicemail notification\n");
-				if ((smdistr = ast_variable_retrieve(cfg, "general", "smdiport"))) {
-					smdi_iface = ast_smdi_interface_find(smdistr);
-				} else {
-					if (option_debug)
-						ast_log(LOG_DEBUG, "No SMDI interface set, trying default (/dev/ttyS0)\n");
-					smdi_iface = ast_smdi_interface_find("/dev/ttyS0");
-				}
-
-				if (!smdi_iface) {
-					ast_log(LOG_ERROR, "No valid SMDI interface specfied, disabling external voicemail notification\n");
-					externnotify[0] = '\0';
-				} else {
-					if (option_debug)
-						ast_log(LOG_DEBUG, "Using SMDI port %s\n", smdi_iface->name);
-				}
-			}
 		} else {
 			externnotify[0] = '\0';
+		}
+
+		/* SMDI voicemail notification */
+		if ((s = ast_variable_retrieve(cfg, "general", "smdienable")) && ast_true(s)) {
+			if (option_debug)
+				ast_log(LOG_DEBUG, "Enabled SMDI voicemail notification\n");
+			if ((smdistr = ast_variable_retrieve(cfg, "general", "smdiport"))) {
+				smdi_iface = ast_smdi_interface_find(smdistr);
+			} else {
+				if (option_debug)
+					ast_log(LOG_DEBUG, "No SMDI interface set, trying default (/dev/ttyS0)\n");
+				smdi_iface = ast_smdi_interface_find("/dev/ttyS0");
+			}
+			if (!smdi_iface) {
+				ast_log(LOG_ERROR, "No valid SMDI interface specfied, disabling SMDI voicemail notification\n");
+			} else {
+				if (option_debug)
+					ast_log(LOG_DEBUG, "Using SMDI port %s\n", smdi_iface->name);
+			}
 		}
 
 		/* Silence treshold */

Modified: team/russell/iax2_performance/channels/chan_iax2.c
URL: http://svn.digium.com/view/asterisk/team/russell/iax2_performance/channels/chan_iax2.c?view=diff&rev=55433&r1=55432&r2=55433
==============================================================================
--- team/russell/iax2_performance/channels/chan_iax2.c (original)
+++ team/russell/iax2_performance/channels/chan_iax2.c Mon Feb 19 11:08:35 2007
@@ -461,6 +461,7 @@
 static int iaxthreadcount = DEFAULT_THREAD_COUNT;
 static int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT;
 static int iaxdynamicthreadcount = 0;
+static int iaxactivethreadcount = 0;
 
 struct iax_rr {
 	int jitter;
@@ -895,6 +896,7 @@
 
 static struct iax2_thread *find_idle_thread(void)
 {
+	pthread_attr_t attr;
 	struct iax2_thread *thread = NULL;
 
 	/* Pop the head of the idle list off */
@@ -928,7 +930,9 @@
 	ast_cond_init(&thread->cond, NULL);
 
 	/* Create thread and send it on it's way */
-	if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) {
+	pthread_attr_init(&attr);
+	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);	
+	if (ast_pthread_create_background(&thread->threadid, &attr, iax2_process_thread, thread)) {
 		ast_cond_destroy(&thread->cond);
 		ast_mutex_destroy(&thread->lock);
 		free(thread);
@@ -7773,6 +7777,16 @@
 	return 1;
 }
 
+/* Function to clean up process thread if it is cancelled */
+static void iax2_process_thread_cleanup(void *data)
+{
+	struct iax2_thread *thread = data;
+	ast_mutex_destroy(&thread->lock);
+	ast_cond_destroy(&thread->cond);
+	free(thread);
+	ast_atomic_dec_and_test(&iaxactivethreadcount);
+}
+
 static void *iax2_process_thread(void *data)
 {
 	struct iax2_thread *thread = data;
@@ -7780,6 +7794,8 @@
 	struct timespec ts;
 	int put_into_idle = 0;
 
+	ast_atomic_fetchadd_int(&iaxactivethreadcount,1);
+	pthread_cleanup_push(iax2_process_thread_cleanup, data);
 	for(;;) {
 		/* Wait for something to signal us to be awake */
 		ast_mutex_lock(&thread->lock);
@@ -7799,7 +7815,7 @@
 				AST_LIST_REMOVE(&dynamic_list, thread, list);
 				AST_LIST_UNLOCK(&dynamic_list);
 				ast_atomic_dec_and_test(&iaxdynamicthreadcount);
-				break;
+				break;		/* exiting the main loop */
 			}
 		} else {
 			ast_cond_wait(&thread->cond, &thread->lock);
@@ -7841,6 +7857,10 @@
 		put_into_idle = 1;
 	}
 
+	/* I am exiting here on my own volition, I need to clean up my own data structures
+	* Assume that I am no longer in any of the lists (idle, active, or dynamic)
+	*/
+	pthread_cleanup_pop(1);
 	return NULL;
 }
 
@@ -8229,6 +8249,8 @@
 		ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL);
 	
 	for(;;) {
+		pthread_testcancel();
+
 		/* Go through the queue, sending messages which have not yet been
 		   sent, and scheduling retransmissions if appropriate */
 		AST_LIST_LOCK(&queue);
@@ -8268,6 +8290,7 @@
 		AST_LIST_TRAVERSE_SAFE_END
 		AST_LIST_UNLOCK(&queue);
 
+		pthread_testcancel();
 		if (count >= 20 && option_debug)
 			ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count);
 
@@ -8283,6 +8306,7 @@
 
 static int start_network_thread(void)
 {
+	pthread_attr_t attr;
 	int threadcount = 0;
 	int x;
 	for (x = 0; x < iaxthreadcount; x++) {
@@ -8292,7 +8316,9 @@
 			thread->threadnum = ++threadcount;
 			ast_mutex_init(&thread->lock);
 			ast_cond_init(&thread->cond, NULL);
-			if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) {
+			pthread_attr_init(&attr);
+			pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);	
+			if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) {
 				ast_log(LOG_WARNING, "Failed to create new thread!\n");
 				free(thread);
 				thread = NULL;
@@ -10023,16 +10049,8 @@
 #endif /* IAXTESTS */
 };
 
-static void thread_free(struct iax2_thread *thread)
-{
-	ast_mutex_destroy(&thread->lock);
-	ast_cond_destroy(&thread->cond);
-	free(thread);
-}
-
 static int unload_module(void)
 {
-	pthread_t threadid = AST_PTHREADT_NULL;
 	struct iax2_thread *thread = NULL;
 	int x;
 
@@ -10045,14 +10063,22 @@
 	ast_unregister_switch(&iax2_switch);
 	ast_channel_unregister(&iax2_tech);
 
+	/* Make sure threads do not hold shared resources when they are canceled */
+	
+	/* Grab the sched lock resource to keep it away from threads about to die */
 	/* Cancel the network thread, close the net socket */
 	if (netthreadid != AST_PTHREADT_NULL) {
+		AST_LIST_LOCK(&queue);
+		ast_mutex_lock(&sched_lock);
 		pthread_cancel(netthreadid);
+		ast_cond_signal(&sched_cond);
+		ast_mutex_unlock(&sched_lock);	/* Release the schedule lock resource */
+		AST_LIST_UNLOCK(&queue);
 		pthread_join(netthreadid, NULL);
 	}
 	if (schedthreadid != AST_PTHREADT_NULL) {
+		ast_mutex_lock(&sched_lock);
 		pthread_cancel(schedthreadid);
-		ast_mutex_lock(&sched_lock);
 		ast_cond_signal(&sched_cond);
 		ast_mutex_unlock(&sched_lock);
 		pthread_join(schedthreadid, NULL);
@@ -10062,39 +10088,31 @@
 	AST_LIST_LOCK(&idle_list);
 	AST_LIST_TRAVERSE_SAFE_BEGIN(&idle_list, thread, list) {
 		AST_LIST_REMOVE_CURRENT(&idle_list, list);
-		threadid = thread->threadid;
-		pthread_cancel(threadid);
-		signal_condition(&thread->lock, &thread->cond);
-		pthread_join(threadid, NULL);
-		thread_free(thread);
+		pthread_cancel(thread->threadid);
 	}
 	AST_LIST_TRAVERSE_SAFE_END
-	AST_LIST_UNLOCK(&idle_list);
+			AST_LIST_UNLOCK(&idle_list);
 
 	AST_LIST_LOCK(&active_list);
 	AST_LIST_TRAVERSE_SAFE_BEGIN(&active_list, thread, list) {
 		AST_LIST_REMOVE_CURRENT(&active_list, list);
-		threadid = thread->threadid;
-		pthread_cancel(threadid);
-		signal_condition(&thread->lock, &thread->cond);
-		pthread_join(threadid, NULL);
-		thread_free(thread);
+		pthread_cancel(thread->threadid);
 	}
 	AST_LIST_TRAVERSE_SAFE_END
-	AST_LIST_UNLOCK(&active_list);
+			AST_LIST_UNLOCK(&active_list);
 
 	AST_LIST_LOCK(&dynamic_list);
 	AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list, thread, list) {
 		AST_LIST_REMOVE_CURRENT(&dynamic_list, list);
-		threadid = thread->threadid;
-		pthread_cancel(threadid);
-		signal_condition(&thread->lock, &thread->cond);
-		pthread_join(threadid, NULL);
-		thread_free(thread);
+		pthread_cancel(thread->threadid);
 	}
 	AST_LIST_TRAVERSE_SAFE_END
-	AST_LIST_UNLOCK(&dynamic_list);
-
+			AST_LIST_UNLOCK(&dynamic_list);
+	
+	/* Wait for threads to exit */
+	while(0 < iaxactivethreadcount)
+		usleep(10000);
+	
 	ast_netsock_release(netsock);
 	for (x = 0; x < IAX_MAX_CALLS; x++) {
 		if (iaxs[x])

Modified: team/russell/iax2_performance/configs/voicemail.conf.sample
URL: http://svn.digium.com/view/asterisk/team/russell/iax2_performance/configs/voicemail.conf.sample?view=diff&rev=55433&r1=55432&r2=55433
==============================================================================
--- team/russell/iax2_performance/configs/voicemail.conf.sample (original)
+++ team/russell/iax2_performance/configs/voicemail.conf.sample Mon Feb 19 11:08:35 2007
@@ -58,11 +58,13 @@
 ;
 ; If you need to have an external program, i.e. /usr/bin/myapp
 ; called when a voicemail is left, delivered, or your voicemailbox 
-; is checked, uncomment this.  It can also be set to 'smdi' to use
-; smdi for external notification.  If it is 'smdi', smdiport should
-; be set to a valid port as specified in smdi.conf.
-
+; is checked, uncomment this.
 ;externnotify=/usr/bin/myapp
+
+; If you would also like to enable SMDI notification then set smdienable to yes.
+; You will also need to make sure smdiport is set to a valid port as specified in
+; smdi.conf.
+;smdienable=yes
 ;smdiport=/dev/ttyS0
 
 ; If you need to have an external program, i.e. /usr/bin/myapp



More information about the asterisk-commits mailing list