Posted: Fri May 29, 2009 1:05 pm Post subject: [asterisk-dev] AST_FRAME_NULL - what is it?
We are running a simple custom application on Asterisk 1.6.1, which
basically waits for a DTMF digit to be entered by the user.
Our code is basically like this:
struct ast_frame *frame;
while (true) {
ast_waitfor(channel, -1);
frame = ast_read(channel);
// Exit if hung up
if (frame->frametype == AST_FRAME_CONTROL) && (f->subclass ==
AST_CONTROL_HANGUP)) {
ast_frfree(frame);
return;
}
if (frame->frametype == AST_FRAME_DTMF) {
// .. Do the thing we need with the digit ...
ast_frfree(frame);
return;
}
// Ignore the frame, it's not a DTMF digit.
ast_frfree(frame);
}
Most of our clients are SIP clients, and this loop ends up ignoring a
few hundred frames before the user enters a digit. That's fine. But
some of our SIP clients, when they execute this, end up throwing us
around 150,000 AST_FRAME_NULL's, which this little loop has to ignore.
I don't know why Asterisk is sending us the AST_FRAME_NULL's or what
it's supposed to mean, but, our CPU is getting pegged from having to
process and ignore all those frames. CPU is NOT pegged when a SIP
client connects which is not sending us these null frames.
Can anyone please advise why this is happening, and how we can get it
to stop?
_______________________________________________
--Bandwidth and Colocation Provided by http://www.api-digital.com--
Posted: Fri May 29, 2009 2:22 pm Post subject: [asterisk-dev] AST_FRAME_NULL - what is it?
Quote:
I don't know why Asterisk is sending us the AST_FRAME_NULL's or what
it's supposed to mean, but, our CPU is getting pegged from having to
process and ignore all those frames. CPU is NOT pegged when a SIP
client connects which is not sending us these null frames.
Can anyone please advise why this is happening, and how we can get it
to stop?
I think someone is holding that channel lock and then you're calling
ast_read from your thread which is causing ast_read to return a null
frame because it cannot take the lock (check main/channel.c in
function __ast_read()). If that't the case you need to find who is
locking that channel and not releasing it.
Can you reproduce this easily? You should dive into main/channel.c and
channels/chan_sip.c to check who's returning that frame.
--
Moises Silva
Software Developer
Sangoma Technologies Inc. | 50 McIntosh Drive, Suite 120, Markham ON
L3R 9T3 Canada
t. 1 905 474 1990 x 128 | e. moy@sangoma.com
_______________________________________________
--Bandwidth and Colocation Provided by http://www.api-digital.com--
Posted: Fri May 29, 2009 2:55 pm Post subject: [asterisk-dev] AST_FRAME_NULL - what is it?
Thanks Moises,
That makes sense. Even before I dive in to the code to try to find out
*what* is hanging on to the channel lock, is there some coding
technique I can apply to my code, to correctly wait for the lock, and/
or yield to other threads, before I call ast_read, so that I can be
certain I won't get a AST_FRAME_NULL in return?
On May 29, 2009, at 8:09 AM, Moises Silva wrote:
Quote:
I don't know why Asterisk is sending us the AST_FRAME_NULL's or what
it's supposed to mean, but, our CPU is getting pegged from having to
process and ignore all those frames. CPU is NOT pegged when a SIP
client connects which is not sending us these null frames.
Can anyone please advise why this is happening, and how we can get it
to stop?
I think someone is holding that channel lock and then you're calling
ast_read from your thread which is causing ast_read to return a null
frame because it cannot take the lock (check main/channel.c in
function __ast_read()). If that't the case you need to find who is
locking that channel and not releasing it.
Can you reproduce this easily? You should dive into main/channel.c and
channels/chan_sip.c to check who's returning that frame.
--
Moises Silva
Software Developer
Sangoma Technologies Inc. | 50 McIntosh Drive, Suite 120, Markham ON
L3R 9T3 Canada
t. 1 905 474 1990 x 128 | e. moy@sangoma.com
_______________________________________________
--Bandwidth and Colocation Provided by http://www.api-digital.com--
Posted: Fri May 29, 2009 3:24 pm Post subject: [asterisk-dev] AST_FRAME_NULL - what is it?
Quote:
That makes sense. Even before I dive in to the code to try to find out
*what* is hanging on to the channel lock, is there some coding
technique I can apply to my code, to correctly wait for the lock, and/
or yield to other threads, before I call ast_read, so that I can be
certain I won't get a AST_FRAME_NULL in return?
ast_channel_lock(chan) will block until it can get the lock, so if you
use that before reading you are certain ast_read will get it as well
(mutex in Asterisk are recursive). However you have not even confirmed
that my guess (ast_read not being able to get the lock) is true, first
I think you should confirm that. If you are developing also be sure to
compile Asterisk as follows
then you have cli commands such core show locks, core show threads
etc, grep those options in Asterisk source code for more info about
what they do. AFAIR DEBUG_CHANNEL_LOCKS will give you enough info
about who is holding the lock and where was taken.
--
Moises Silva
Software Developer
Sangoma Technologies Inc. | 50 McIntosh Drive, Suite 120, Markham ON
L3R 9T3 Canada
t. 1 905 474 1990 x 128 | e. moy@sangoma.com
_______________________________________________
--Bandwidth and Colocation Provided by http://www.api-digital.com--
Posted: Fri May 29, 2009 4:01 pm Post subject: [asterisk-dev] AST_FRAME_NULL - what is it?
On Friday 29 May 2009 11:08:59 Moises Silva wrote:
Quote:
> That makes sense. Even before I dive in to the code to try to find out
> *what* is hanging on to the channel lock, is there some coding
> technique I can apply to my code, to correctly wait for the lock, and/
> or yield to other threads, before I call ast_read, so that I can be
> certain I won't get a AST_FRAME_NULL in return?
ast_channel_lock(chan) will block until it can get the lock, so if you
use that before reading you are certain ast_read will get it as well
(mutex in Asterisk are recursive). However you have not even confirmed
that my guess (ast_read not being able to get the lock) is true, first
I think you should confirm that. If you are developing also be sure to
compile Asterisk as follows
then you have cli commands such core show locks, core show threads
etc, grep those options in Asterisk source code for more info about
what they do. AFAIR DEBUG_CHANNEL_LOCKS will give you enough info
about who is holding the lock and where was taken.
One additional caveat -- make sure you aren't holding any locks when you
call ast_channel_lock or you may initiate a deadlock situation.
DEBUG_CHANNEL_LOCKS is NOT what you want; rather, you want DEBUG_THREADS,
as this enables the CLI command "core show locks", which will show you all
locks presently held at a snapshot in time.
--
Tilghman
_______________________________________________
--Bandwidth and Colocation Provided by http://www.api-digital.com--
Posted: Fri May 29, 2009 4:17 pm Post subject: [asterisk-dev] AST_FRAME_NULL - what is it?
Thanks Tilghman and Moises for your advice,
Before I got your message about calling ast_channel_lock, I added the
following code and it seems to relieve the symptoms by a large factor
(not quite 100%, but maybe by 98%):
if (frame->frametype == AST_FRAME_NULL) {
// yield
usleep(1);
}
Do you see anything wrong with this approach which I might pay for
down the road?
On May 29, 2009, at 9:42 AM, Tilghman Lesher wrote:
On Friday 29 May 2009 11:08:59 Moises Silva wrote:
Quote:
> That makes sense. Even before I dive in to the code to try to find
> out
> *what* is hanging on to the channel lock, is there some coding
> technique I can apply to my code, to correctly wait for the lock,
> and/
> or yield to other threads, before I call ast_read, so that I can be
> certain I won't get a AST_FRAME_NULL in return?
ast_channel_lock(chan) will block until it can get the lock, so if you
use that before reading you are certain ast_read will get it as well
(mutex in Asterisk are recursive). However you have not even confirmed
that my guess (ast_read not being able to get the lock) is true, first
I think you should confirm that. If you are developing also be sure to
compile Asterisk as follows
then you have cli commands such core show locks, core show threads
etc, grep those options in Asterisk source code for more info about
what they do. AFAIR DEBUG_CHANNEL_LOCKS will give you enough info
about who is holding the lock and where was taken.
One additional caveat -- make sure you aren't holding any locks when you
call ast_channel_lock or you may initiate a deadlock situation.
DEBUG_CHANNEL_LOCKS is NOT what you want; rather, you want
DEBUG_THREADS,
as this enables the CLI command "core show locks", which will show you
all
locks presently held at a snapshot in time.
--
Tilghman
_______________________________________________
--Bandwidth and Colocation Provided by http://www.api-digital.com--
Posted: Fri May 29, 2009 4:35 pm Post subject: [asterisk-dev] AST_FRAME_NULL - what is it?
Quote:
if (frame->frametype == AST_FRAME_NULL) {
// yield
usleep(1);
}
Do you see anything wrong with this approach which I might pay for
down the road?
Other than the ugliness? :-)
I just think ideally you should find the root cause of those null
frames, since they are likely a symptom of something going wrong
somewhere else, but it's up to you.
--
Moises Silva
Software Developer
Sangoma Technologies Inc. | 50 McIntosh Drive, Suite 120, Markham ON
L3R 9T3 Canada
t. 1 905 474 1990 x 128 | e. moy@sangoma.com
_______________________________________________
--Bandwidth and Colocation Provided by http://www.api-digital.com--
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum