[Asterisk-Dev] Signal timing can bring down Asterisk

Kristian Nielsen kn at sifira.dk
Tue Aug 16 04:19:36 MST 2005


Hans Petter Selasky <hselasky at c2i.net> writes:

> On Tuesday 16 August 2005 11:15, Kristian Nielsen wrote:

> There is no ast_wait() in my source code, asterisk 1.0 according to the 
> manpage. But there is ast_waitfor().

Right, I meant any of the functions starting with ast_wait... But do
note that I am talking about Asterisk CVS HEAD (which will become v1.2),
I believe there are some differences as compared to v1.0, which I
haven't really worked with.

> But the thing is, that when I have a call coming from CAPI or ISDN, I setup an 
> "ast_channel", then I call "ast_pbx_start()" and that function will setup a 
> _new_ _thread_ that will listen for Asterisk frames and then call 
> "tech->read()" and "tech->write()". But I have another thread waiting for 
> messages from the CAPI interface, "/dev/capi20", and these two threads will 
> race for "ast_hangup" or "ast_softhangup" !

This is your misunderstanding. Your CAPI thread must not call
ast_hangup() or ast_softhangup().

The two threads may race for the HANGUP event, but that only means that
you must be prepared to handle multiple hangup events (at least one from
each end) simultaneously. Your CAPI thread must NOT call ast_hangup(),
call your channel tech->hangup() callback, or otherwise cause the struct
ast_channel() to become invalid. That is solely the job of the
ast_pbx_start() thread. Once the ast_pbx_start() thread calls your
tech->hangup() callback, you must lock your global list of active
channels, disconnect the channel from the list, unlock the global
channel list, and only then return from tech->hangup() after which the
struct ast_channel * will be deallocated. After that the CAPI thread
might get a signal, lock the global channel list and look for an
associated channel, but it will not find it and thus should discard the
stray event.

To put it another way, the struct ast_channel * is owned by the
ast_pbx_start() thread, and your CAPI thread must not invalidate it, nor
access it after it has been invalidated.

So yes, your CAPI thread and your tech->hangup() callback need to
synchronize with a global mutex in your channel driver. But there is no
race in ast_hangup(), since it is only called in the ast_pbx_start()
thread, and only once.

Hope this helps,

 - Kristian.

-- 
Kristian Nielsen   kn at sifira.dk
Development Manager, Sifira A/S




More information about the asterisk-dev mailing list