[asterisk-commits] murf: branch murf/masqpark r165207 - in /team/murf/masqpark: ./ apps/ channel...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Dec 17 13:06:07 CST 2008


Author: murf
Date: Wed Dec 17 13:06:06 2008
New Revision: 165207

URL: http://svn.digium.com/view/asterisk?view=rev&rev=165207
Log:
Merged revisions 163080,163084,163088,163092,163253,163316,163383,163448,163511,163761,163785,164082,164201,164204,164343,164350,164416,164422,164605,164634,164672,164736,164806,164876,164881,164977 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
  r163080 | mmichelson | 2008-12-11 09:24:43 -0700 (Thu, 11 Dec 2008) | 14 lines
  
  Fix a potential crash due to unsafe datastore handling.
  
  This patch also contains a conversion from using long to time_t
  for representing times for a queue, as well as some whitespace
  fixes.
  
  (closes issue #14060)
  Reported by: nivek
  Patches:
        datastore_fixup.patch.corrected uploaded by nivek (license 636)
  	  with slight modification from me
  Tested by: nivek
........
  r163084 | mmichelson | 2008-12-11 09:46:22 -0700 (Thu, 11 Dec 2008) | 4 lines
  
  Revert this cast to long. Using time_t here causes build failures on a 
  FreeBSD 32-bit build.
........
  r163088 | tilghman | 2008-12-11 09:51:27 -0700 (Thu, 11 Dec 2008) | 6 lines
  
  Don't wait forever, if there's a specified recording timeout.
  (closes issue #13885)
   Reported by: bamby
   Patches: 
         res_agi.c.patch uploaded by bamby (license 430)
........
  r163092 | russell | 2008-12-11 09:54:51 -0700 (Thu, 11 Dec 2008) | 11 lines
  
  Fix an issue that made it so you could only have a single caller executing
  a custom feature at a time.  This was especially problematic when custom
  features ran for any appreciable amount of time.
  
  The fix turned out to be quite simple.  The dynamic features are now stored
  in a read/write list instead of a list using a mutex.
  
  (closes issue #13478)
  Reported by: neutrino88
  Fix suggested by file
........
  r163253 | russell | 2008-12-11 14:46:29 -0700 (Thu, 11 Dec 2008) | 8 lines
  
  Fix some observed slowdowns in dialplan processing.
  
  The change is to remove autoservice usage from dialplan functions that do not
  need it because they do not perform operations that potentially block.
  
  (closes issue #13940)
  Reported by: tbelder
........
  r163316 | mnicholson | 2008-12-11 15:44:31 -0700 (Thu, 11 Dec 2008) | 9 lines
  
  Clean up the dundi cache every 5 minutes.
  
  (closes issue #13819)
  Reported by: adomjan
  Patches:
        pbx_dundi.c-clearcache.patch uploaded by adomjan (license 487)
        dundi_clearecache3.diff uploaded by mnicholson (license 96)
  Tested by: adomjan
........
  r163383 | tilghman | 2008-12-11 16:35:55 -0700 (Thu, 11 Dec 2008) | 9 lines
  
  When a Ctrl-C or Ctrl-D ends a remote console, on certain shells, the terminal
  is messed up.  By intercepting those events with a signal handler in the remote
  console, we can avoid those issues.
  (closes issue #13464)
   Reported by: tzafrir
   Patches: 
         20081110__bug13464.diff.txt uploaded by Corydon76 (license 14)
   Tested by: blitzrage
........
  r163448 | russell | 2008-12-12 06:44:08 -0700 (Fri, 12 Dec 2008) | 26 lines
  
  Resolve issues that could cause DTMF to be processed out of order.
  
  These changes come from team/russell/issue_12658
  
  1) Change autoservice to put digits on the head of the channel's frame readq 
     instead of the tail.  If there were frames on the readq that autoservice 
     had not yet read, the previous code would have resulted in out of order 
     processing.  This required a new API call to queue a frame to the head 
     of the queue instead of the tail.
  
  2) Change up the processing of DTMF in ast_read().  Some of the problems 
     were the result of having two sources of pending DTMF frames.  There 
     was the dtmfq and the more generic readq.  Both were used for pending 
     DTMF in various scenarios.  Simplifying things to only use the frame 
     readq avoids some of the problems.
  
  3) Fix a bug where a DTMF END frame could get passed through when it 
     shouldn't have.  If code set END_DTMF_ONLY in the middle of digit emulation,
     and a digit arrived before emulation was complete, digits would get 
     processed out of order.
  
  (closes issue #12658)
  Reported by: dimas
  Tested by: russell, file
  Review: http://reviewboard.digium.com/r/85/
........
  r163511 | russell | 2008-12-12 07:40:31 -0700 (Fri, 12 Dec 2008) | 5 lines
  
  Specify uint32_t for variables storing a CRC32 so that it is actually 32 bits
  on 64-bit machines, as well.
  
  (inspired by issue #13879)
........
  r163761 | tilghman | 2008-12-12 15:03:10 -0700 (Fri, 12 Dec 2008) | 7 lines
  
  Simple fix for Ctrl-C not immediately exiting Asterisk, but also add a
  pointer inside editline to look back to asterisk.c, so others don't spend
  as much time as I did looking (in the wrong place) for the appropriate
  function.
  Reported by: ZX81, via the #asterisk-users channel
  Fixed by: me (license 14)
........
  r163785 | russell | 2008-12-12 15:20:26 -0700 (Fri, 12 Dec 2008) | 2 lines
  
  Set the reviewboard:url property on 1.4, as well
........
  r164082 | tilghman | 2008-12-13 16:22:02 -0700 (Sat, 13 Dec 2008) | 9 lines
  
  Change the default calldurationlimit from the special value 0 to -1, so we
  can better detect an exceptional case.  This follows on to the changes made
  in revision 156386.  Related to issue #13851.
  (closes issue #13974)
   Reported by: paradise
   Patches: 
         20081208__bug13974.diff.txt uploaded by Corydon76 (license 14)
   Tested by: file, blitzrage, ZX81
........
  r164201 | russell | 2008-12-15 07:31:37 -0700 (Mon, 15 Dec 2008) | 31 lines
  
  Handle a case where a call can be bridged to a channel that is still ringing.
  
  The issue that was reported was about a case where a RINGING channel got 
  redirected to an extension to pick up a call from parking.  Once the parked 
  call got taken out of parking, it heard silence until the other side answered.  
  Ideally, the caller that was parked would get a ringing indication.  This patch
  fixes this case so that the caller receives ringback once it comes out of 
  parking until the other side answers.
  
  The fixes are:
  
   - Make sure we remember that a channel was an outgoing channel when doing 
     a masquerade.  This prevents an erroneous ast_answer() call on the channel,
     which causes a bogus 200 OK to be sent in the case of SIP.
  
   - Add some additional comments to explain related parts of code.
  
   - Update the handling of the ast_channel visible_indication field.  Storing 
     values that are not stateful is pointless.  Control frames that are events 
     or commands should be ignored.
  
   - When a bridge first starts, check to see if the peer channel needs to be 
     given ringing indication because the calling side is still ringing.
  
   - Rework ast_indicate_data() a bit for the sake of readability.
  
  (closes issue #13747)
  Reported by: davidw
  Tested by: russell
  Review: http://reviewboard.digium.com/r/90/
........
  r164204 | file | 2008-12-15 08:05:08 -0700 (Mon, 15 Dec 2008) | 4 lines
  
  Can we try not to assign an unsigned int to -1?
  (closes issue #14074)
  Reported by: wetwired
........
  r164343 | file | 2008-12-15 10:43:59 -0700 (Mon, 15 Dec 2008) | 4 lines
  
  Use autoconf logic to determine whether the system has timersub or not. Do not blindly assume Solaris does not.
  (closes issue #13838)
  Reported by: ano
........
  r164350 | file | 2008-12-15 11:11:21 -0700 (Mon, 15 Dec 2008) | 6 lines
  
  Do not try to unlock a non-existant channel if the transfer fails.
  (closes issue #13800)
  Reported by: dwagner
  Patches:
        asterisk-1.4.22-chan-sip-nullp.patch uploaded by tweety (license 608)
........
  r164416 | mmichelson | 2008-12-15 12:45:07 -0700 (Mon, 15 Dec 2008) | 4 lines
  
  Add notes to autoservice and pbx doxygen regarding a potential
  deadlock scenario so that it is avoided in the future
........
  r164422 | mmichelson | 2008-12-15 12:53:08 -0700 (Mon, 15 Dec 2008) | 3 lines
  
  Add the deadlock note to ast_spawn_extension as well
........
  r164605 | russell | 2008-12-16 07:28:10 -0700 (Tue, 16 Dec 2008) | 5 lines
  
  Don't try to change working directory if a directory was not configured.
  
  (closes issue #14089)
  Reported by: caspy
........
  r164634 | murf | 2008-12-16 08:15:58 -0700 (Tue, 16 Dec 2008) | 5 lines
  
  I added a sentence to clarify why - and ' ' are ignored in patterns
  as per bug 14076. Leif says he'll put some stuff about it in the
  extensions.conf sample, etc.
........
  r164672 | russell | 2008-12-16 08:56:37 -0700 (Tue, 16 Dec 2008) | 11 lines
  
  Fix a memory leak related to the use of the "setvar" configuration option.
  
  The problem was that these variables were being appended to the list of vars
  on the sip_pvt every time a re-registration or re-subscription came in.
  Since it's just a waste of memory to put them there unless the request was an
  INVITE, then the fix is to check the request type before copying the vars.
  
  (closes issue #14037)
  Reported by: marvinek
  Tested by: russell
........
  r164736 | russell | 2008-12-16 10:06:29 -0700 (Tue, 16 Dec 2008) | 14 lines
  
  Fix memory leak and invalid reporting issues with DEBUG_THREADLOCALS.
  
  One issue was that the ast_mutex_* API was being used within the context of the
  thread local data destructors.  We would go off and allocate more thread local data
  while the pthread lib was in the middle of destroying it all.  This led to a memory 
  leak.
  
  Another issue was an invalid argument being provided to the the object_add
  API call.
  
  (closes issue #13678)
  Reported by: ys
  Tested by: Russell
........
  r164806 | russell | 2008-12-16 13:35:25 -0700 (Tue, 16 Dec 2008) | 9 lines
  
  Add "restart gracefully" to the AMI blacklist of CLI commands.  
  
  "module unload" was already identified as a command that can not be used 
  from the AMI.  "restart gracefully" effectively unloads all modules, and will 
  run in to the same problems.
  
  (closes issue #13894)
  Reported by: kernelsensei
........
  r164876 | russell | 2008-12-16 14:10:44 -0700 (Tue, 16 Dec 2008) | 6 lines
  
  Do not dereference the channel if AST_PBX_KEEPALIVE has been returned.
  
  This is a bug I noticed while looking at the code for app_macro.  This return code
  means that another thread has assumed ownership of the channel and it can no longer
  be touched.  (I hate this return code with a passion, by the way.)
........
  r164881 | russell | 2008-12-16 14:38:29 -0700 (Tue, 16 Dec 2008) | 9 lines
  
  Fix an issue where DEBUG_THREADS may erroneously report that a thread 
  is exiting while holding a lock.
  
  If the last lock attempt was a trylock, and it failed, it will still be in the
  list of locks so that it can be reported.
  
  (closes issue #13219)
  Reported by: pj
........
  r164977 | mmichelson | 2008-12-16 16:04:27 -0700 (Tue, 16 Dec 2008) | 7 lines
  
  After looking through SIP registration code most of the day, this
  is one of the few things I could find that was just plain wrong.
  Even though it probably isn't possible for it to happen, it seems weird
  to have code that checks if a pointer is NULL and then immediately dereferences
  that pointer if it was NULL.
........

Modified:
    team/murf/masqpark/   (props changed)
    team/murf/masqpark/apps/app_dial.c
    team/murf/masqpark/apps/app_macro.c
    team/murf/masqpark/apps/app_queue.c
    team/murf/masqpark/channels/chan_sip.c
    team/murf/masqpark/configure
    team/murf/masqpark/configure.ac
    team/murf/masqpark/funcs/func_cut.c
    team/murf/masqpark/funcs/func_strings.c
    team/murf/masqpark/include/asterisk/autoconfig.h.in
    team/murf/masqpark/include/asterisk/channel.h
    team/murf/masqpark/include/asterisk/pbx.h
    team/murf/masqpark/include/asterisk/threadstorage.h
    team/murf/masqpark/main/asterisk.c
    team/murf/masqpark/main/autoservice.c
    team/murf/masqpark/main/channel.c
    team/murf/masqpark/main/editline/read.c
    team/murf/masqpark/main/manager.c
    team/murf/masqpark/main/pbx.c
    team/murf/masqpark/main/threadstorage.c
    team/murf/masqpark/main/utils.c
    team/murf/masqpark/pbx/pbx_dundi.c
    team/murf/masqpark/res/res_agi.c
    team/murf/masqpark/res/res_features.c
    team/murf/masqpark/res/res_musiconhold.c

Propchange: team/murf/masqpark/
------------------------------------------------------------------------------
    automerge = yep

Propchange: team/murf/masqpark/
------------------------------------------------------------------------------
--- reviewboard:url (added)
+++ reviewboard:url Wed Dec 17 13:06:06 2008
@@ -1,0 +1,1 @@
+http://reviewboard.digium.com

Propchange: team/murf/masqpark/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Wed Dec 17 13:06:06 2008
@@ -1,1 +1,1 @@
-/branches/1.4:1-162956
+/branches/1.4:1-165179

Modified: team/murf/masqpark/apps/app_dial.c
URL: http://svn.digium.com/view/asterisk/team/murf/masqpark/apps/app_dial.c?view=diff&rev=165207&r1=165206&r2=165207
==============================================================================
--- team/murf/masqpark/apps/app_dial.c (original)
+++ team/murf/masqpark/apps/app_dial.c Wed Dec 17 13:06:06 2008
@@ -876,7 +876,7 @@
 	char numsubst[256];
 	char cidname[AST_MAX_EXTENSION] = "";
 	int privdb_val = 0;
-	unsigned int calldurationlimit = 0;
+	int calldurationlimit = -1;
 	long timelimit = 0;
 	long play_warning = 0;
 	long warning_freq = 0;
@@ -1017,7 +1017,7 @@
 		start_sound = S_OR(var, NULL);	/* XXX not much of a point in doing this! */
 
 		/* undo effect of S(x) in case they are both used */
-		calldurationlimit = 0;
+		calldurationlimit = -1;
 		/* more efficient to do it like S(x) does since no advanced opts */
 		if (!play_warning && !start_sound && !end_sound && timelimit) {
 			calldurationlimit = timelimit / 1000;
@@ -1751,7 +1751,7 @@
 		if (!res) {
 			if (calldurationlimit > 0) {
 				peer->whentohangup = time(NULL) + calldurationlimit;
-			} else if (timelimit > 0) {
+			} else if (calldurationlimit != -1 && timelimit > 0) {
 				/* Not enough granularity to make it less, but we can't use the special value 0 */
 				peer->whentohangup = time(NULL) + 1;
 			}

Modified: team/murf/masqpark/apps/app_macro.c
URL: http://svn.digium.com/view/asterisk/team/murf/masqpark/apps/app_macro.c?view=diff&rev=165207&r1=165206&r2=165207
==============================================================================
--- team/murf/masqpark/apps/app_macro.c (original)
+++ team/murf/masqpark/apps/app_macro.c Wed Dec 17 13:06:06 2008
@@ -322,8 +322,8 @@
 					ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited KEEPALIVE in macro %s on '%s'\n", chan->context, chan->exten, chan->priority, macro, chan->name);
 				else if (option_verbose > 1)
 					ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited KEEPALIVE in macro '%s' on '%s'\n", chan->context, chan->exten, chan->priority, macro, chan->name);
+				dead = 1;
 				goto out;
-				break;
 			default:
 				if (option_debug)
 					ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s' in macro '%s'\n", chan->context, chan->exten, chan->priority, chan->name, macro);

Modified: team/murf/masqpark/apps/app_queue.c
URL: http://svn.digium.com/view/asterisk/team/murf/masqpark/apps/app_queue.c?view=diff&rev=165207&r1=165206&r2=165207
==============================================================================
--- team/murf/masqpark/apps/app_queue.c (original)
+++ team/murf/masqpark/apps/app_queue.c Wed Dec 17 13:06:06 2008
@@ -2576,7 +2576,7 @@
 struct queue_transfer_ds {
 	struct queue_ent *qe;
 	struct member *member;
-	int starttime;
+	time_t starttime;
 	int callcompletedinsl;
 };
 
@@ -2603,12 +2603,12 @@
  * At the end of this, we want to remove the datastore so that this fixup function is not called on any
  * future masquerades of the caller during the current call.
  */
-static void queue_transfer_fixup(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan) 
+static void queue_transfer_fixup(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan)
 {
 	struct queue_transfer_ds *qtds = data;
 	struct queue_ent *qe = qtds->qe;
 	struct member *member = qtds->member;
-	int callstart = qtds->starttime;
+	time_t callstart = qtds->starttime;
 	int callcompletedinsl = qtds->callcompletedinsl;
 	struct ast_datastore *datastore;
 
@@ -2618,13 +2618,11 @@
 
 	update_queue(qe->parent, member, callcompletedinsl);
 	
-	if (!(datastore = ast_channel_datastore_find(new_chan, &queue_transfer_info, NULL))) {
+	if ((datastore = ast_channel_datastore_find(new_chan, &queue_transfer_info, NULL))) {
+		ast_channel_datastore_remove(new_chan, datastore);
+	} else {
 		ast_log(LOG_WARNING, "Can't find the queue_transfer datastore.\n");
-		return;
-	}
-
-	ast_channel_datastore_remove(new_chan, datastore);
-	ast_channel_datastore_free(datastore);
+	}
 }
 
 /*! \brief mechanism to tell if a queue caller was atxferred by a queue member.
@@ -2640,21 +2638,21 @@
 
 /*! \brief create a datastore for storing relevant info to log attended transfers in the queue_log
  */
-static void setup_transfer_datastore(struct queue_ent *qe, struct member *member, int starttime, int callcompletedinsl)
+static struct ast_datastore *setup_transfer_datastore(struct queue_ent *qe, struct member *member, time_t starttime, int callcompletedinsl)
 {
 	struct ast_datastore *ds;
 	struct queue_transfer_ds *qtds = ast_calloc(1, sizeof(*qtds));
 
 	if (!qtds) {
 		ast_log(LOG_WARNING, "Memory allocation error!\n");
-		return;
+		return NULL;
 	}
 
 	ast_channel_lock(qe->chan);
 	if (!(ds = ast_channel_datastore_alloc(&queue_transfer_info, NULL))) {
 		ast_channel_unlock(qe->chan);
 		ast_log(LOG_WARNING, "Unable to create transfer datastore. queue_log will not show attended transfer\n");
-		return;
+		return NULL;
 	}
 
 	qtds->qe = qe;
@@ -2665,6 +2663,7 @@
 	ds->data = qtds;
 	ast_channel_datastore_add(qe->chan, ds);
 	ast_channel_unlock(qe->chan);
+	return ds;
 }
 
 
@@ -2728,7 +2727,7 @@
 	int forwardsallowed = 1;
 	int callcompletedinsl;
 	struct ao2_iterator memi;
-	struct ast_datastore *datastore;
+	struct ast_datastore *datastore, *transfer_ds;
 
 	ast_channel_lock(qe->chan);
 	datastore = ast_channel_datastore_find(qe->chan, &dialed_interface_info, NULL);
@@ -3151,11 +3150,11 @@
 		if (member->status == AST_DEVICE_NOT_INUSE)
 			ast_log(LOG_WARNING, "The device state of this queue member, %s, is still 'Not in Use' when it probably should not be! Please check UPGRADE.txt for correct configuration settings.\n", member->membername);
 			
-		setup_transfer_datastore(qe, member, callstart, callcompletedinsl);
+		transfer_ds = setup_transfer_datastore(qe, member, callstart, callcompletedinsl);
 		bridge = ast_bridge_call(qe->chan,peer, &bridge_config);
 
 		if (!attended_transfer_occurred(qe->chan)) {
-			struct ast_datastore *transfer_ds;
+			struct ast_datastore *tds;
 			if (strcasecmp(oldcontext, qe->chan->context) || strcasecmp(oldexten, qe->chan->exten)) {
 				ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "TRANSFER", "%s|%s|%ld|%ld",
 					qe->chan->exten, qe->chan->context, (long) (callstart - qe->start),
@@ -3195,15 +3194,16 @@
 							qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, sizeof(vars)) : "");
 			}
 			ast_channel_lock(qe->chan);
-			transfer_ds = ast_channel_datastore_find(qe->chan, &queue_transfer_info, NULL);
-			if (transfer_ds) {
-				ast_channel_datastore_remove(qe->chan, transfer_ds);
-				ast_channel_datastore_free(transfer_ds);
+			if ((tds = ast_channel_datastore_find(qe->chan, &queue_transfer_info, NULL))) {
+				ast_channel_datastore_remove(qe->chan, tds);
 			}
 			ast_channel_unlock(qe->chan);
 			update_queue(qe->parent, member, callcompletedinsl);
 		}
 
+		if (transfer_ds) {
+			ast_channel_datastore_free(transfer_ds);
+		}
 		ast_hangup(peer);
 		res = bridge ? bridge : 1;
 		ao2_ref(member, -1);
@@ -3446,7 +3446,7 @@
 /* Reload dynamic queue members persisted into the astdb */
 static void reload_queue_members(void)
 {
-	char *cur_ptr;	
+	char *cur_ptr;
 	char *queue_name;
 	char *member;
 	char *interface;

Modified: team/murf/masqpark/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/murf/masqpark/channels/chan_sip.c?view=diff&rev=165207&r1=165206&r2=165207
==============================================================================
--- team/murf/masqpark/channels/chan_sip.c (original)
+++ team/murf/masqpark/channels/chan_sip.c Wed Dec 17 13:06:06 2008
@@ -7627,7 +7627,9 @@
 
 	/* exit if we are already in process with this registrar ?*/
 	if ( r == NULL || ((auth==NULL) && (r->regstate==REG_STATE_REGSENT || r->regstate==REG_STATE_AUTHSENT))) {
-		ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname);
+		if (r) {
+			ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname);
+		}
 		return 0;
 	}
 
@@ -9566,11 +9568,13 @@
 	if (user && ast_apply_ha(user->ha, sin)) {
 		ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY);
 		ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
-		/* copy channel vars */
-		for (v = user->chanvars ; v ; v = v->next) {
-			if ((tmpvar = ast_variable_new(v->name, v->value))) {
-				tmpvar->next = p->chanvars; 
-				p->chanvars = tmpvar;
+		if (sipmethod == SIP_INVITE) {
+			/* copy channel vars */
+			for (v = user->chanvars ; v ; v = v->next) {
+				if ((tmpvar = ast_variable_new(v->name, v->value))) {
+					tmpvar->next = p->chanvars; 
+					p->chanvars = tmpvar;
+				}
 			}
 		}
 		p->prefs = user->prefs;
@@ -9724,11 +9728,13 @@
 				ast_string_field_set(p, peername, peer->name);
 				ast_string_field_set(p, authname, peer->name);
 
-				/* copy channel vars */
-				for (v = peer->chanvars ; v ; v = v->next) {
-					if ((tmpvar = ast_variable_new(v->name, v->value))) {
-						tmpvar->next = p->chanvars; 
-						p->chanvars = tmpvar;
+				if (sipmethod == SIP_INVITE) {
+					/* copy channel vars */
+					for (v = peer->chanvars ; v ; v = v->next) {
+						if ((tmpvar = ast_variable_new(v->name, v->value))) {
+							tmpvar->next = p->chanvars; 
+							p->chanvars = tmpvar;
+						}
 					}
 				}
 				if (authpeer) {
@@ -14313,7 +14319,9 @@
 			ast_mutex_unlock(&p->lock);
 			if (p->refer->refer_call) {
 				ast_mutex_unlock(&p->refer->refer_call->lock);
-				ast_channel_unlock(p->refer->refer_call->owner);
+				if (p->refer->refer_call->owner) {
+					ast_channel_unlock(p->refer->refer_call->owner);
+				}
 			}
 			p->invitestate = INV_COMPLETED;
 			return -1;

Modified: team/murf/masqpark/configure.ac
URL: http://svn.digium.com/view/asterisk/team/murf/masqpark/configure.ac?view=diff&rev=165207&r1=165206&r2=165207
==============================================================================
--- team/murf/masqpark/configure.ac (original)
+++ team/murf/masqpark/configure.ac Wed Dec 17 13:06:06 2008
@@ -266,6 +266,15 @@
 AC_FUNC_UTIME_NULL
 AC_FUNC_VPRINTF
 AC_CHECK_FUNCS([asprintf atexit bzero dup2 endpwent floor ftruncate getcwd gethostbyname gethostname getloadavg gettimeofday inet_ntoa isascii localtime_r memchr memmove memset mkdir munmap pow putenv re_comp regcomp rint select setenv socket sqrt strcasecmp strcasestr strchr strcspn strdup strerror strlcat strlcpy strncasecmp strndup strnlen strrchr strsep strspn strstr strtol strtoq unsetenv utime vasprintf ioperm])
+
+AC_MSG_CHECKING(for timersub in time.h)
+AC_LINK_IFELSE(
+	AC_LANG_PROGRAM([#include <sys/time.h>],
+			[struct timeval *zombies; timersub(zombies, zombies, zombies);]),
+	AC_MSG_RESULT(yes)
+	AC_DEFINE([HAVE_TIMERSUB], 1, [Define to 1 if your system has timersub in time.h]),
+	AC_MSG_RESULT(no)
+)
 
 # some systems already have gethostbyname_r so we don't need to build ours in main/utils.c
 AC_SEARCH_LIBS(gethostbyname_r, [socket nsl])

Modified: team/murf/masqpark/funcs/func_cut.c
URL: http://svn.digium.com/view/asterisk/team/murf/masqpark/funcs/func_cut.c?view=diff&rev=165207&r1=165206&r2=165207
==============================================================================
--- team/murf/masqpark/funcs/func_cut.c (original)
+++ team/murf/masqpark/funcs/func_cut.c Wed Dec 17 13:06:06 2008
@@ -254,7 +254,6 @@
 	struct ast_module_user *u = NULL;
 
 	if (chan) {
-		ast_autoservice_start(chan);
 		u = ast_module_user_add(chan);
 	}
 
@@ -277,7 +276,6 @@
 
 	if (chan) {
 		ast_module_user_remove(u);
-		ast_autoservice_stop(chan);
 	}
 
 	return ret;

Modified: team/murf/masqpark/funcs/func_strings.c
URL: http://svn.digium.com/view/asterisk/team/murf/masqpark/funcs/func_strings.c?view=diff&rev=165207&r1=165206&r2=165207
==============================================================================
--- team/murf/masqpark/funcs/func_strings.c (original)
+++ team/murf/masqpark/funcs/func_strings.c Wed Dec 17 13:06:06 2008
@@ -53,9 +53,6 @@
 			     AST_APP_ARG(delim);
 		);
 
-	if (chan)
-		ast_autoservice_start(chan);
-
 	AST_STANDARD_APP_ARGS(args, parse);
 	if (args.delim) {
 		varsubst = alloca(strlen(args.varname) + 4);
@@ -73,9 +70,6 @@
 	}
 	snprintf(buf, len, "%d", fieldcount);
 
-	if (chan)
-		ast_autoservice_stop(chan);
-
 	return 0;
 }
 
@@ -183,9 +177,6 @@
 	value2 = ast_strdupa(value);
 	if (!var || !value2)
 		return -1;
-
-	if (chan)
-		ast_autoservice_start(chan);
 
 	/* The functions this will generally be used with are SORT and ODBC_*, which
 	 * both return comma-delimited lists.  However, if somebody uses literal lists,
@@ -217,9 +208,6 @@
 			pbx_builtin_setvar_helper(chan, arg1.var[i], "");
 		}
 	}
-
-	if (chan)
-		ast_autoservice_stop(chan);
 
 	return 0;
 }
@@ -543,11 +531,7 @@
 		return -1;
 	}
 
-	if (chan)
-		ast_autoservice_start(chan);
 	pbx_substitute_variables_helper(chan, data, buf, len - 1);
-	if (chan)
-		ast_autoservice_stop(chan);
 
 	return 0;
 }

Modified: team/murf/masqpark/include/asterisk/autoconfig.h.in
URL: http://svn.digium.com/view/asterisk/team/murf/masqpark/include/asterisk/autoconfig.h.in?view=diff&rev=165207&r1=165206&r2=165207
==============================================================================
--- team/murf/masqpark/include/asterisk/autoconfig.h.in (original)
+++ team/murf/masqpark/include/asterisk/autoconfig.h.in Wed Dec 17 13:06:06 2008
@@ -497,6 +497,9 @@
 
 /* Define to 1 if you have the <termios.h> header file. */
 #undef HAVE_TERMIOS_H
+
+/* Define to 1 if your system has timersub in time.h */
+#undef HAVE_TIMERSUB
 
 /* Define to indicate the ${TINFO_DESCRIP} library */
 #undef HAVE_TINFO

Modified: team/murf/masqpark/include/asterisk/channel.h
URL: http://svn.digium.com/view/asterisk/team/murf/masqpark/include/asterisk/channel.h?view=diff&rev=165207&r1=165206&r2=165207
==============================================================================
--- team/murf/masqpark/include/asterisk/channel.h (original)
+++ team/murf/masqpark/include/asterisk/channel.h Wed Dec 17 13:06:06 2008
@@ -398,7 +398,7 @@
 	enum ast_channel_state _state;			/*!< State of line -- Don't write directly, use ast_setstate */
 	int rings;					/*!< Number of rings so far */
 	struct ast_callerid cid;			/*!< Caller ID, name, presentation etc */
-	char dtmfq[AST_MAX_EXTENSION];			/*!< Any/all queued DTMF characters */
+	char unused_old_dtmfq[AST_MAX_EXTENSION];	/*!< The DTMFQ is deprecated.  All frames should go to the readq. */
 	struct ast_frame dtmff;				/*!< DTMF frame */
 
 	char context[AST_MAX_CONTEXT];			/*!< Dialplan: Current extension context */
@@ -632,6 +632,20 @@
 /*! \brief Queue an outgoing frame */
 int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f);
 
+/*!
+ * \brief Queue an outgoing frame to the head of the frame queue
+ *
+ * \param chan the channel to queue the frame on
+ * \param f the frame to queue.  Note that this frame will be duplicated by
+ *        this function.  It is the responsibility of the caller to handle
+ *        freeing the memory associated with the frame being passed if
+ *        necessary.
+ *
+ * \retval 0 success
+ * \retval non-zero failure
+ */
+int ast_queue_frame_head(struct ast_channel *chan, struct ast_frame *f);
+
 /*! \brief Queue a hangup frame */
 int ast_queue_hangup(struct ast_channel *chan);
 
@@ -1173,6 +1187,11 @@
 /*! 
  * \brief Stop servicing a channel for us...  
  *
+ * \note if chan is locked prior to calling ast_autoservice_stop, it
+ * is likely that there will be a deadlock between the thread that calls
+ * ast_autoservice_stop and the autoservice thread. It is important
+ * that chan is not locked prior to this call
+ *
  * \retval 0 success
  * \retval -1 error, or the channel has been hungup 
  */
@@ -1301,7 +1320,7 @@
 	return 0;
 }
 
-#ifdef SOLARIS
+#ifndef HAVE_TIMERSUB
 static inline void timersub(struct timeval *tvend, struct timeval *tvstart, struct timeval *tvdiff)
 {
 	tvdiff->tv_sec = tvend->tv_sec - tvstart->tv_sec;

Modified: team/murf/masqpark/include/asterisk/pbx.h
URL: http://svn.digium.com/view/asterisk/team/murf/masqpark/include/asterisk/pbx.h?view=diff&rev=165207&r1=165206&r2=165207
==============================================================================
--- team/murf/masqpark/include/asterisk/pbx.h (original)
+++ team/murf/masqpark/include/asterisk/pbx.h Wed Dec 17 13:06:06 2008
@@ -381,6 +381,10 @@
  * \param priority priority of the action within the extension
  * \param callerid callerid to search for
  *
+ * \note It is possible for autoservice to be started and stopped on c during this
+ * function call, it is important that c is not locked prior to calling this. Otherwise
+ * a deadlock may occur
+ *
  * \return If an extension within the given context(or callerid) with the given priority 
  *         is found a non zero value will be returned. Otherwise, 0 is returned.
  */
@@ -396,6 +400,10 @@
  * \param label label of the action within the extension to match to priority
  * \param callerid callerid to search for
  *
+ * \note It is possible for autoservice to be started and stopped on c during this
+ * function call, it is important that c is not locked prior to calling this. Otherwise
+ * a deadlock may occur
+ *
  * \return the priority which matches the given label in the extension or -1 if not found.
  */
 int ast_findlabel_extension(struct ast_channel *c, const char *context, 
@@ -403,6 +411,10 @@
 
 /*!
  * \brief Find the priority of an extension that has the specified label
+ *
+ * \note It is possible for autoservice to be started and stopped on c during this
+ * function call, it is important that c is not locked prior to calling this. Otherwise
+ * a deadlock may occur
  *
  * \note This function is the same as ast_findlabel_extension, except that it accepts
  * a pointer to an ast_context structure to specify the context instead of the
@@ -420,6 +432,10 @@
  * \param priority priority of extension path
  * \param callerid callerid of extension being searched for
  *
+ * \note It is possible for autoservice to be started and stopped on c during this
+ * function call, it is important that c is not locked prior to calling this. Otherwise
+ * a deadlock may occur
+ *
  * \return If "exten" *could be* a valid extension in this context with or without
  * some more digits, return non-zero.  Basically, when this returns 0, no matter
  * what you add to exten, it's not going to be a valid extension anymore
@@ -436,6 +452,10 @@
  * \param priority priority of extension path
  * \param callerid callerid of extension being searched for
  *
+ * \note It is possible for autoservice to be started and stopped on c during this
+ * function call, it is important that c is not locked prior to calling this. Otherwise
+ * a deadlock may occur
+ *
  * \return If "exten" *could match* a valid extension in this context with
  * some more digits, return non-zero.  Does NOT return non-zero if this is
  * an exact-match only.  Basically, when this returns 0, no matter
@@ -469,6 +489,10 @@
  * \param callerid callerid of extension
  *
  * This adds a new extension to the asterisk extension list.
+ *
+ * \note It is possible for autoservice to be started and stopped on c during this
+ * function call, it is important that c is not locked prior to calling this. Otherwise
+ * a deadlock may occur
  *
  * \retval 0 on success 
  * \retval -1 on failure.

Modified: team/murf/masqpark/include/asterisk/threadstorage.h
URL: http://svn.digium.com/view/asterisk/team/murf/masqpark/include/asterisk/threadstorage.h?view=diff&rev=165207&r1=165206&r2=165207
==============================================================================
--- team/murf/masqpark/include/asterisk/threadstorage.h (original)
+++ team/murf/masqpark/include/asterisk/threadstorage.h Wed Dec 17 13:06:06 2008
@@ -159,7 +159,7 @@
 		if (!(buf = ast_calloc(1, init_size)))
 			return NULL;
 		pthread_setspecific(ts->key, buf);
-		__ast_threadstorage_object_add(&ts->key, init_size, file, function, line);
+		__ast_threadstorage_object_add(buf, init_size, file, function, line);
 	}
 
 	return buf;

Modified: team/murf/masqpark/main/asterisk.c
URL: http://svn.digium.com/view/asterisk/team/murf/masqpark/main/asterisk.c?view=diff&rev=165207&r1=165206&r2=165207
==============================================================================
--- team/murf/masqpark/main/asterisk.c (original)
+++ team/murf/masqpark/main/asterisk.c Wed Dec 17 13:06:06 2008
@@ -1363,6 +1363,11 @@
 	 * is going to exit */
 }
 
+static void __remote_quit_handler(int num)
+{
+	sig_flags.need_quit = 1;
+}
+
 static const char *fix_header(char *outbuf, int maxout, const char *s, char *cmp)
 {
 	const char *c;
@@ -1772,6 +1777,8 @@
 		}
 		res = poll(fds, max, -1);
 		if (res < 0) {
+			if (sig_flags.need_quit)
+				break;
 			if (errno == EINTR)
 				continue;
 			ast_log(LOG_ERROR, "poll failed: %s\n", strerror(errno));
@@ -2306,6 +2313,11 @@
 	char *ebuf;
 	int num = 0;
 
+	memset(&sig_flags, 0, sizeof(sig_flags));
+	signal(SIGINT, __remote_quit_handler);
+	signal(SIGTERM, __remote_quit_handler);
+	signal(SIGHUP, __remote_quit_handler);
+
 	if (read(ast_consock, buf, sizeof(buf)) < 0) {
 		ast_log(LOG_ERROR, "read() failed: %s\n", strerror(errno));
 		return;
@@ -2313,6 +2325,9 @@
 	if (data) {
 		if (write(ast_consock, data, strlen(data) + 1) < 0) {
 			ast_log(LOG_ERROR, "write() failed: %s\n", strerror(errno));
+			if (sig_flags.need_quit == 1) {
+				return;
+			}
 		}
 	}
 	stringp = buf;
@@ -2358,6 +2373,10 @@
 			char buf[512] = "", *curline = buf, *nextline;
 			int not_written = 1;
 
+			if (sig_flags.need_quit == 1) {
+				break;
+			}
+
 			if (read(ast_consock, buf, sizeof(buf) - 1) <= 0) {
 				break;
 			}
@@ -2388,6 +2407,10 @@
 	}
 	for (;;) {
 		ebuf = (char *)el_gets(el, &num);
+
+		if (sig_flags.need_quit == 1) {
+			break;
+		}
 
 		if (!ebuf && write(1, "", 1) < 0)
 			break;

Modified: team/murf/masqpark/main/autoservice.c
URL: http://svn.digium.com/view/asterisk/team/murf/masqpark/main/autoservice.c?view=diff&rev=165207&r1=165206&r2=165207
==============================================================================
--- team/murf/masqpark/main/autoservice.c (original)
+++ team/murf/masqpark/main/autoservice.c Wed Dec 17 13:06:06 2008
@@ -61,6 +61,9 @@
 	 *  it gets stopped for the last time. */
 	unsigned int use_count;
 	unsigned int orig_end_dtmf_flag:1;
+	/*! Frames go on at the head of deferred_frames, so we have the frames
+	 *  from newest to oldest.  As we put them at the head of the readq, we'll
+	 *  end up with them in the right order for the channel's readq. */
 	AST_LIST_HEAD_NOLOCK(, ast_frame) deferred_frames;
 	AST_LIST_ENTRY(asent) list;
 };
@@ -166,7 +169,7 @@
 				}
 				
 				if ((dup_f = ast_frdup(defer_frame))) {
-					AST_LIST_INSERT_TAIL(&ents[i]->deferred_frames, dup_f, frame_list);
+					AST_LIST_INSERT_HEAD(&ents[i]->deferred_frames, dup_f, frame_list);
 				}
 				
 				break;
@@ -298,10 +301,12 @@
 		ast_clear_flag(chan, AST_FLAG_END_DTMF_ONLY);
 	}
 
+	ast_channel_lock(chan);
 	while ((f = AST_LIST_REMOVE_HEAD(&as->deferred_frames, frame_list))) {
-		ast_queue_frame(chan, f);
+		ast_queue_frame_head(chan, f);
 		ast_frfree(f);
 	}
+	ast_channel_unlock(chan);
 
 	free(as);
 

Modified: team/murf/masqpark/main/channel.c
URL: http://svn.digium.com/view/asterisk/team/murf/masqpark/main/channel.c?view=diff&rev=165207&r1=165206&r2=165207
==============================================================================
--- team/murf/masqpark/main/channel.c (original)
+++ team/murf/masqpark/main/channel.c Wed Dec 17 13:06:06 2008
@@ -899,7 +899,7 @@
 }
 
 /*! \brief Queue an outgoing media frame */
-int ast_queue_frame(struct ast_channel *chan, struct ast_frame *fin)
+static int __ast_queue_frame(struct ast_channel *chan, struct ast_frame *fin, int head)
 {
 	struct ast_frame *f;
 	struct ast_frame *cur;
@@ -908,9 +908,9 @@
 
 	/* Build us a copy and free the original one */
 	if (!(f = ast_frdup(fin))) {
-		ast_log(LOG_WARNING, "Unable to duplicate frame\n");
 		return -1;
 	}
+
 	ast_channel_lock(chan);
 
 	/* See if the last frame on the queue is a hangup, if so don't queue anything */
@@ -938,11 +938,18 @@
 			return 0;
 		}
 	}
-	AST_LIST_INSERT_TAIL(&chan->readq, f, frame_list);
+
+	if (head) {
+		AST_LIST_INSERT_HEAD(&chan->readq, f, frame_list);
+	} else {
+		AST_LIST_INSERT_TAIL(&chan->readq, f, frame_list);
+	}
+
 	if (chan->alertpipe[1] > -1) {
-		if (write(chan->alertpipe[1], &blah, sizeof(blah)) != sizeof(blah))
+		if (write(chan->alertpipe[1], &blah, sizeof(blah)) != sizeof(blah)) {
 			ast_log(LOG_WARNING, "Unable to write to alert pipe on %s, frametype/subclass %d/%d (qlen = %d): %s!\n",
 				chan->name, f->frametype, f->subclass, qlen, strerror(errno));
+		}
 #ifdef HAVE_DAHDI
 	} else if (chan->timingfd > -1) {
 		ioctl(chan->timingfd, DAHDI_TIMERPING, &blah);
@@ -950,8 +957,20 @@
 	} else if (ast_test_flag(chan, AST_FLAG_BLOCKING)) {
 		pthread_kill(chan->blocker, SIGURG);
 	}
+
 	ast_channel_unlock(chan);
+
 	return 0;
+}
+
+int ast_queue_frame(struct ast_channel *chan, struct ast_frame *fin)
+{
+	return __ast_queue_frame(chan, fin, 0);
+}
+
+int ast_queue_frame_head(struct ast_channel *chan, struct ast_frame *fin)
+{
+	return __ast_queue_frame(chan, fin, 1);
 }
 
 /*! \brief Queue a hangup frame for channel */
@@ -1968,6 +1987,42 @@
 	}
 }
 
+static inline void queue_dtmf_readq(struct ast_channel *chan, struct ast_frame *f)
+{
+	struct ast_frame *fr = &chan->dtmff;
+
+	fr->frametype = AST_FRAME_DTMF_END;
+	fr->subclass = f->subclass;
+	fr->len = f->len;
+
+	/* The only time this function will be called is for a frame that just came
+	 * out of the channel driver.  So, we want to stick it on the tail of the
+	 * readq. */
+
+	ast_queue_frame(chan, fr);
+}
+
+/*!
+ * \brief Determine whether or not we should ignore DTMF in the readq
+ */
+static inline int should_skip_dtmf(struct ast_channel *chan)
+{
+	if (ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_EMULATE_DTMF)) {
+		/* We're in the middle of emulating a digit, or DTMF has been
+		 * explicitly deferred.  Skip this digit, then. */
+		return 1;
+	}
+			
+	if (!ast_tvzero(chan->dtmf_tv) && 
+			ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) {
+		/* We're not in the middle of a digit, but it hasn't been long enough
+		 * since the last digit, so we'll have to skip DTMF for now. */
+		return 1;
+	}
+
+	return 0;
+}
+
 static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio)
 {
 	struct ast_frame *f = NULL;	/* the return value */
@@ -2001,28 +2056,6 @@
 	}
 	prestate = chan->_state;
 
-	if (!ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_EMULATE_DTMF | AST_FLAG_IN_DTMF) && 
-	    !ast_strlen_zero(chan->dtmfq) && 
-		(ast_tvzero(chan->dtmf_tv) || ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) > AST_MIN_DTMF_GAP) ) {

[... 902 lines stripped ...]



More information about the asterisk-commits mailing list