[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