[Asterisk-Dev] Signal timing can bring down Asterisk

Hans Petter Selasky hselasky at c2i.net
Tue Aug 16 09:18:22 MST 2005


On Tuesday 16 August 2005 15:20, Kristian Nielsen wrote:
> Armin Schindler <armin at melware.de> writes:
> > What is the problem by calling ast_hangup()? Many channel drivers do call
> > ast_hangup() in their own (additional) threads when an event like
> > hangup occurs.
>
> Well I could be wrong :-). I just had the impression that it was the
> responsibility of the one who called ast_request() to also call
> ast_hangup() at the end.
>
> > If ast_hangup() is wrong, how should the event of a hangup shall be
> > signaled to the pbx ?
>
> I would think that the proper way would be to return a
> AST_CONTROL_HANGUP control packet from the tech->read() callback, or
> alternatively to queue one using ast_queue_frame(). The latter is
> actually what ast_softhangup() does.

Yes, this is going to work. But there still is a problem, and that is that one 
has to wakeup the thread that is started by "ast_start_pbx", and this is 
usually done by writing some dummy data to the alertpipe. Now, what happens 
when this call is gone? One will either write some dummy data to a closed 
file number, or one will write dummy data to the next file, pipe or socket 
opened! So the problem is not solved! At some point one has got to touch 
"struct ast_channel" ?

But, if you add a refcount and a pointer to "struct ast_channel" in "struct 
ast_mutex", it will not be any problem at all to call "ast_xxx" from many 
threads at the same time!


But can you explain this: Why is asterisk setting up one thread for each call. 
Is this just because it is too difficult to implement some kind of callback 
mechanism? I did some testing on my computer, and it showed that I could not 
create more than around 500 pipes. So Asterisk is limited to 500/2 
simultaneous calls, because every "ast_channel" needs at least one file 
number that can be used for polling. That is not very much, if no DSP 
processing is done. So I suggest that you use that locking mechanism I 
explained in one of my previous mails, to make sure that one is not accessing 
freed data, and then send data directly from the receiver to the transmitter, 
maybe through some kind of function. And then have some kind of timer to 
clean up the call if there is no data for 8 seconds.

It is much faster to make a function call, than to wakeup a thread !

Any comments ?


Thanks for clearing things up. Summed up: it is not allowed to read or write 
"ast_channel" unless one is in the thread that "ast_start_pbx" has started. 
So now I have to make a framework that can send commands to this thread to 
set/clear things in "struct ast_channel". But actually it would be much 
simpler if one could access "struct ast_channel" outside this thread, which 
is not very impossible.


--HPS



More information about the asterisk-dev mailing list