[asterisk-commits] tilghman: branch group/manager_http_auth r187557 - in /team/group/manager_htt...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Apr 9 15:45:37 CDT 2009


Author: tilghman
Date: Thu Apr  9 15:45:32 2009
New Revision: 187557

URL: http://svn.digium.com/svn-view/asterisk?view=rev&rev=187557
Log:
Merged revisions 187483,187488,187491,187556 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/trunk

................
  r187483 | tilghman | 2009-04-09 13:40:01 -0500 (Thu, 09 Apr 2009) | 15 lines
  
  Merged revisions 187428 via svnmerge from 
  https://origsvn.digium.com/svn/asterisk/branches/1.4
  
  ........
    r187428 | tilghman | 2009-04-09 13:08:20 -0500 (Thu, 09 Apr 2009) | 8 lines
    
    Race condition between ast_cli_command() and 'module unload' could cause a deadlock.
    Add lock timeouts to avoid this potential deadlock.
    (closes issue #14705)
     Reported by: jamessan
     Patches: 
           20090320__bug14705.diff.txt uploaded by tilghman (license 14)
     Tested by: jamessan
  ........
................
  r187488 | mmichelson | 2009-04-09 13:58:41 -0500 (Thu, 09 Apr 2009) | 24 lines
  
  Merged revisions 187484 via svnmerge from 
  https://origsvn.digium.com/svn/asterisk/branches/1.4
  
  ........
    r187484 | mmichelson | 2009-04-09 13:51:20 -0500 (Thu, 09 Apr 2009) | 18 lines
    
    Handle a SIP race condition (reinvite before an ACK) properly.
    
    RFC 5047 explains the proper course of action to take if a 
    reINVITE is received before the ACK from a previous invite
    transaction. What we are to do is to treat the reINVITE as
    if it were both an ACK and a reINVITE and process it normally.
    
    Later, when we receive the ACK we had been expecting, we will
    ignore it since its CSeq is less than the current iseqno of
    the sip_pvt representing this dialog.
    
    (closes issue #13849)
    Reported by: klaus3000
    Patches:
          13849_v2.patch uploaded by mmichelson (license 60)
    Tested by: mmichelson, klaus3000
  ........
................
  r187491 | jpeeler | 2009-04-09 14:10:02 -0500 (Thu, 09 Apr 2009) | 15 lines
  
  Add ability for dialplan execution to continue when caller hangs up.
  
  The F option to app_dial has been modified to accept no parameters and perform
  the above functionality. I don't see anywhere else that is doing function
  overloading, but this really is the best place for this operation because:
  
  - It makes it close to the 'g' option in the argument list which provides
  similar functionality.
  - The existing code to support the current F option provides a very
  convienient location to add this new feature.
  
  (closes issue #12381)
  Reported by: michael-fig
................
  r187556 | dvossel | 2009-04-09 15:40:34 -0500 (Thu, 09 Apr 2009) | 3 lines
  
  More changes concerning r187426. Revised where locks are placed.
................

Modified:
    team/group/manager_http_auth/   (props changed)
    team/group/manager_http_auth/CHANGES
    team/group/manager_http_auth/apps/app_dial.c
    team/group/manager_http_auth/channels/chan_sip.c
    team/group/manager_http_auth/include/asterisk/linkedlists.h
    team/group/manager_http_auth/include/asterisk/lock.h
    team/group/manager_http_auth/include/asterisk/pbx.h
    team/group/manager_http_auth/main/manager.c
    team/group/manager_http_auth/main/pbx.c

Propchange: team/group/manager_http_auth/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.

Propchange: team/group/manager_http_auth/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Thu Apr  9 15:45:32 2009
@@ -1,1 +1,1 @@
-/trunk:1-187444
+/trunk:1-187556

Modified: team/group/manager_http_auth/CHANGES
URL: http://svn.digium.com/svn-view/asterisk/team/group/manager_http_auth/CHANGES?view=diff&rev=187557&r1=187556&r2=187557
==============================================================================
--- team/group/manager_http_auth/CHANGES (original)
+++ team/group/manager_http_auth/CHANGES Thu Apr  9 15:45:32 2009
@@ -24,6 +24,8 @@
  * Added progress option to the app_dial D() option.  When progress DTMF is
    present, those values are sent immediatly upon receiving a PROGRESS message
    regardless if the call has been answered or not.
+ * Added functionality to the app_dial F() option to continue with execution
+   at the current location when no parameters are provided.
 
 Dialplan Functions
 ------------------

Modified: team/group/manager_http_auth/apps/app_dial.c
URL: http://svn.digium.com/svn-view/asterisk/team/group/manager_http_auth/apps/app_dial.c?view=diff&rev=187557&r1=187556&r2=187557
==============================================================================
--- team/group/manager_http_auth/apps/app_dial.c (original)
+++ team/group/manager_http_auth/apps/app_dial.c Thu Apr  9 15:45:32 2009
@@ -132,6 +132,10 @@
 					<argument name="priority" required="true" />
 					<para>When the caller hangs up, transfer the called party
 					to the specified destination and continue execution at that location.</para>
+				</option>
+				<option name="F">
+					<para>Proceed with dialplan execution at the next priority in the current extension if the
+					source channel hangs up.</para>
 				</option>
 				<option name="g">
 					<para>Proceed with dialplan execution at the next priority in the current extension if the
@@ -664,8 +668,13 @@
 /* do not call with chan lock held */
 static const char *get_cid_name(char *name, int namelen, struct ast_channel *chan)
 {
-	const char *context = ast_strdupa(S_OR(chan->macrocontext, chan->context));
-	const char *exten = ast_strdupa(S_OR(chan->macroexten, chan->exten));
+	const char *context;
+	const char *exten;
+
+	ast_channel_lock(chan);
+	context = ast_strdupa(S_OR(chan->macrocontext, chan->context));
+	exten = ast_strdupa(S_OR(chan->macroexten, chan->exten));
+	ast_channel_unlock(chan);
 
 	return ast_get_hint(NULL, 0, name, namelen, chan, context, exten) ? name : "";
 }
@@ -777,13 +786,13 @@
 		ast_party_connected_line_copy(&c->connected, apc);
 
 		S_REPLACE(in->cid.cid_rdnis, ast_strdup(c->cid.cid_rdnis));
-		ast_channel_unlock(in);
-		ast_channel_unlock(c);
 		ast_channel_update_redirecting(in, apr);
 
 		ast_clear_flag64(peerflags, OPT_IGNORE_CONNECTEDLINE);
 
 		if (ast_call(c, tmpchan, 0)) {
+			ast_channel_unlock(in);
+			ast_channel_unlock(c);
 			ast_log(LOG_NOTICE, "Failed to dial on local channel for call forward to '%s'\n", tmpchan);
 			ast_clear_flag64(o, DIAL_STILLGOING);
 			ast_hangup(original);
@@ -794,7 +803,14 @@
 			senddialevent(in, c, stuff);
 			if (!ast_test_flag64(peerflags, OPT_ORIGINAL_CLID)) {
 				char cidname[AST_MAX_EXTENSION] = "";
-				ast_set_callerid(c, S_OR(in->macroexten, in->exten), get_cid_name(cidname, sizeof(cidname), in), NULL);
+				const char *tmpexten;
+				tmpexten = ast_strdupa(S_OR(in->macroexten, in->exten));
+				ast_channel_unlock(in);
+				ast_channel_unlock(c);
+				ast_set_callerid(c, tmpexten, get_cid_name(cidname, sizeof(cidname), in), NULL);
+			} else {
+				ast_channel_unlock(in);
+				ast_channel_unlock(c);
 			}
 			/* Hangup the original channel now, in case we needed it */
 			ast_hangup(original);
@@ -1919,11 +1935,11 @@
 			const char *tmpexten = ast_strdupa(S_OR(chan->macroexten, chan->exten));
 			senddialevent(chan, tc, numsubst);
 			ast_verb(3, "Called %s\n", numsubst);
-			ast_channel_unlock(chan); /* unlock chan here.  should not call get_cid_name with chan locked */
+			ast_channel_unlock(chan);
+			ast_channel_unlock(tc);
 			if (!ast_test_flag64(peerflags, OPT_ORIGINAL_CLID)) {
 				ast_set_callerid(tc, tmpexten, get_cid_name(cidname, sizeof(cidname), chan), NULL);
 			}
-			ast_channel_unlock(tc);
 		}
 		/* Put them in the list of outgoing thingies...  We're ready now.
 		   XXX If we're forcibly removed, these outgoing calls won't get
@@ -2332,9 +2348,18 @@
 			}
 			ast_set2_flag(peer, autoloopflag, AST_FLAG_IN_AUTOLOOP);  /* set it back the way it was */
 		}
-		if (!ast_check_hangup(peer) && ast_test_flag64(&opts, OPT_CALLEE_GO_ON) && !ast_strlen_zero(opt_args[OPT_ARG_CALLEE_GO_ON])) {		
-			replace_macro_delimiter(opt_args[OPT_ARG_CALLEE_GO_ON]);
-			ast_parseable_goto(peer, opt_args[OPT_ARG_CALLEE_GO_ON]);
+		if (!ast_check_hangup(peer) && ast_test_flag64(&opts, OPT_CALLEE_GO_ON)) {
+			if(!ast_strlen_zero(opt_args[OPT_ARG_CALLEE_GO_ON])) {
+				replace_macro_delimiter(opt_args[OPT_ARG_CALLEE_GO_ON]);
+				ast_parseable_goto(peer, opt_args[OPT_ARG_CALLEE_GO_ON]);
+			} else { /* F() */
+				int res;
+				res = ast_goto_if_exists(peer, chan->context, chan->exten, (chan->priority) + 1); 
+				if (res == AST_PBX_GOTO_FAILED) {
+					ast_hangup(peer);
+					goto out;
+				}
+			}
 			ast_pbx_start(peer);
 		} else {
 			if (!ast_check_hangup(chan))

Modified: team/group/manager_http_auth/channels/chan_sip.c
URL: http://svn.digium.com/svn-view/asterisk/team/group/manager_http_auth/channels/chan_sip.c?view=diff&rev=187557&r1=187556&r2=187557
==============================================================================
--- team/group/manager_http_auth/channels/chan_sip.c (original)
+++ team/group/manager_http_auth/channels/chan_sip.c Thu Apr  9 15:45:32 2009
@@ -19346,12 +19346,25 @@
 	}
 
 	if (!req->ignore && p->pendinginvite) {
-		/* We already have a pending invite. Sorry. You are on hold. */
-		p->glareinvite = seqno;     /* must hold on to this seqno to process ack and retransmit correctly */
-		transmit_response_reliable(p, "491 Request Pending", req);
-		ast_debug(1, "Got INVITE on call where we already have pending INVITE, deferring that - %s\n", p->callid);
-		/* Don't destroy dialog here */
-		return 0;
+		if (!ast_test_flag(&p->flags[0], SIP_OUTGOING) && ast_test_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) {
+			/* We have received a reINVITE on an incoming call to which we have sent a 200 OK but not yet received
+			 * an ACK. According to RFC 5407, Section 3.1.4, the proper way to handle this race condition is to accept
+			 * the reINVITE since we have established a dialog.
+			 */
+			 
+			/* Note that this will both clear the pendinginvite flag and cancel the 
+			 * retransmission of the 200 OK. Basically, we're accepting this reINVITE as both an ACK
+			 * and a reINVITE in one request.
+			 */
+			__sip_ack(p, p->lastinvite, 1, 0);
+		} else {
+			/* We already have a pending invite. Sorry. You are on hold. */
+			p->glareinvite = seqno;
+			transmit_response_reliable(p, "491 Request Pending", req);
+			ast_debug(1, "Got INVITE on call where we already have pending INVITE, deferring that - %s\n", p->callid);
+			/* Don't destroy dialog here */
+			return 0;
+		}
 	}
 
 	p_replaces = get_header(req, "Replaces");

Modified: team/group/manager_http_auth/include/asterisk/linkedlists.h
URL: http://svn.digium.com/svn-view/asterisk/team/group/manager_http_auth/include/asterisk/linkedlists.h?view=diff&rev=187557&r1=187556&r2=187557
==============================================================================
--- team/group/manager_http_auth/include/asterisk/linkedlists.h (original)
+++ team/group/manager_http_auth/include/asterisk/linkedlists.h Thu Apr  9 15:45:32 2009
@@ -52,6 +52,18 @@
         ast_rwlock_wrlock(&(head)->lock)
 
 /*!
+  \brief Write locks a list, with timeout.
+  \param head This is a pointer to the list head structure
+  \param tv Pointer to a timeval structure
+
+  This macro attempts to place an exclusive write lock in the
+  list head structure pointed to by head.
+  \retval 0 on success
+  \retval non-zero on failure
+*/
+#define	AST_RWLIST_TIMEDWRLOCK(head,tv)	ast_rwlock_timedwrlock(&(head)->lock, tv)
+
+/*!
   \brief Read locks a list.
   \param head This is a pointer to the list head structure
 
@@ -62,6 +74,19 @@
 */
 #define AST_RWLIST_RDLOCK(head)                                         \
         ast_rwlock_rdlock(&(head)->lock)
+
+/*!
+  \brief Read locks a list, with timeout.
+  \param head This is a pointer to the list head structure
+  \param tv Pointer to a timeval structure
+
+  This macro attempts to place a read lock in the
+  list head structure pointed to by head.
+  \retval 0 on success
+  \retval non-zero on failure
+*/
+#define AST_RWLIST_TIMEDRDLOCK(head,tv)                                 \
+        ast_rwlock_timedrdlock(&(head)->lock, tv)
 
 /*!
   \brief Locks a list, without blocking if the list is locked.

Modified: team/group/manager_http_auth/include/asterisk/lock.h
URL: http://svn.digium.com/svn-view/asterisk/team/group/manager_http_auth/include/asterisk/lock.h?view=diff&rev=187557&r1=187556&r2=187557
==============================================================================
--- team/group/manager_http_auth/include/asterisk/lock.h (original)
+++ team/group/manager_http_auth/include/asterisk/lock.h Thu Apr  9 15:45:32 2009
@@ -1353,15 +1353,18 @@
 	return res;
 }
 
-static inline int _ast_rwlock_tryrdlock(ast_rwlock_t *t, const char *name,
-	const char *filename, int line, const char *func)
+#define ast_rwlock_timedrdlock(a,b) \
+	_ast_rwlock_timedrdlock(a, # a, b, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+static inline int _ast_rwlock_timedrdlock(ast_rwlock_t *t, const char *name,
+	const struct timespec *abs_timeout, const char *filename, int line, const char *func)
 {
 	int res;
 	struct ast_lock_track *lt = &t->track;
+	int canlog = strcmp(filename, "logger.c") & t->tracking;
 #ifdef HAVE_BKTR
 	struct ast_bt *bt = NULL;
 #endif
-
 
 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
 	if ((t->lock) == ((pthread_rwlock_t) __AST_RWLOCK_INIT_VALUE)) {
@@ -1386,13 +1389,13 @@
 			bt = &lt->backtrace[lt->reentrancy];
 		}
 		ast_reentrancy_unlock(lt);
-		ast_store_lock_info(AST_RDLOCK, filename, line, func, name, t, bt);
-#else
-		ast_store_lock_info(AST_RDLOCK, filename, line, func, name, t);
-#endif
-	}
-
-	if (!(res = pthread_rwlock_tryrdlock(&t->lock))) {
+		ast_store_lock_info(AST_WRLOCK, filename, line, func, name, t, bt);
+#else
+		ast_store_lock_info(AST_WRLOCK, filename, line, func, name, t);
+#endif
+	}
+	res = pthread_rwlock_timedrdlock(&t->lock, abs_timeout);
+	if (!res) {
 		ast_reentrancy_lock(lt);
 		if (lt->reentrancy < AST_MAX_REENTRANCY) {
 			lt->file[lt->reentrancy] = filename;
@@ -1405,21 +1408,41 @@
 		if (t->tracking) {
 			ast_mark_lock_acquired(t);
 		}
-	} else if (t->tracking) {
-		ast_mark_lock_failed(t);
+	} else {
+#ifdef HAVE_BKTR
+		if (lt->reentrancy) {
+			ast_reentrancy_lock(lt);
+			bt = &lt->backtrace[lt->reentrancy-1];
+		} else {
+			bt = NULL;
+		}
+		if (t->tracking) {
+			ast_remove_lock_info(t, bt);
+		}
+#else
+		if (t->tracking) {
+			ast_remove_lock_info(t);
+		}
+#endif
+		__ast_mutex_logger("%s line %d (%s): Error obtaining read lock: %s\n",
+				filename, line, func, strerror(res));
+		DO_THREAD_CRASH;
 	}
 	return res;
 }
 
-static inline int _ast_rwlock_trywrlock(ast_rwlock_t *t, const char *name,
-	const char *filename, int line, const char *func)
+#define ast_rwlock_timedwrlock(a,b) \
+	_ast_rwlock_timedwrlock(a, # a, b, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+static inline int _ast_rwlock_timedwrlock(ast_rwlock_t *t, const char *name,
+	const struct timespec *abs_timeout, const char *filename, int line, const char *func)
 {
 	int res;
-	struct ast_lock_track *lt= &t->track;
+	struct ast_lock_track *lt = &t->track;
+	int canlog = strcmp(filename, "logger.c") & t->tracking;
 #ifdef HAVE_BKTR
 	struct ast_bt *bt = NULL;
 #endif
-
 
 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
 	if ((t->lock) == ((pthread_rwlock_t) __AST_RWLOCK_INIT_VALUE)) {
@@ -1449,6 +1472,139 @@
 		ast_store_lock_info(AST_WRLOCK, filename, line, func, name, t);
 #endif
 	}
+	res = pthread_rwlock_timedwrlock(&t->lock, abs_timeout);
+	if (!res) {
+		ast_reentrancy_lock(lt);
+		if (lt->reentrancy < AST_MAX_REENTRANCY) {
+			lt->file[lt->reentrancy] = filename;
+			lt->lineno[lt->reentrancy] = line;
+			lt->func[lt->reentrancy] = func;
+			lt->thread[lt->reentrancy] = pthread_self();
+			lt->reentrancy++;
+		}
+		ast_reentrancy_unlock(lt);
+		if (t->tracking) {
+			ast_mark_lock_acquired(t);
+		}
+	} else {
+#ifdef HAVE_BKTR
+		if (lt->reentrancy) {
+			ast_reentrancy_lock(lt);
+			bt = &lt->backtrace[lt->reentrancy-1];
+		} else {
+			bt = NULL;
+		}
+		if (t->tracking) {
+			ast_remove_lock_info(t, bt);
+		}
+#else
+		if (t->tracking) {
+			ast_remove_lock_info(t);
+		}
+#endif
+		__ast_mutex_logger("%s line %d (%s): Error obtaining read lock: %s\n",
+				filename, line, func, strerror(res));
+		DO_THREAD_CRASH;
+	}
+	return res;
+}
+
+static inline int _ast_rwlock_tryrdlock(ast_rwlock_t *t, const char *name,
+	const char *filename, int line, const char *func)
+{
+	int res;
+	struct ast_lock_track *lt = &t->track;
+#ifdef HAVE_BKTR
+	struct ast_bt *bt = NULL;
+#endif
+
+
+#ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
+	if ((t->lock) == ((pthread_rwlock_t) __AST_RWLOCK_INIT_VALUE)) {
+		 /* Don't warn abount uninitialized lock.
+		  * Simple try to initialize it.
+		  * May be not needed in linux system.
+		  */
+		res = __ast_rwlock_init(t->tracking, filename, line, func, name, t);
+		if ((t->lock) == ((pthread_rwlock_t) __AST_RWLOCK_INIT_VALUE)) {
+			__ast_mutex_logger("%s line %d (%s): Error: rwlock '%s' is uninitialized and unable to initialize.\n",
+					filename, line, func, name);
+			return res;
+		}
+	}
+#endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
+
+	if (t->tracking) {
+#ifdef HAVE_BKTR
+		ast_reentrancy_lock(lt);
+		if (lt->reentrancy != AST_MAX_REENTRANCY) {
+			ast_bt_get_addresses(&lt->backtrace[lt->reentrancy]);
+			bt = &lt->backtrace[lt->reentrancy];
+		}
+		ast_reentrancy_unlock(lt);
+		ast_store_lock_info(AST_RDLOCK, filename, line, func, name, t, bt);
+#else
+		ast_store_lock_info(AST_RDLOCK, filename, line, func, name, t);
+#endif
+	}
+
+	if (!(res = pthread_rwlock_tryrdlock(&t->lock))) {
+		ast_reentrancy_lock(lt);
+		if (lt->reentrancy < AST_MAX_REENTRANCY) {
+			lt->file[lt->reentrancy] = filename;
+			lt->lineno[lt->reentrancy] = line;
+			lt->func[lt->reentrancy] = func;
+			lt->thread[lt->reentrancy] = pthread_self();
+			lt->reentrancy++;
+		}
+		ast_reentrancy_unlock(lt);
+		if (t->tracking) {
+			ast_mark_lock_acquired(t);
+		}
+	} else if (t->tracking) {
+		ast_mark_lock_failed(t);
+	}
+	return res;
+}
+
+static inline int _ast_rwlock_trywrlock(ast_rwlock_t *t, const char *name,
+	const char *filename, int line, const char *func)
+{
+	int res;
+	struct ast_lock_track *lt= &t->track;
+#ifdef HAVE_BKTR
+	struct ast_bt *bt = NULL;
+#endif
+
+
+#ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
+	if ((t->lock) == ((pthread_rwlock_t) __AST_RWLOCK_INIT_VALUE)) {
+		 /* Don't warn abount uninitialized lock.
+		  * Simple try to initialize it.
+		  * May be not needed in linux system.
+		  */
+		res = __ast_rwlock_init(t->tracking, filename, line, func, name, t);
+		if ((t->lock) == ((pthread_rwlock_t) __AST_RWLOCK_INIT_VALUE)) {
+			__ast_mutex_logger("%s line %d (%s): Error: rwlock '%s' is uninitialized and unable to initialize.\n",
+					filename, line, func, name);
+			return res;
+		}
+	}
+#endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
+
+	if (t->tracking) {
+#ifdef HAVE_BKTR
+		ast_reentrancy_lock(lt);
+		if (lt->reentrancy != AST_MAX_REENTRANCY) {
+			ast_bt_get_addresses(&lt->backtrace[lt->reentrancy]);
+			bt = &lt->backtrace[lt->reentrancy];
+		}
+		ast_reentrancy_unlock(lt);
+		ast_store_lock_info(AST_WRLOCK, filename, line, func, name, t, bt);
+#else
+		ast_store_lock_info(AST_WRLOCK, filename, line, func, name, t);
+#endif
+	}
 
 	if (!(res = pthread_rwlock_trywrlock(&t->lock))) {
 		ast_reentrancy_lock(lt);
@@ -1601,6 +1757,11 @@
 	return pthread_rwlock_rdlock(prwlock);
 }
 
+static inline int ast_rwlock_timedrdlock(ast_rwlock_t *prwlock, const struct timespec *abs_timeout)
+{
+	return pthread_rwlock_timedrdlock(prwlock, abs_timeout);
+}
+
 static inline int ast_rwlock_tryrdlock(ast_rwlock_t *prwlock)
 {
 	return pthread_rwlock_tryrdlock(prwlock);
@@ -1609,6 +1770,11 @@
 static inline int ast_rwlock_wrlock(ast_rwlock_t *prwlock)
 {
 	return pthread_rwlock_wrlock(prwlock);
+}
+
+static inline int ast_rwlock_timedwrlock(ast_rwlock_t *prwlock, const struct timespec *abs_timeout)
+{
+	return pthread_rwlock_timedwrlock(prwlock, abs_timeout);
 }
 
 static inline int ast_rwlock_trywrlock(ast_rwlock_t *prwlock)

Modified: team/group/manager_http_auth/include/asterisk/pbx.h
URL: http://svn.digium.com/svn-view/asterisk/team/group/manager_http_auth/include/asterisk/pbx.h?view=diff&rev=187557&r1=187556&r2=187557
==============================================================================
--- team/group/manager_http_auth/include/asterisk/pbx.h (original)
+++ team/group/manager_http_auth/include/asterisk/pbx.h Thu Apr  9 15:45:32 2009
@@ -34,6 +34,7 @@
 
 #define AST_MAX_APP	32	/*!< Max length of an application */
 
+#define AST_PBX_GOTO_FAILED -3
 #define AST_PBX_KEEP    0
 #define AST_PBX_REPLACE 1
 

Modified: team/group/manager_http_auth/main/manager.c
URL: http://svn.digium.com/svn-view/asterisk/team/group/manager_http_auth/main/manager.c?view=diff&rev=187557&r1=187556&r2=187557
==============================================================================
--- team/group/manager_http_auth/main/manager.c (original)
+++ team/group/manager_http_auth/main/manager.c Thu Apr  9 15:45:32 2009
@@ -3535,8 +3535,12 @@
 int ast_manager_unregister(char *action)
 {
 	struct manager_action *cur;
-
-	AST_RWLIST_WRLOCK(&actions);
+	struct timespec tv = { 5, };
+
+	if (AST_RWLIST_TIMEDWRLOCK(&actions, &tv)) {
+		ast_log(LOG_ERROR, "Could not obtain lock on manager list\n");
+		return -1;
+	}
 	AST_RWLIST_TRAVERSE_SAFE_BEGIN(&actions, cur, list) {
 		if (!strcasecmp(action, cur->action)) {
 			AST_RWLIST_REMOVE_CURRENT(list);
@@ -3545,7 +3549,7 @@
 			break;
 		}
 	}
-	AST_RWLIST_TRAVERSE_SAFE_END;
+	AST_RWLIST_TRAVERSE_SAFE_END
 	AST_RWLIST_UNLOCK(&actions);
 
 	return 0;
@@ -3564,8 +3568,12 @@
 static int ast_manager_register_struct(struct manager_action *act)
 {
 	struct manager_action *cur, *prev = NULL;
-
-	AST_RWLIST_WRLOCK(&actions);
+	struct timespec tv = { 5, };
+
+	if (AST_RWLIST_TIMEDWRLOCK(&actions, &tv)) {
+		ast_log(LOG_ERROR, "Could not obtain lock on manager list\n");
+		return -1;
+	}
 	AST_RWLIST_TRAVERSE(&actions, cur, list) {
 		int ret = strcasecmp(cur->action, act->action);
 		if (ret == 0) {
@@ -3578,7 +3586,7 @@
 			break;
 		}
 	}
-	
+
 	if (prev) {
 		AST_RWLIST_INSERT_AFTER(&actions, prev, act, list);
 	} else {
@@ -3608,7 +3616,10 @@
 	cur->synopsis = synopsis;
 	cur->description = description;
 
-	ast_manager_register_struct(cur);
+	if (ast_manager_register_struct(cur)) {
+		ast_free(cur);
+		return -1;
+	}
 
 	return 0;
 }

Modified: team/group/manager_http_auth/main/pbx.c
URL: http://svn.digium.com/svn-view/asterisk/team/group/manager_http_auth/main/pbx.c?view=diff&rev=187557&r1=187556&r2=187557
==============================================================================
--- team/group/manager_http_auth/main/pbx.c (original)
+++ team/group/manager_http_auth/main/pbx.c Thu Apr  9 15:45:32 2009
@@ -9461,8 +9461,9 @@
 	goto_func = (async) ? ast_async_goto : ast_explicit_goto;
 	if (ast_exists_extension(chan, context, exten, priority, chan->cid.cid_num))
 		return goto_func(chan, context, exten, priority);
-	else
-		return -3;
+	else {
+		return AST_PBX_GOTO_FAILED;
+	}
 }
 
 int ast_goto_if_exists(struct ast_channel *chan, const char* context, const char *exten, int priority)




More information about the asterisk-commits mailing list