[Asterisk-Dev] Re: Fundamental locking (race/deadlock) problem in
ast_hangup()
Tony Mountifield
tony at softins.clara.co.uk
Fri Aug 26 07:03:19 MST 2005
In article <200508261545.55792.hselasky at c2i.net>,
Hans Petter Selasky <hselasky at c2i.net> wrote:
> 2) The lock in "struct ast_channel" must go away. Instead there must be:
>
> struct ast_channel {
> struct ast_mutex *priv_lock; // the lock that protects the channel driver
The above suggests priv_lock is per-channel...
> struct ast_mutex *ast_lock; // the lock that is used by Asterisk
> u_int8_t refcount; // structure reference count
> u_int8_t present; // set if hangup has not been called
> ...
> };
>
> 3) The locking order is defined like this.
>
> chan->priv_lock first
> chan->ast_lock second
>
>
> 4) In the channel driver:
>
> lock(priv_lock);
But this suggests priv_lock is global to all channels. Which is it?
> chan = lookup ast_channel in list;
>
> lock(chan->ast_lock);
>
> call a Asterisk callback ;
>
> // if this is hangup
> // {
> // chan->present = 0;
> // chan->refcount--;
> // }
> //
>
> refcount = chan->refcount;
>
> unlock(chan->ast_lock);
>
> if(refcount == 0)
> {
> free(chan);
> }
>
> unlock(priv_lock);
As does this.
> Comment to 4):
>
> In this scheme it is important that the channel driver has its lock locked
> from it looks up "struct ast_channel", and until after that Asterisk has been
> called, if that is needed.
>
>
> 5) In asterisk:
>
> lock(ast_lock);
>
> chan = lookup ast_channel in list;
>
> chan->refcount++;
>
> unlock(ast_lock);
>
> // NOTE: if we sleep here, and 4) calls hangup
> // chan->present will be set to 0 !
> //
>
> lock(chan->priv_mtx);
What's priv_mtx? A typo for priv_lock?
Cheers
Tony
--
Tony Mountifield
Work: tony at softins.co.uk - http://www.softins.co.uk
Play: tony at mountifield.org - http://tony.mountifield.org
More information about the asterisk-dev
mailing list