[asterisk-dev] Astobj2 and locks

Russell Bryant russell at digium.com
Wed Sep 12 19:24:15 CDT 2007


Watkins, Bradley wrote:
> But here is a snippet from app_queue.c in branches/1.4:
> 
> mem_iter = ao2_iterator_init(q->members, 0);
> while ((m = ao2_iterator_next(&mem_iter))) {
> 	q->membercount++;
> 	if (m->realtime)
> 	m->dead = 1;
> 	ao2_ref(m, -1);
> }
> 
> 
> I would expect (based on my cursory glance at the implementation in
> astobj2.c) that it should look something like:
> 
> mem_iter = ao2_iterator_init(q->members, 0);
> while ((m = ao2_iterator_next(&mem_iter))) {
> 	q->membercount++;
> 	if (m->realtime) {
> 		if(ao2_lock(m)) {
> 			m->dead = 1;
> 			ao2_unlock(m);
> 		}
> 	}
> 	ao2_ref(m, -1);
> }
> 
> 
> 
> Do I have it all wrong somehow?  And if so, please educate me as to how
> so that I may be enlightened.

It comes down to understanding exactly when and why the locking is required.  In
some places in Asterisk, locks are used (and sometimes abused) to ensure that
the object we're looking at doesn't disappear.  However, in this case, the
object has a reference count, and we currently hold a reference, so we know that
it will not disappear.

The lock for the member struct is still required in some situations, when you
need to protect certain elements of the member from changing while you're
working with them.  In this case, there is no possibility for something to
change in the member that could cause this code to break.  Thus, no locking is
required.

-- 
Russell Bryant
Software Engineer
Digium, Inc.



More information about the asterisk-dev mailing list