[asterisk-commits] russell: trunk r105564 - in /trunk: ./ include/asterisk/ main/
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Mon Mar 3 09:59:50 CST 2008
Author: russell
Date: Mon Mar 3 09:59:50 2008
New Revision: 105564
URL: http://svn.digium.com/view/asterisk?view=rev&rev=105564
Log:
3) In addition to merging the changes below, change trunk back to a regular
LIST instead of an RWLIST. The way this list works makes it such that
a RWLIST provides no additional benefit. Also, a mutex is needed for
use with the thread condition.
Merged revisions 105563 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r105563 | russell | 2008-03-03 09:50:43 -0600 (Mon, 03 Mar 2008) | 24 lines
Merge in some changes from team/russell/autoservice-nochans-1.4
These changes fix up some dubious code that I came across while auditing what
happens in the autoservice thread when there are no channels currently in
autoservice.
1) Change it so that autoservice thread doesn't keep looping around calling
ast_waitfor_n() on 0 channels twice a second. Instead, use a thread condition
so that the thread properly goes to sleep and does not wake up until a
channel is put into autoservice.
This actually fixes an interesting bug, as well. If the autoservice thread
is already running (almost always is the case), then when the thread goes
from having 0 channels to have 1 channel to autoservice, that channel would
have to wait for up to 1/2 of a second to have the first frame read from it.
2) Fix up the code in ast_waitfor_nandfds() for when it gets called with no
channels and no fds to poll() on, such as was the case with the previous code
for the autoservice thread. In this case, the code would call alloca(0), and
pass the result as the first argument to poll(). In this case, the 2nd
argument to poll() specified that there were no fds, so this invalid pointer
shouldn't actually get dereferenced, but, this code makes it explicit and
ensures the pointers are NULL unless we have valid data to put there.
........
Modified:
trunk/ (props changed)
trunk/include/asterisk/_private.h
trunk/main/asterisk.c
trunk/main/autoservice.c
trunk/main/channel.c
Propchange: trunk/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.
Modified: trunk/include/asterisk/_private.h
URL: http://svn.digium.com/view/asterisk/trunk/include/asterisk/_private.h?view=diff&rev=105564&r1=105563&r2=105564
==============================================================================
--- trunk/include/asterisk/_private.h (original)
+++ trunk/include/asterisk/_private.h Mon Mar 3 09:59:50 2008
@@ -33,6 +33,7 @@
int astobj2_init(void); /*!< Provided by astobj2.c */
int ast_file_init(void); /*!< Provided by file.c */
int ast_features_init(void); /*!< Provided by features.c */
+void ast_autoservice_init(void); /*!< Provided by autoservice.c */
/*!
* \brief Reload asterisk modules.
Modified: trunk/main/asterisk.c
URL: http://svn.digium.com/view/asterisk/trunk/main/asterisk.c?view=diff&rev=105564&r1=105563&r2=105564
==============================================================================
--- trunk/main/asterisk.c (original)
+++ trunk/main/asterisk.c Mon Mar 3 09:59:50 2008
@@ -3186,6 +3186,8 @@
astobj2_init();
+ ast_autoservice_init();
+
if (load_modules(1)) { /* Load modules, pre-load only */
printf(term_quit());
exit(1);
Modified: trunk/main/autoservice.c
URL: http://svn.digium.com/view/asterisk/trunk/main/autoservice.c?view=diff&rev=105564&r1=105563&r2=105564
==============================================================================
--- trunk/main/autoservice.c (original)
+++ trunk/main/autoservice.c Mon Mar 3 09:59:50 2008
@@ -29,6 +29,8 @@
#include <sys/time.h>
#include <signal.h>
+
+#include "asterisk/_private.h" /* prototype for ast_autoservice_init() */
#include "asterisk/pbx.h"
#include "asterisk/frame.h"
@@ -56,7 +58,8 @@
AST_LIST_ENTRY(asent) list;
};
-static AST_RWLIST_HEAD_STATIC(aslist, asent);
+static AST_LIST_HEAD_STATIC(aslist, asent);
+static ast_cond_t as_cond;
static pthread_t asthread = AST_PTHREADT_NULL;
@@ -67,14 +70,14 @@
struct ast_frame *dup_f;
struct asent *as;
- AST_RWLIST_WRLOCK(&aslist);
- AST_RWLIST_TRAVERSE(&aslist, as, list) {
+ AST_LIST_LOCK(&aslist);
+ AST_LIST_TRAVERSE(&aslist, as, list) {
if (as->chan != chan)
continue;
if ((dup_f = ast_frdup(f)))
AST_LIST_INSERT_TAIL(&as->dtmf_frames, dup_f, frame_list);
}
- AST_RWLIST_UNLOCK(&aslist);
+ AST_LIST_UNLOCK(&aslist);
}
static void *autoservice_run(void *ign)
@@ -84,13 +87,16 @@
struct asent *as;
int x = 0, ms = 500;
- AST_RWLIST_RDLOCK(&aslist);
+ AST_LIST_LOCK(&aslist);
/* At this point, we know that no channels that have been removed are going
* to get used again. */
as_chan_list_state++;
- AST_RWLIST_TRAVERSE(&aslist, as, list) {
+ if (AST_LIST_EMPTY(&aslist))
+ ast_cond_wait(&as_cond, &aslist.lock);
+
+ AST_LIST_TRAVERSE(&aslist, as, list) {
if (!ast_check_hangup(as->chan)) {
if (x < MAX_AUTOMONS)
mons[x++] = as->chan;
@@ -98,7 +104,8 @@
ast_log(LOG_WARNING, "Exceeded maximum number of automatic monitoring events. Fix autoservice.c\n");
}
}
- AST_RWLIST_UNLOCK(&aslist);
+
+ AST_LIST_UNLOCK(&aslist);
if ((chan = ast_waitfor_n(mons, x, &ms))) {
struct ast_frame *f = ast_read(chan);
@@ -158,14 +165,14 @@
int res = 0;
struct asent *as;
- AST_RWLIST_WRLOCK(&aslist);
- AST_RWLIST_TRAVERSE(&aslist, as, list) {
+ AST_LIST_LOCK(&aslist);
+ AST_LIST_TRAVERSE(&aslist, as, list) {
if (as->chan == chan) {
as->use_count++;
break;
}
}
- AST_RWLIST_UNLOCK(&aslist);
+ AST_LIST_UNLOCK(&aslist);
if (as) {
/* Entry exists, autoservice is already handling this channel */
@@ -185,18 +192,20 @@
ast_set_flag(chan, AST_FLAG_END_DTMF_ONLY);
ast_channel_unlock(chan);
- AST_RWLIST_WRLOCK(&aslist);
- AST_RWLIST_INSERT_HEAD(&aslist, as, list);
- AST_RWLIST_UNLOCK(&aslist);
+ AST_LIST_LOCK(&aslist);
+ if (AST_LIST_EMPTY(&aslist))
+ ast_cond_signal(&as_cond);
+ AST_LIST_INSERT_HEAD(&aslist, as, list);
+ AST_LIST_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);
+ AST_LIST_LOCK(&aslist);
+ AST_LIST_REMOVE(&aslist, as, list);
+ AST_LIST_UNLOCK(&aslist);
free(as);
res = -1;
} else
@@ -218,7 +227,7 @@
AST_LIST_HEAD_INIT_NOLOCK(&dtmf_frames);
- AST_RWLIST_WRLOCK(&aslist);
+ AST_LIST_LOCK(&aslist);
/* Save the autoservice channel list state. We _must_ verify that the channel
* list has been rebuilt before we return. Because, after we return, the channel
@@ -226,9 +235,9 @@
* it after its gone! */
chan_list_state = as_chan_list_state;
- AST_RWLIST_TRAVERSE_SAFE_BEGIN(&aslist, as, list) {
+ AST_LIST_TRAVERSE_SAFE_BEGIN(&aslist, as, list) {
if (as->chan == chan) {
- AST_RWLIST_REMOVE_CURRENT(list);
+ AST_LIST_REMOVE_CURRENT(list);
as->use_count--;
if (as->use_count)
break;
@@ -241,12 +250,12 @@
break;
}
}
- AST_RWLIST_TRAVERSE_SAFE_END;
+ AST_LIST_TRAVERSE_SAFE_END;
if (removed && asthread != AST_PTHREADT_NULL)
pthread_kill(asthread, SIGURG);
- AST_RWLIST_UNLOCK(&aslist);
+ AST_LIST_UNLOCK(&aslist);
if (!removed)
return 0;
@@ -268,3 +277,8 @@
return res;
}
+
+void ast_autoservice_init(void)
+{
+ ast_cond_init(&as_cond, NULL);
+}
Modified: trunk/main/channel.c
URL: http://svn.digium.com/view/asterisk/trunk/main/channel.c?view=diff&rev=105564&r1=105563&r2=105564
==============================================================================
--- trunk/main/channel.c (original)
+++ trunk/main/channel.c Mon Mar 3 09:59:50 2008
@@ -1771,7 +1771,7 @@
#endif
{
struct timeval start = { 0 , 0 };
- struct pollfd *pfds;
+ struct pollfd *pfds = NULL;
int res;
long rms;
int x, y, max;
@@ -1782,11 +1782,12 @@
struct fdmap {
int chan;
int fdno;
- } *fdmap;
-
- sz = n * AST_MAX_FDS + nfds;
- pfds = alloca(sizeof(*pfds) * sz);
- fdmap = alloca(sizeof(*fdmap) * sz);
+ } *fdmap = NULL;
+
+ if ((sz = n * AST_MAX_FDS + nfds)) {
+ pfds = alloca(sizeof(*pfds) * sz);
+ fdmap = alloca(sizeof(*fdmap) * sz);
+ }
if (outfd)
*outfd = -99999;
More information about the asterisk-commits
mailing list