[asterisk-commits] russell: trunk r94802 - in /trunk: ./ main/autoservice.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Dec 26 13:09:18 CST 2007


Author: russell
Date: Wed Dec 26 13:09:17 2007
New Revision: 94802

URL: http://svn.digium.com/view/asterisk?view=rev&rev=94802
Log:
Merged revisions 94801 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r94801 | russell | 2007-12-26 13:04:31 -0600 (Wed, 26 Dec 2007) | 4 lines

Just in case the AST_FLAG_END_DTMF_ONLY flag was already set before starting
autoservice, remember it and ensure that the channel has the same setting when
autoservice gets stopped.  (pointed out by d1mas, patched up by me)

........

Modified:
    trunk/   (props changed)
    trunk/main/autoservice.c

Propchange: trunk/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.

Modified: trunk/main/autoservice.c
URL: http://svn.digium.com/view/asterisk/trunk/main/autoservice.c?view=diff&rev=94802&r1=94801&r2=94802
==============================================================================
--- trunk/main/autoservice.c (original)
+++ trunk/main/autoservice.c Wed Dec 26 13:09:17 2007
@@ -51,6 +51,7 @@
 	 *  channel.  It will ensure that it doesn't actually get stopped until 
 	 *  it gets stopped for the last time. */
 	unsigned int use_count;
+	unsigned int orig_end_dtmf_flag:1;
 	AST_LIST_HEAD_NOLOCK(, ast_frame) dtmf_frames;
 	AST_LIST_ENTRY(asent) list;
 };
@@ -151,41 +152,49 @@
 	struct asent *as;
 
 	AST_RWLIST_WRLOCK(&aslist);
-
-	/* Check if the channel already has autoservice */
 	AST_RWLIST_TRAVERSE(&aslist, as, list) {
 		if (as->chan == chan) {
 			as->use_count++;
 			break;
 		}
 	}
-
-	/* If not, start autoservice on channel */
+	AST_RWLIST_UNLOCK(&aslist);
+
 	if (as) {
-		/* Entry extist, autoservice is already handling this channel */
-	} else if ((as = ast_calloc(1, sizeof(*as))) == NULL) {
-		/* Memory allocation failed */
-		res = -1;
-	} else {
-		/* New entry created */
-		as->chan = chan;
+		/* Entry exists, autoservice is already handling this channel */
+		return 0;
+	}
+
+	if (!(as = ast_calloc(1, sizeof(*as))))
+		return -1;
+	
+	/* New entry created */
+	as->chan = chan;
+	as->use_count = 1;
+
+	ast_channel_lock(chan);
+	as->orig_end_dtmf_flag = ast_test_flag(chan, AST_FLAG_END_DTMF_ONLY) ? 1 : 0;
+	if (!as->orig_end_dtmf_flag)
 		ast_set_flag(chan, AST_FLAG_END_DTMF_ONLY);
-		as->use_count = 1;
-		AST_RWLIST_INSERT_HEAD(&aslist, as, list);
-		if (asthread == AST_PTHREADT_NULL) { /* need start the thread */
-			if (ast_pthread_create_background(&asthread, NULL, autoservice_run, NULL)) {
-				ast_log(LOG_WARNING, "Unable to create autoservice thread :(\n");
-				/* There will only be a single member in the list at this point,
-				   the one we just added. */
-				AST_RWLIST_REMOVE(&aslist, as, list);
-				ast_free(as);
-				res = -1;
-			} else
-				pthread_kill(asthread, SIGURG);
-		}
-	}
-
-	AST_RWLIST_UNLOCK(&aslist);
+	ast_channel_unlock(chan);
+
+	AST_RWLIST_WRLOCK(&aslist);
+	AST_RWLIST_INSERT_HEAD(&aslist, as, list);
+	AST_RWLIST_UNLOCK(&aslist);
+
+	if (asthread == AST_PTHREADT_NULL) { /* need start the thread */
+		if (ast_pthread_create_background(&asthread, NULL, autoservice_run, NULL)) {
+			ast_log(LOG_WARNING, "Unable to create autoservice thread :(\n");
+			/* There will only be a single member in the list at this point,
+			   the one we just added. */
+			AST_RWLIST_WRLOCK(&aslist);
+			AST_RWLIST_REMOVE(&aslist, as, list);
+			AST_RWLIST_UNLOCK(&aslist);
+			free(as);
+			res = -1;
+		} else
+			pthread_kill(asthread, SIGURG);
+	}
 
 	return res;
 }
@@ -197,6 +206,7 @@
 	AST_LIST_HEAD_NOLOCK(, ast_frame) dtmf_frames;
 	struct ast_frame *f;
 	int removed = 0;
+	int orig_end_dtmf_flag = 0;
 
 	AST_LIST_HEAD_INIT_NOLOCK(&dtmf_frames);
 
@@ -208,11 +218,11 @@
 			if (as->use_count)
 				break;
 			AST_LIST_APPEND_LIST(&dtmf_frames, &as->dtmf_frames, frame_list);
+			orig_end_dtmf_flag = as->orig_end_dtmf_flag;
 			ast_free(as);
 			removed = 1;
 			if (!ast_check_hangup(chan))
 				res = 0;
-			ast_clear_flag(chan, AST_FLAG_END_DTMF_ONLY);
 			break;
 		}
 	}
@@ -226,6 +236,9 @@
 	if (!removed)
 		return 0;
 
+	if (!orig_end_dtmf_flag)
+		ast_clear_flag(chan, AST_FLAG_END_DTMF_ONLY);
+
 	/* Wait for it to un-block */
 	while (ast_test_flag(chan, AST_FLAG_BLOCKING))
 		usleep(1000);




More information about the asterisk-commits mailing list