2002-12-30 13:09:27 +00:00
|
|
|
/*
|
2005-09-14 20:46:50 +00:00
|
|
|
* Asterisk -- An open source telephony toolkit.
|
2002-12-30 13:09:27 +00:00
|
|
|
*
|
2008-03-03 16:02:19 +00:00
|
|
|
* Copyright (C) 1999 - 2008, Digium, Inc.
|
2005-09-14 20:46:50 +00:00
|
|
|
*
|
|
|
|
* Mark Spencer <markster@digium.com>
|
2008-03-03 16:02:19 +00:00
|
|
|
* Russell Bryant <russell@digium.com>
|
2002-12-30 13:09:27 +00:00
|
|
|
*
|
2005-09-14 20:46:50 +00:00
|
|
|
* See http://www.asterisk.org for more information about
|
|
|
|
* the Asterisk project. Please do not directly contact
|
|
|
|
* any of the maintainers of this project for assistance;
|
|
|
|
* the project provides a web site, mailing lists and IRC
|
|
|
|
* channels for your use.
|
2002-12-30 13:09:27 +00:00
|
|
|
*
|
|
|
|
* This program is free software, distributed under the terms of
|
2005-09-14 20:46:50 +00:00
|
|
|
* the GNU General Public License Version 2. See the LICENSE file
|
|
|
|
* at the top of the source tree.
|
|
|
|
*/
|
|
|
|
|
2005-10-24 20:12:06 +00:00
|
|
|
/*! \file
|
2005-09-14 20:46:50 +00:00
|
|
|
*
|
2005-10-24 20:12:06 +00:00
|
|
|
* \brief Automatic channel service routines
|
2005-12-30 21:18:06 +00:00
|
|
|
*
|
|
|
|
* \author Mark Spencer <markster@digium.com>
|
2008-03-03 16:02:19 +00:00
|
|
|
* \author Russell Bryant <russell@digium.com>
|
2002-12-30 13:09:27 +00:00
|
|
|
*/
|
|
|
|
|
2006-06-07 18:54:56 +00:00
|
|
|
#include "asterisk.h"
|
|
|
|
|
|
|
|
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
|
|
|
|
|
2002-12-30 13:09:27 +00:00
|
|
|
#include <sys/time.h>
|
|
|
|
#include <signal.h>
|
2005-04-22 13:11:34 +00:00
|
|
|
|
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.
(related to issue #12116)
........
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@105564 f38db490-d61c-443f-a65b-d21fe96a405b
2008-03-03 15:59:50 +00:00
|
|
|
#include "asterisk/_private.h" /* prototype for ast_autoservice_init() */
|
|
|
|
|
2005-04-21 06:02:45 +00:00
|
|
|
#include "asterisk/pbx.h"
|
|
|
|
#include "asterisk/frame.h"
|
|
|
|
#include "asterisk/sched.h"
|
|
|
|
#include "asterisk/channel.h"
|
|
|
|
#include "asterisk/file.h"
|
|
|
|
#include "asterisk/translate.h"
|
|
|
|
#include "asterisk/manager.h"
|
|
|
|
#include "asterisk/chanvars.h"
|
|
|
|
#include "asterisk/linkedlists.h"
|
|
|
|
#include "asterisk/indications.h"
|
|
|
|
#include "asterisk/lock.h"
|
|
|
|
#include "asterisk/utils.h"
|
2002-12-30 13:09:27 +00:00
|
|
|
|
2008-01-08 20:56:38 +00:00
|
|
|
#define MAX_AUTOMONS 1500
|
2002-12-30 13:09:27 +00:00
|
|
|
|
|
|
|
struct asent {
|
|
|
|
struct ast_channel *chan;
|
Merged revisions 89790 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r89790 | russell | 2007-11-27 15:45:51 -0600 (Tue, 27 Nov 2007) | 41 lines
Merge changes from team/russell/autoservice_1.4
This set of changes fixes an issue that was reported to me on IRC yesterday.
The user, d1mas, was using chan_zap for incoming calls and was having DTMF
recognition issues in some situations. Specifically, he noticed that the
problem occurred when using DISA or WaitExten. He also noticed that when
using Read, the problem did not occur. His system also used DUNDi for
dialplan lookups.
So, he theorized that if the DUNDi lookups blocked for some period of time,
that audio from the zap channel could get lost. If the audio got lost, then
it wouldn't be run through the DTMF detector, and digits could get lost.
He was correct, and the following set of changes fixes the problem. However,
the changes go a little bit further than what was necessary to fix this exact
problem.
1) I updated pbx_extension_helper() to autoservice the associated channel to
handle cases where extension lookups may take a long time. This would
normally be a dialplan switch that does some lookup over the network, such
as the DUNDi or IAX2 switches.
This ensures that even while a DUNDi lookup is blocking, the channel will be
continuously serviced.
2) I made a change to the autoservice code. This is actually something that
has bothered me for a long time. When a channel is in autoservice, _all_
frames get thrown away. However, some frames really shouldn't be thrown
away. The most notable examples are signalling (CONTROL) frames, and DTMF.
So, this patch queues up important frames while a channel is in autoservice.
When autoservice is stopped on the channel, the queued up frames get stuck
back on the channel so that they can get processed instead of thrown away.
3) I made another change to the autoservice code to handle the case where
autoservice is started on channels recursively.
Previously, you could call ast_autoservice_start() multiple times on a
channel, and it would stop the first time ast_autoservice_stop() gets
called. Now, it will ensure that autoservice doesn't actually stop until
the final call to ast_autoservice_stop().
........
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@89791 f38db490-d61c-443f-a65b-d21fe96a405b
2007-11-27 22:05:36 +00:00
|
|
|
/*! This gets incremented each time autoservice gets started on the same
|
|
|
|
* channel. It will ensure that it doesn't actually get stopped until
|
|
|
|
* it gets stopped for the last time. */
|
|
|
|
unsigned int use_count;
|
2007-12-26 19:09:17 +00:00
|
|
|
unsigned int orig_end_dtmf_flag:1;
|
2008-05-29 22:28:50 +00:00
|
|
|
AST_LIST_HEAD_NOLOCK(, ast_frame) deferred_frames;
|
2006-01-03 08:54:19 +00:00
|
|
|
AST_LIST_ENTRY(asent) list;
|
2002-12-30 13:09:27 +00:00
|
|
|
};
|
|
|
|
|
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.
(related to issue #12116)
........
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@105564 f38db490-d61c-443f-a65b-d21fe96a405b
2008-03-03 15:59:50 +00:00
|
|
|
static AST_LIST_HEAD_STATIC(aslist, asent);
|
|
|
|
static ast_cond_t as_cond;
|
2006-01-03 08:54:19 +00:00
|
|
|
|
2004-03-15 07:51:22 +00:00
|
|
|
static pthread_t asthread = AST_PTHREADT_NULL;
|
2002-12-30 13:09:27 +00:00
|
|
|
|
2008-02-29 23:36:46 +00:00
|
|
|
static int as_chan_list_state;
|
|
|
|
|
2007-12-07 16:11:00 +00:00
|
|
|
static void *autoservice_run(void *ign)
|
|
|
|
{
|
2007-01-23 00:11:32 +00:00
|
|
|
for (;;) {
|
2008-05-29 22:28:50 +00:00
|
|
|
struct ast_channel *mons[MAX_AUTOMONS];
|
|
|
|
struct asent *ents[MAX_AUTOMONS];
|
|
|
|
struct ast_channel *chan;
|
2006-02-15 01:38:20 +00:00
|
|
|
struct asent *as;
|
2008-05-29 22:28:50 +00:00
|
|
|
int i, x = 0, ms = 50;
|
|
|
|
struct ast_frame *f = NULL;
|
|
|
|
struct ast_frame *defer_frame = NULL;
|
2006-02-15 01:38:20 +00:00
|
|
|
|
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.
(related to issue #12116)
........
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@105564 f38db490-d61c-443f-a65b-d21fe96a405b
2008-03-03 15:59:50 +00:00
|
|
|
AST_LIST_LOCK(&aslist);
|
2008-02-29 23:36:46 +00:00
|
|
|
|
|
|
|
/* At this point, we know that no channels that have been removed are going
|
|
|
|
* to get used again. */
|
|
|
|
as_chan_list_state++;
|
|
|
|
|
2008-05-29 22:28:50 +00:00
|
|
|
if (AST_LIST_EMPTY(&aslist)) {
|
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.
(related to issue #12116)
........
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@105564 f38db490-d61c-443f-a65b-d21fe96a405b
2008-03-03 15:59:50 +00:00
|
|
|
ast_cond_wait(&as_cond, &aslist.lock);
|
2008-05-29 22:28:50 +00:00
|
|
|
}
|
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.
(related to issue #12116)
........
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@105564 f38db490-d61c-443f-a65b-d21fe96a405b
2008-03-03 15:59:50 +00:00
|
|
|
|
|
|
|
AST_LIST_TRAVERSE(&aslist, as, list) {
|
2007-08-01 15:39:54 +00:00
|
|
|
if (!ast_check_hangup(as->chan)) {
|
2008-05-29 22:28:50 +00:00
|
|
|
if (x < MAX_AUTOMONS) {
|
|
|
|
ents[x] = as;
|
2002-12-30 13:09:27 +00:00
|
|
|
mons[x++] = as->chan;
|
2008-05-29 22:28:50 +00:00
|
|
|
} else {
|
2002-12-30 13:09:27 +00:00
|
|
|
ast_log(LOG_WARNING, "Exceeded maximum number of automatic monitoring events. Fix autoservice.c\n");
|
2008-05-29 22:28:50 +00:00
|
|
|
}
|
2002-12-30 13:09:27 +00:00
|
|
|
}
|
|
|
|
}
|
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.
(related to issue #12116)
........
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@105564 f38db490-d61c-443f-a65b-d21fe96a405b
2008-03-03 15:59:50 +00:00
|
|
|
|
|
|
|
AST_LIST_UNLOCK(&aslist);
|
2002-12-30 13:09:27 +00:00
|
|
|
|
2008-06-13 21:45:21 +00:00
|
|
|
if (!x) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2008-05-29 22:28:50 +00:00
|
|
|
chan = ast_waitfor_n(mons, x, &ms);
|
|
|
|
if (!chan) {
|
|
|
|
continue;
|
|
|
|
}
|
2007-12-07 16:11:00 +00:00
|
|
|
|
2008-05-29 22:28:50 +00:00
|
|
|
f = ast_read(chan);
|
|
|
|
|
|
|
|
if (!f) {
|
|
|
|
struct ast_frame hangup_frame = { 0, };
|
|
|
|
/* No frame means the channel has been hung up.
|
|
|
|
* A hangup frame needs to be queued here as ast_waitfor() may
|
|
|
|
* never return again for the condition to be detected outside
|
|
|
|
* of autoservice. So, we'll leave a HANGUP queued up so the
|
|
|
|
* thread in charge of this channel will know. */
|
|
|
|
|
|
|
|
hangup_frame.frametype = AST_FRAME_CONTROL;
|
|
|
|
hangup_frame.subclass = AST_CONTROL_HANGUP;
|
|
|
|
|
|
|
|
defer_frame = &hangup_frame;
|
|
|
|
} else {
|
2007-12-07 16:11:00 +00:00
|
|
|
|
Merged revisions 89790 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r89790 | russell | 2007-11-27 15:45:51 -0600 (Tue, 27 Nov 2007) | 41 lines
Merge changes from team/russell/autoservice_1.4
This set of changes fixes an issue that was reported to me on IRC yesterday.
The user, d1mas, was using chan_zap for incoming calls and was having DTMF
recognition issues in some situations. Specifically, he noticed that the
problem occurred when using DISA or WaitExten. He also noticed that when
using Read, the problem did not occur. His system also used DUNDi for
dialplan lookups.
So, he theorized that if the DUNDi lookups blocked for some period of time,
that audio from the zap channel could get lost. If the audio got lost, then
it wouldn't be run through the DTMF detector, and digits could get lost.
He was correct, and the following set of changes fixes the problem. However,
the changes go a little bit further than what was necessary to fix this exact
problem.
1) I updated pbx_extension_helper() to autoservice the associated channel to
handle cases where extension lookups may take a long time. This would
normally be a dialplan switch that does some lookup over the network, such
as the DUNDi or IAX2 switches.
This ensures that even while a DUNDi lookup is blocking, the channel will be
continuously serviced.
2) I made a change to the autoservice code. This is actually something that
has bothered me for a long time. When a channel is in autoservice, _all_
frames get thrown away. However, some frames really shouldn't be thrown
away. The most notable examples are signalling (CONTROL) frames, and DTMF.
So, this patch queues up important frames while a channel is in autoservice.
When autoservice is stopped on the channel, the queued up frames get stuck
back on the channel so that they can get processed instead of thrown away.
3) I made another change to the autoservice code to handle the case where
autoservice is started on channels recursively.
Previously, you could call ast_autoservice_start() multiple times on a
channel, and it would stop the first time ast_autoservice_stop() gets
called. Now, it will ensure that autoservice doesn't actually stop until
the final call to ast_autoservice_stop().
........
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@89791 f38db490-d61c-443f-a65b-d21fe96a405b
2007-11-27 22:05:36 +00:00
|
|
|
/* Do not add a default entry in this switch statement. Each new
|
|
|
|
* frame type should be addressed directly as to whether it should
|
|
|
|
* be queued up or not. */
|
2008-05-29 22:28:50 +00:00
|
|
|
|
Merged revisions 89790 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r89790 | russell | 2007-11-27 15:45:51 -0600 (Tue, 27 Nov 2007) | 41 lines
Merge changes from team/russell/autoservice_1.4
This set of changes fixes an issue that was reported to me on IRC yesterday.
The user, d1mas, was using chan_zap for incoming calls and was having DTMF
recognition issues in some situations. Specifically, he noticed that the
problem occurred when using DISA or WaitExten. He also noticed that when
using Read, the problem did not occur. His system also used DUNDi for
dialplan lookups.
So, he theorized that if the DUNDi lookups blocked for some period of time,
that audio from the zap channel could get lost. If the audio got lost, then
it wouldn't be run through the DTMF detector, and digits could get lost.
He was correct, and the following set of changes fixes the problem. However,
the changes go a little bit further than what was necessary to fix this exact
problem.
1) I updated pbx_extension_helper() to autoservice the associated channel to
handle cases where extension lookups may take a long time. This would
normally be a dialplan switch that does some lookup over the network, such
as the DUNDi or IAX2 switches.
This ensures that even while a DUNDi lookup is blocking, the channel will be
continuously serviced.
2) I made a change to the autoservice code. This is actually something that
has bothered me for a long time. When a channel is in autoservice, _all_
frames get thrown away. However, some frames really shouldn't be thrown
away. The most notable examples are signalling (CONTROL) frames, and DTMF.
So, this patch queues up important frames while a channel is in autoservice.
When autoservice is stopped on the channel, the queued up frames get stuck
back on the channel so that they can get processed instead of thrown away.
3) I made another change to the autoservice code to handle the case where
autoservice is started on channels recursively.
Previously, you could call ast_autoservice_start() multiple times on a
channel, and it would stop the first time ast_autoservice_stop() gets
called. Now, it will ensure that autoservice doesn't actually stop until
the final call to ast_autoservice_stop().
........
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@89791 f38db490-d61c-443f-a65b-d21fe96a405b
2007-11-27 22:05:36 +00:00
|
|
|
switch (f->frametype) {
|
|
|
|
/* Save these frames */
|
|
|
|
case AST_FRAME_DTMF_END:
|
|
|
|
case AST_FRAME_CONTROL:
|
|
|
|
case AST_FRAME_TEXT:
|
|
|
|
case AST_FRAME_IMAGE:
|
|
|
|
case AST_FRAME_HTML:
|
2008-05-29 22:28:50 +00:00
|
|
|
defer_frame = f;
|
2007-12-07 16:11:00 +00:00
|
|
|
break;
|
Merged revisions 89790 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r89790 | russell | 2007-11-27 15:45:51 -0600 (Tue, 27 Nov 2007) | 41 lines
Merge changes from team/russell/autoservice_1.4
This set of changes fixes an issue that was reported to me on IRC yesterday.
The user, d1mas, was using chan_zap for incoming calls and was having DTMF
recognition issues in some situations. Specifically, he noticed that the
problem occurred when using DISA or WaitExten. He also noticed that when
using Read, the problem did not occur. His system also used DUNDi for
dialplan lookups.
So, he theorized that if the DUNDi lookups blocked for some period of time,
that audio from the zap channel could get lost. If the audio got lost, then
it wouldn't be run through the DTMF detector, and digits could get lost.
He was correct, and the following set of changes fixes the problem. However,
the changes go a little bit further than what was necessary to fix this exact
problem.
1) I updated pbx_extension_helper() to autoservice the associated channel to
handle cases where extension lookups may take a long time. This would
normally be a dialplan switch that does some lookup over the network, such
as the DUNDi or IAX2 switches.
This ensures that even while a DUNDi lookup is blocking, the channel will be
continuously serviced.
2) I made a change to the autoservice code. This is actually something that
has bothered me for a long time. When a channel is in autoservice, _all_
frames get thrown away. However, some frames really shouldn't be thrown
away. The most notable examples are signalling (CONTROL) frames, and DTMF.
So, this patch queues up important frames while a channel is in autoservice.
When autoservice is stopped on the channel, the queued up frames get stuck
back on the channel so that they can get processed instead of thrown away.
3) I made another change to the autoservice code to handle the case where
autoservice is started on channels recursively.
Previously, you could call ast_autoservice_start() multiple times on a
channel, and it would stop the first time ast_autoservice_stop() gets
called. Now, it will ensure that autoservice doesn't actually stop until
the final call to ast_autoservice_stop().
........
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@89791 f38db490-d61c-443f-a65b-d21fe96a405b
2007-11-27 22:05:36 +00:00
|
|
|
|
|
|
|
/* Throw these frames away */
|
2007-12-26 17:07:12 +00:00
|
|
|
case AST_FRAME_DTMF_BEGIN:
|
Merged revisions 89790 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r89790 | russell | 2007-11-27 15:45:51 -0600 (Tue, 27 Nov 2007) | 41 lines
Merge changes from team/russell/autoservice_1.4
This set of changes fixes an issue that was reported to me on IRC yesterday.
The user, d1mas, was using chan_zap for incoming calls and was having DTMF
recognition issues in some situations. Specifically, he noticed that the
problem occurred when using DISA or WaitExten. He also noticed that when
using Read, the problem did not occur. His system also used DUNDi for
dialplan lookups.
So, he theorized that if the DUNDi lookups blocked for some period of time,
that audio from the zap channel could get lost. If the audio got lost, then
it wouldn't be run through the DTMF detector, and digits could get lost.
He was correct, and the following set of changes fixes the problem. However,
the changes go a little bit further than what was necessary to fix this exact
problem.
1) I updated pbx_extension_helper() to autoservice the associated channel to
handle cases where extension lookups may take a long time. This would
normally be a dialplan switch that does some lookup over the network, such
as the DUNDi or IAX2 switches.
This ensures that even while a DUNDi lookup is blocking, the channel will be
continuously serviced.
2) I made a change to the autoservice code. This is actually something that
has bothered me for a long time. When a channel is in autoservice, _all_
frames get thrown away. However, some frames really shouldn't be thrown
away. The most notable examples are signalling (CONTROL) frames, and DTMF.
So, this patch queues up important frames while a channel is in autoservice.
When autoservice is stopped on the channel, the queued up frames get stuck
back on the channel so that they can get processed instead of thrown away.
3) I made another change to the autoservice code to handle the case where
autoservice is started on channels recursively.
Previously, you could call ast_autoservice_start() multiple times on a
channel, and it would stop the first time ast_autoservice_stop() gets
called. Now, it will ensure that autoservice doesn't actually stop until
the final call to ast_autoservice_stop().
........
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@89791 f38db490-d61c-443f-a65b-d21fe96a405b
2007-11-27 22:05:36 +00:00
|
|
|
case AST_FRAME_VOICE:
|
|
|
|
case AST_FRAME_VIDEO:
|
|
|
|
case AST_FRAME_NULL:
|
|
|
|
case AST_FRAME_IAX:
|
|
|
|
case AST_FRAME_CNG:
|
|
|
|
case AST_FRAME_MODEM:
|
|
|
|
break;
|
|
|
|
}
|
2008-05-29 22:28:50 +00:00
|
|
|
}
|
Merged revisions 89790 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r89790 | russell | 2007-11-27 15:45:51 -0600 (Tue, 27 Nov 2007) | 41 lines
Merge changes from team/russell/autoservice_1.4
This set of changes fixes an issue that was reported to me on IRC yesterday.
The user, d1mas, was using chan_zap for incoming calls and was having DTMF
recognition issues in some situations. Specifically, he noticed that the
problem occurred when using DISA or WaitExten. He also noticed that when
using Read, the problem did not occur. His system also used DUNDi for
dialplan lookups.
So, he theorized that if the DUNDi lookups blocked for some period of time,
that audio from the zap channel could get lost. If the audio got lost, then
it wouldn't be run through the DTMF detector, and digits could get lost.
He was correct, and the following set of changes fixes the problem. However,
the changes go a little bit further than what was necessary to fix this exact
problem.
1) I updated pbx_extension_helper() to autoservice the associated channel to
handle cases where extension lookups may take a long time. This would
normally be a dialplan switch that does some lookup over the network, such
as the DUNDi or IAX2 switches.
This ensures that even while a DUNDi lookup is blocking, the channel will be
continuously serviced.
2) I made a change to the autoservice code. This is actually something that
has bothered me for a long time. When a channel is in autoservice, _all_
frames get thrown away. However, some frames really shouldn't be thrown
away. The most notable examples are signalling (CONTROL) frames, and DTMF.
So, this patch queues up important frames while a channel is in autoservice.
When autoservice is stopped on the channel, the queued up frames get stuck
back on the channel so that they can get processed instead of thrown away.
3) I made another change to the autoservice code to handle the case where
autoservice is started on channels recursively.
Previously, you could call ast_autoservice_start() multiple times on a
channel, and it would stop the first time ast_autoservice_stop() gets
called. Now, it will ensure that autoservice doesn't actually stop until
the final call to ast_autoservice_stop().
........
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@89791 f38db490-d61c-443f-a65b-d21fe96a405b
2007-11-27 22:05:36 +00:00
|
|
|
|
2008-08-15 15:09:46 +00:00
|
|
|
if (defer_frame) {
|
2008-05-30 19:47:30 +00:00
|
|
|
for (i = 0; i < x; i++) {
|
|
|
|
struct ast_frame *dup_f;
|
|
|
|
|
|
|
|
if (mons[i] != chan) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2008-08-15 15:09:46 +00:00
|
|
|
if ((dup_f = ast_frdup(defer_frame))) {
|
2008-05-30 19:47:30 +00:00
|
|
|
AST_LIST_INSERT_TAIL(&ents[i]->deferred_frames, dup_f, frame_list);
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
2008-08-15 15:09:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (f) {
|
2008-05-29 22:28:50 +00:00
|
|
|
ast_frfree(f);
|
2002-12-30 13:09:27 +00:00
|
|
|
}
|
|
|
|
}
|
2007-06-12 14:16:37 +00:00
|
|
|
|
2004-03-15 07:51:22 +00:00
|
|
|
asthread = AST_PTHREADT_NULL;
|
2007-06-12 14:16:37 +00:00
|
|
|
|
2002-12-30 13:09:27 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
int ast_autoservice_start(struct ast_channel *chan)
|
|
|
|
{
|
2007-12-02 09:42:48 +00:00
|
|
|
int res = 0;
|
2002-12-30 13:09:27 +00:00
|
|
|
struct asent *as;
|
2007-01-23 00:16:55 +00:00
|
|
|
|
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.
(related to issue #12116)
........
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@105564 f38db490-d61c-443f-a65b-d21fe96a405b
2008-03-03 15:59:50 +00:00
|
|
|
AST_LIST_LOCK(&aslist);
|
|
|
|
AST_LIST_TRAVERSE(&aslist, as, list) {
|
Merged revisions 89790 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r89790 | russell | 2007-11-27 15:45:51 -0600 (Tue, 27 Nov 2007) | 41 lines
Merge changes from team/russell/autoservice_1.4
This set of changes fixes an issue that was reported to me on IRC yesterday.
The user, d1mas, was using chan_zap for incoming calls and was having DTMF
recognition issues in some situations. Specifically, he noticed that the
problem occurred when using DISA or WaitExten. He also noticed that when
using Read, the problem did not occur. His system also used DUNDi for
dialplan lookups.
So, he theorized that if the DUNDi lookups blocked for some period of time,
that audio from the zap channel could get lost. If the audio got lost, then
it wouldn't be run through the DTMF detector, and digits could get lost.
He was correct, and the following set of changes fixes the problem. However,
the changes go a little bit further than what was necessary to fix this exact
problem.
1) I updated pbx_extension_helper() to autoservice the associated channel to
handle cases where extension lookups may take a long time. This would
normally be a dialplan switch that does some lookup over the network, such
as the DUNDi or IAX2 switches.
This ensures that even while a DUNDi lookup is blocking, the channel will be
continuously serviced.
2) I made a change to the autoservice code. This is actually something that
has bothered me for a long time. When a channel is in autoservice, _all_
frames get thrown away. However, some frames really shouldn't be thrown
away. The most notable examples are signalling (CONTROL) frames, and DTMF.
So, this patch queues up important frames while a channel is in autoservice.
When autoservice is stopped on the channel, the queued up frames get stuck
back on the channel so that they can get processed instead of thrown away.
3) I made another change to the autoservice code to handle the case where
autoservice is started on channels recursively.
Previously, you could call ast_autoservice_start() multiple times on a
channel, and it would stop the first time ast_autoservice_stop() gets
called. Now, it will ensure that autoservice doesn't actually stop until
the final call to ast_autoservice_stop().
........
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@89791 f38db490-d61c-443f-a65b-d21fe96a405b
2007-11-27 22:05:36 +00:00
|
|
|
if (as->chan == chan) {
|
|
|
|
as->use_count++;
|
2002-12-30 13:09:27 +00:00
|
|
|
break;
|
Merged revisions 89790 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r89790 | russell | 2007-11-27 15:45:51 -0600 (Tue, 27 Nov 2007) | 41 lines
Merge changes from team/russell/autoservice_1.4
This set of changes fixes an issue that was reported to me on IRC yesterday.
The user, d1mas, was using chan_zap for incoming calls and was having DTMF
recognition issues in some situations. Specifically, he noticed that the
problem occurred when using DISA or WaitExten. He also noticed that when
using Read, the problem did not occur. His system also used DUNDi for
dialplan lookups.
So, he theorized that if the DUNDi lookups blocked for some period of time,
that audio from the zap channel could get lost. If the audio got lost, then
it wouldn't be run through the DTMF detector, and digits could get lost.
He was correct, and the following set of changes fixes the problem. However,
the changes go a little bit further than what was necessary to fix this exact
problem.
1) I updated pbx_extension_helper() to autoservice the associated channel to
handle cases where extension lookups may take a long time. This would
normally be a dialplan switch that does some lookup over the network, such
as the DUNDi or IAX2 switches.
This ensures that even while a DUNDi lookup is blocking, the channel will be
continuously serviced.
2) I made a change to the autoservice code. This is actually something that
has bothered me for a long time. When a channel is in autoservice, _all_
frames get thrown away. However, some frames really shouldn't be thrown
away. The most notable examples are signalling (CONTROL) frames, and DTMF.
So, this patch queues up important frames while a channel is in autoservice.
When autoservice is stopped on the channel, the queued up frames get stuck
back on the channel so that they can get processed instead of thrown away.
3) I made another change to the autoservice code to handle the case where
autoservice is started on channels recursively.
Previously, you could call ast_autoservice_start() multiple times on a
channel, and it would stop the first time ast_autoservice_stop() gets
called. Now, it will ensure that autoservice doesn't actually stop until
the final call to ast_autoservice_stop().
........
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@89791 f38db490-d61c-443f-a65b-d21fe96a405b
2007-11-27 22:05:36 +00:00
|
|
|
}
|
2002-12-30 13:09:27 +00:00
|
|
|
}
|
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.
(related to issue #12116)
........
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@105564 f38db490-d61c-443f-a65b-d21fe96a405b
2008-03-03 15:59:50 +00:00
|
|
|
AST_LIST_UNLOCK(&aslist);
|
2006-01-03 08:54:19 +00:00
|
|
|
|
2007-12-02 09:42:48 +00:00
|
|
|
if (as) {
|
2007-12-26 19:09:17 +00:00
|
|
|
/* Entry exists, autoservice is already handling this channel */
|
|
|
|
return 0;
|
2002-12-30 13:09:27 +00:00
|
|
|
}
|
Merged revisions 89790 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r89790 | russell | 2007-11-27 15:45:51 -0600 (Tue, 27 Nov 2007) | 41 lines
Merge changes from team/russell/autoservice_1.4
This set of changes fixes an issue that was reported to me on IRC yesterday.
The user, d1mas, was using chan_zap for incoming calls and was having DTMF
recognition issues in some situations. Specifically, he noticed that the
problem occurred when using DISA or WaitExten. He also noticed that when
using Read, the problem did not occur. His system also used DUNDi for
dialplan lookups.
So, he theorized that if the DUNDi lookups blocked for some period of time,
that audio from the zap channel could get lost. If the audio got lost, then
it wouldn't be run through the DTMF detector, and digits could get lost.
He was correct, and the following set of changes fixes the problem. However,
the changes go a little bit further than what was necessary to fix this exact
problem.
1) I updated pbx_extension_helper() to autoservice the associated channel to
handle cases where extension lookups may take a long time. This would
normally be a dialplan switch that does some lookup over the network, such
as the DUNDi or IAX2 switches.
This ensures that even while a DUNDi lookup is blocking, the channel will be
continuously serviced.
2) I made a change to the autoservice code. This is actually something that
has bothered me for a long time. When a channel is in autoservice, _all_
frames get thrown away. However, some frames really shouldn't be thrown
away. The most notable examples are signalling (CONTROL) frames, and DTMF.
So, this patch queues up important frames while a channel is in autoservice.
When autoservice is stopped on the channel, the queued up frames get stuck
back on the channel so that they can get processed instead of thrown away.
3) I made another change to the autoservice code to handle the case where
autoservice is started on channels recursively.
Previously, you could call ast_autoservice_start() multiple times on a
channel, and it would stop the first time ast_autoservice_stop() gets
called. Now, it will ensure that autoservice doesn't actually stop until
the final call to ast_autoservice_stop().
........
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@89791 f38db490-d61c-443f-a65b-d21fe96a405b
2007-11-27 22:05:36 +00:00
|
|
|
|
2007-12-26 19:09:17 +00:00
|
|
|
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);
|
|
|
|
ast_channel_unlock(chan);
|
|
|
|
|
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.
(related to issue #12116)
........
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@105564 f38db490-d61c-443f-a65b-d21fe96a405b
2008-03-03 15:59:50 +00:00
|
|
|
AST_LIST_LOCK(&aslist);
|
2008-05-13 21:07:59 +00:00
|
|
|
|
|
|
|
if (AST_LIST_EMPTY(&aslist) && asthread != AST_PTHREADT_NULL) {
|
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.
(related to issue #12116)
........
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@105564 f38db490-d61c-443f-a65b-d21fe96a405b
2008-03-03 15:59:50 +00:00
|
|
|
ast_cond_signal(&as_cond);
|
2008-05-13 21:07:59 +00:00
|
|
|
}
|
|
|
|
|
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.
(related to issue #12116)
........
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@105564 f38db490-d61c-443f-a65b-d21fe96a405b
2008-03-03 15:59:50 +00:00
|
|
|
AST_LIST_INSERT_HEAD(&aslist, as, list);
|
Merged revisions 89790 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r89790 | russell | 2007-11-27 15:45:51 -0600 (Tue, 27 Nov 2007) | 41 lines
Merge changes from team/russell/autoservice_1.4
This set of changes fixes an issue that was reported to me on IRC yesterday.
The user, d1mas, was using chan_zap for incoming calls and was having DTMF
recognition issues in some situations. Specifically, he noticed that the
problem occurred when using DISA or WaitExten. He also noticed that when
using Read, the problem did not occur. His system also used DUNDi for
dialplan lookups.
So, he theorized that if the DUNDi lookups blocked for some period of time,
that audio from the zap channel could get lost. If the audio got lost, then
it wouldn't be run through the DTMF detector, and digits could get lost.
He was correct, and the following set of changes fixes the problem. However,
the changes go a little bit further than what was necessary to fix this exact
problem.
1) I updated pbx_extension_helper() to autoservice the associated channel to
handle cases where extension lookups may take a long time. This would
normally be a dialplan switch that does some lookup over the network, such
as the DUNDi or IAX2 switches.
This ensures that even while a DUNDi lookup is blocking, the channel will be
continuously serviced.
2) I made a change to the autoservice code. This is actually something that
has bothered me for a long time. When a channel is in autoservice, _all_
frames get thrown away. However, some frames really shouldn't be thrown
away. The most notable examples are signalling (CONTROL) frames, and DTMF.
So, this patch queues up important frames while a channel is in autoservice.
When autoservice is stopped on the channel, the queued up frames get stuck
back on the channel so that they can get processed instead of thrown away.
3) I made another change to the autoservice code to handle the case where
autoservice is started on channels recursively.
Previously, you could call ast_autoservice_start() multiple times on a
channel, and it would stop the first time ast_autoservice_stop() gets
called. Now, it will ensure that autoservice doesn't actually stop until
the final call to ast_autoservice_stop().
........
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@89791 f38db490-d61c-443f-a65b-d21fe96a405b
2007-11-27 22:05:36 +00:00
|
|
|
|
2007-12-26 19:09:17 +00:00
|
|
|
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. */
|
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.
(related to issue #12116)
........
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@105564 f38db490-d61c-443f-a65b-d21fe96a405b
2008-03-03 15:59:50 +00:00
|
|
|
AST_LIST_REMOVE(&aslist, as, list);
|
2007-12-26 19:09:17 +00:00
|
|
|
free(as);
|
2008-05-13 21:07:59 +00:00
|
|
|
asthread = AST_PTHREADT_NULL;
|
2007-12-26 19:09:17 +00:00
|
|
|
res = -1;
|
2008-05-13 21:07:59 +00:00
|
|
|
} else {
|
2007-12-26 19:09:17 +00:00
|
|
|
pthread_kill(asthread, SIGURG);
|
2008-05-13 21:07:59 +00:00
|
|
|
}
|
2007-12-26 19:09:17 +00:00
|
|
|
}
|
|
|
|
|
2008-05-13 21:07:59 +00:00
|
|
|
AST_LIST_UNLOCK(&aslist);
|
|
|
|
|
2002-12-30 13:09:27 +00:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
int ast_autoservice_stop(struct ast_channel *chan)
|
|
|
|
{
|
|
|
|
int res = -1;
|
2008-05-29 22:28:50 +00:00
|
|
|
struct asent *as, *removed = NULL;
|
Merged revisions 89790 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r89790 | russell | 2007-11-27 15:45:51 -0600 (Tue, 27 Nov 2007) | 41 lines
Merge changes from team/russell/autoservice_1.4
This set of changes fixes an issue that was reported to me on IRC yesterday.
The user, d1mas, was using chan_zap for incoming calls and was having DTMF
recognition issues in some situations. Specifically, he noticed that the
problem occurred when using DISA or WaitExten. He also noticed that when
using Read, the problem did not occur. His system also used DUNDi for
dialplan lookups.
So, he theorized that if the DUNDi lookups blocked for some period of time,
that audio from the zap channel could get lost. If the audio got lost, then
it wouldn't be run through the DTMF detector, and digits could get lost.
He was correct, and the following set of changes fixes the problem. However,
the changes go a little bit further than what was necessary to fix this exact
problem.
1) I updated pbx_extension_helper() to autoservice the associated channel to
handle cases where extension lookups may take a long time. This would
normally be a dialplan switch that does some lookup over the network, such
as the DUNDi or IAX2 switches.
This ensures that even while a DUNDi lookup is blocking, the channel will be
continuously serviced.
2) I made a change to the autoservice code. This is actually something that
has bothered me for a long time. When a channel is in autoservice, _all_
frames get thrown away. However, some frames really shouldn't be thrown
away. The most notable examples are signalling (CONTROL) frames, and DTMF.
So, this patch queues up important frames while a channel is in autoservice.
When autoservice is stopped on the channel, the queued up frames get stuck
back on the channel so that they can get processed instead of thrown away.
3) I made another change to the autoservice code to handle the case where
autoservice is started on channels recursively.
Previously, you could call ast_autoservice_start() multiple times on a
channel, and it would stop the first time ast_autoservice_stop() gets
called. Now, it will ensure that autoservice doesn't actually stop until
the final call to ast_autoservice_stop().
........
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@89791 f38db490-d61c-443f-a65b-d21fe96a405b
2007-11-27 22:05:36 +00:00
|
|
|
struct ast_frame *f;
|
2008-02-29 23:36:46 +00:00
|
|
|
int chan_list_state;
|
Merged revisions 89790 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r89790 | russell | 2007-11-27 15:45:51 -0600 (Tue, 27 Nov 2007) | 41 lines
Merge changes from team/russell/autoservice_1.4
This set of changes fixes an issue that was reported to me on IRC yesterday.
The user, d1mas, was using chan_zap for incoming calls and was having DTMF
recognition issues in some situations. Specifically, he noticed that the
problem occurred when using DISA or WaitExten. He also noticed that when
using Read, the problem did not occur. His system also used DUNDi for
dialplan lookups.
So, he theorized that if the DUNDi lookups blocked for some period of time,
that audio from the zap channel could get lost. If the audio got lost, then
it wouldn't be run through the DTMF detector, and digits could get lost.
He was correct, and the following set of changes fixes the problem. However,
the changes go a little bit further than what was necessary to fix this exact
problem.
1) I updated pbx_extension_helper() to autoservice the associated channel to
handle cases where extension lookups may take a long time. This would
normally be a dialplan switch that does some lookup over the network, such
as the DUNDi or IAX2 switches.
This ensures that even while a DUNDi lookup is blocking, the channel will be
continuously serviced.
2) I made a change to the autoservice code. This is actually something that
has bothered me for a long time. When a channel is in autoservice, _all_
frames get thrown away. However, some frames really shouldn't be thrown
away. The most notable examples are signalling (CONTROL) frames, and DTMF.
So, this patch queues up important frames while a channel is in autoservice.
When autoservice is stopped on the channel, the queued up frames get stuck
back on the channel so that they can get processed instead of thrown away.
3) I made another change to the autoservice code to handle the case where
autoservice is started on channels recursively.
Previously, you could call ast_autoservice_start() multiple times on a
channel, and it would stop the first time ast_autoservice_stop() gets
called. Now, it will ensure that autoservice doesn't actually stop until
the final call to ast_autoservice_stop().
........
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@89791 f38db490-d61c-443f-a65b-d21fe96a405b
2007-11-27 22:05:36 +00:00
|
|
|
|
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.
(related to issue #12116)
........
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@105564 f38db490-d61c-443f-a65b-d21fe96a405b
2008-03-03 15:59:50 +00:00
|
|
|
AST_LIST_LOCK(&aslist);
|
2008-02-29 23:36:46 +00:00
|
|
|
|
|
|
|
/* 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
|
|
|
|
* could get destroyed and we don't want our poor autoservice thread to step on
|
|
|
|
* it after its gone! */
|
|
|
|
chan_list_state = as_chan_list_state;
|
|
|
|
|
2008-05-29 22:28:50 +00:00
|
|
|
/* Find the entry, but do not free it because it still can be in the
|
|
|
|
autoservice thread array */
|
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.
(related to issue #12116)
........
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@105564 f38db490-d61c-443f-a65b-d21fe96a405b
2008-03-03 15:59:50 +00:00
|
|
|
AST_LIST_TRAVERSE_SAFE_BEGIN(&aslist, as, list) {
|
2006-01-03 08:54:19 +00:00
|
|
|
if (as->chan == chan) {
|
Merged revisions 89790 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r89790 | russell | 2007-11-27 15:45:51 -0600 (Tue, 27 Nov 2007) | 41 lines
Merge changes from team/russell/autoservice_1.4
This set of changes fixes an issue that was reported to me on IRC yesterday.
The user, d1mas, was using chan_zap for incoming calls and was having DTMF
recognition issues in some situations. Specifically, he noticed that the
problem occurred when using DISA or WaitExten. He also noticed that when
using Read, the problem did not occur. His system also used DUNDi for
dialplan lookups.
So, he theorized that if the DUNDi lookups blocked for some period of time,
that audio from the zap channel could get lost. If the audio got lost, then
it wouldn't be run through the DTMF detector, and digits could get lost.
He was correct, and the following set of changes fixes the problem. However,
the changes go a little bit further than what was necessary to fix this exact
problem.
1) I updated pbx_extension_helper() to autoservice the associated channel to
handle cases where extension lookups may take a long time. This would
normally be a dialplan switch that does some lookup over the network, such
as the DUNDi or IAX2 switches.
This ensures that even while a DUNDi lookup is blocking, the channel will be
continuously serviced.
2) I made a change to the autoservice code. This is actually something that
has bothered me for a long time. When a channel is in autoservice, _all_
frames get thrown away. However, some frames really shouldn't be thrown
away. The most notable examples are signalling (CONTROL) frames, and DTMF.
So, this patch queues up important frames while a channel is in autoservice.
When autoservice is stopped on the channel, the queued up frames get stuck
back on the channel so that they can get processed instead of thrown away.
3) I made another change to the autoservice code to handle the case where
autoservice is started on channels recursively.
Previously, you could call ast_autoservice_start() multiple times on a
channel, and it would stop the first time ast_autoservice_stop() gets
called. Now, it will ensure that autoservice doesn't actually stop until
the final call to ast_autoservice_stop().
........
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@89791 f38db490-d61c-443f-a65b-d21fe96a405b
2007-11-27 22:05:36 +00:00
|
|
|
as->use_count--;
|
2008-05-29 22:28:50 +00:00
|
|
|
if (as->use_count < 1) {
|
|
|
|
AST_LIST_REMOVE_CURRENT(list);
|
|
|
|
removed = as;
|
|
|
|
}
|
2002-12-30 13:09:27 +00:00
|
|
|
break;
|
2006-01-03 08:54:19 +00:00
|
|
|
}
|
2002-12-30 13:09:27 +00:00
|
|
|
}
|
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.
(related to issue #12116)
........
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@105564 f38db490-d61c-443f-a65b-d21fe96a405b
2008-03-03 15:59:50 +00:00
|
|
|
AST_LIST_TRAVERSE_SAFE_END;
|
2006-01-03 08:54:19 +00:00
|
|
|
|
2008-05-29 22:28:50 +00:00
|
|
|
if (removed && asthread != AST_PTHREADT_NULL) {
|
2002-12-30 13:09:27 +00:00
|
|
|
pthread_kill(asthread, SIGURG);
|
2008-05-29 22:28:50 +00:00
|
|
|
}
|
|
|
|
|
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.
(related to issue #12116)
........
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@105564 f38db490-d61c-443f-a65b-d21fe96a405b
2008-03-03 15:59:50 +00:00
|
|
|
AST_LIST_UNLOCK(&aslist);
|
2006-01-03 08:54:19 +00:00
|
|
|
|
2008-05-29 22:28:50 +00:00
|
|
|
if (!removed) {
|
Merged revisions 89790 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r89790 | russell | 2007-11-27 15:45:51 -0600 (Tue, 27 Nov 2007) | 41 lines
Merge changes from team/russell/autoservice_1.4
This set of changes fixes an issue that was reported to me on IRC yesterday.
The user, d1mas, was using chan_zap for incoming calls and was having DTMF
recognition issues in some situations. Specifically, he noticed that the
problem occurred when using DISA or WaitExten. He also noticed that when
using Read, the problem did not occur. His system also used DUNDi for
dialplan lookups.
So, he theorized that if the DUNDi lookups blocked for some period of time,
that audio from the zap channel could get lost. If the audio got lost, then
it wouldn't be run through the DTMF detector, and digits could get lost.
He was correct, and the following set of changes fixes the problem. However,
the changes go a little bit further than what was necessary to fix this exact
problem.
1) I updated pbx_extension_helper() to autoservice the associated channel to
handle cases where extension lookups may take a long time. This would
normally be a dialplan switch that does some lookup over the network, such
as the DUNDi or IAX2 switches.
This ensures that even while a DUNDi lookup is blocking, the channel will be
continuously serviced.
2) I made a change to the autoservice code. This is actually something that
has bothered me for a long time. When a channel is in autoservice, _all_
frames get thrown away. However, some frames really shouldn't be thrown
away. The most notable examples are signalling (CONTROL) frames, and DTMF.
So, this patch queues up important frames while a channel is in autoservice.
When autoservice is stopped on the channel, the queued up frames get stuck
back on the channel so that they can get processed instead of thrown away.
3) I made another change to the autoservice code to handle the case where
autoservice is started on channels recursively.
Previously, you could call ast_autoservice_start() multiple times on a
channel, and it would stop the first time ast_autoservice_stop() gets
called. Now, it will ensure that autoservice doesn't actually stop until
the final call to ast_autoservice_stop().
........
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@89791 f38db490-d61c-443f-a65b-d21fe96a405b
2007-11-27 22:05:36 +00:00
|
|
|
return 0;
|
2008-05-29 22:28:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Wait while autoservice thread rebuilds its list. */
|
|
|
|
while (chan_list_state == as_chan_list_state) {
|
|
|
|
usleep(1000);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Now autoservice thread should have no references to our entry
|
|
|
|
and we can safely destroy it */
|
|
|
|
|
|
|
|
if (!chan->_softhangup) {
|
|
|
|
res = 0;
|
|
|
|
}
|
Merged revisions 89790 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r89790 | russell | 2007-11-27 15:45:51 -0600 (Tue, 27 Nov 2007) | 41 lines
Merge changes from team/russell/autoservice_1.4
This set of changes fixes an issue that was reported to me on IRC yesterday.
The user, d1mas, was using chan_zap for incoming calls and was having DTMF
recognition issues in some situations. Specifically, he noticed that the
problem occurred when using DISA or WaitExten. He also noticed that when
using Read, the problem did not occur. His system also used DUNDi for
dialplan lookups.
So, he theorized that if the DUNDi lookups blocked for some period of time,
that audio from the zap channel could get lost. If the audio got lost, then
it wouldn't be run through the DTMF detector, and digits could get lost.
He was correct, and the following set of changes fixes the problem. However,
the changes go a little bit further than what was necessary to fix this exact
problem.
1) I updated pbx_extension_helper() to autoservice the associated channel to
handle cases where extension lookups may take a long time. This would
normally be a dialplan switch that does some lookup over the network, such
as the DUNDi or IAX2 switches.
This ensures that even while a DUNDi lookup is blocking, the channel will be
continuously serviced.
2) I made a change to the autoservice code. This is actually something that
has bothered me for a long time. When a channel is in autoservice, _all_
frames get thrown away. However, some frames really shouldn't be thrown
away. The most notable examples are signalling (CONTROL) frames, and DTMF.
So, this patch queues up important frames while a channel is in autoservice.
When autoservice is stopped on the channel, the queued up frames get stuck
back on the channel so that they can get processed instead of thrown away.
3) I made another change to the autoservice code to handle the case where
autoservice is started on channels recursively.
Previously, you could call ast_autoservice_start() multiple times on a
channel, and it would stop the first time ast_autoservice_stop() gets
called. Now, it will ensure that autoservice doesn't actually stop until
the final call to ast_autoservice_stop().
........
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@89791 f38db490-d61c-443f-a65b-d21fe96a405b
2007-11-27 22:05:36 +00:00
|
|
|
|
2008-05-29 22:28:50 +00:00
|
|
|
if (!as->orig_end_dtmf_flag) {
|
2007-12-26 19:09:17 +00:00
|
|
|
ast_clear_flag(chan, AST_FLAG_END_DTMF_ONLY);
|
2008-05-29 22:28:50 +00:00
|
|
|
}
|
2007-12-26 19:09:17 +00:00
|
|
|
|
2008-05-29 22:28:50 +00:00
|
|
|
while ((f = AST_LIST_REMOVE_HEAD(&as->deferred_frames, frame_list))) {
|
Merged revisions 89790 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r89790 | russell | 2007-11-27 15:45:51 -0600 (Tue, 27 Nov 2007) | 41 lines
Merge changes from team/russell/autoservice_1.4
This set of changes fixes an issue that was reported to me on IRC yesterday.
The user, d1mas, was using chan_zap for incoming calls and was having DTMF
recognition issues in some situations. Specifically, he noticed that the
problem occurred when using DISA or WaitExten. He also noticed that when
using Read, the problem did not occur. His system also used DUNDi for
dialplan lookups.
So, he theorized that if the DUNDi lookups blocked for some period of time,
that audio from the zap channel could get lost. If the audio got lost, then
it wouldn't be run through the DTMF detector, and digits could get lost.
He was correct, and the following set of changes fixes the problem. However,
the changes go a little bit further than what was necessary to fix this exact
problem.
1) I updated pbx_extension_helper() to autoservice the associated channel to
handle cases where extension lookups may take a long time. This would
normally be a dialplan switch that does some lookup over the network, such
as the DUNDi or IAX2 switches.
This ensures that even while a DUNDi lookup is blocking, the channel will be
continuously serviced.
2) I made a change to the autoservice code. This is actually something that
has bothered me for a long time. When a channel is in autoservice, _all_
frames get thrown away. However, some frames really shouldn't be thrown
away. The most notable examples are signalling (CONTROL) frames, and DTMF.
So, this patch queues up important frames while a channel is in autoservice.
When autoservice is stopped on the channel, the queued up frames get stuck
back on the channel so that they can get processed instead of thrown away.
3) I made another change to the autoservice code to handle the case where
autoservice is started on channels recursively.
Previously, you could call ast_autoservice_start() multiple times on a
channel, and it would stop the first time ast_autoservice_stop() gets
called. Now, it will ensure that autoservice doesn't actually stop until
the final call to ast_autoservice_stop().
........
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@89791 f38db490-d61c-443f-a65b-d21fe96a405b
2007-11-27 22:05:36 +00:00
|
|
|
ast_queue_frame(chan, f);
|
|
|
|
ast_frfree(f);
|
|
|
|
}
|
|
|
|
|
2008-05-29 22:28:50 +00:00
|
|
|
free(as);
|
2008-02-29 23:36:46 +00:00
|
|
|
|
2002-12-30 13:09:27 +00:00
|
|
|
return res;
|
|
|
|
}
|
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.
(related to issue #12116)
........
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@105564 f38db490-d61c-443f-a65b-d21fe96a405b
2008-03-03 15:59:50 +00:00
|
|
|
|
|
|
|
void ast_autoservice_init(void)
|
|
|
|
{
|
|
|
|
ast_cond_init(&as_cond, NULL);
|
|
|
|
}
|