[asterisk-commits] russell: branch russell/chan_refcount r82330 - in /team/russell/chan_refcount...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Thu Sep 13 12:41:24 CDT 2007
Author: russell
Date: Thu Sep 13 12:41:24 2007
New Revision: 82330
URL: http://svn.digium.com/view/asterisk?view=rev&rev=82330
Log:
As rizzo pointed out on the asterisk-dev list, due to the fact that we use
recursive locks, ao2_lock_both() should be implemented with the trylock/sleep
loop to protect against the case where the thread already holds one of the
locks. Also, just remove unlock_both(), since it doesn't do anything useful.
Modified:
team/russell/chan_refcount/include/asterisk/astobj2.h
team/russell/chan_refcount/include/asterisk/channel.h
team/russell/chan_refcount/main/astobj2.c
Modified: team/russell/chan_refcount/include/asterisk/astobj2.h
URL: http://svn.digium.com/view/asterisk/team/russell/chan_refcount/include/asterisk/astobj2.h?view=diff&rev=82330&r1=82329&r2=82330
==============================================================================
--- team/russell/chan_refcount/include/asterisk/astobj2.h (original)
+++ team/russell/chan_refcount/include/asterisk/astobj2.h Thu Sep 13 12:41:24 2007
@@ -198,10 +198,8 @@
* \param obj1 a pointer to the first object to lock
* \param obj2 a pointer to the second object to lock
*
- * This function should be used in all cases where two objects need to be
- * locked at the same time. It avoids deadlocks by ensuring the same locking
- * order is always used, by locking the object with a lower pointer address
- * first.
+ * This function should be used in cases where two objects need to be
+ * locked at the same time. It will attempt to avoid a deadlock.
*
* \return 0 on success, other values on error
*/
@@ -223,20 +221,6 @@
* \return 0 on success, other values on error.
*/
int ao2_unlock(void *a);
-
-/*!
- * \brief Unlock two objects.
- *
- * \param obj1 a pointer to the first object to lock
- * \param obj2 a pointer to the second object to lock
- *
- * This function can be used with ao2_lock_both, but isn't necessarily
- * required, as the order in which objects are unlocked is not as important
- * as the order in which they are locked.
- *
- * \return 0 on success, other values on error
- */
-int ao2_unlock_both(void *obj1, void *obj2);
/*!
*
Modified: team/russell/chan_refcount/include/asterisk/channel.h
URL: http://svn.digium.com/view/asterisk/team/russell/chan_refcount/include/asterisk/channel.h?view=diff&rev=82330&r1=82329&r2=82330
==============================================================================
--- team/russell/chan_refcount/include/asterisk/channel.h (original)
+++ team/russell/chan_refcount/include/asterisk/channel.h Thu Sep 13 12:41:24 2007
@@ -1488,7 +1488,6 @@
#define ast_channel_trylock(c) ao2_trylock(c)
#define ast_channel_lock_both(c1, c2) ao2_lock_both(c1, c2)
-#define ast_channel_unlock_both(c1, c2) ao2_unlock_both(c1, c2)
static force_inline struct ast_channel *ast_channel_ref(struct ast_channel *chan)
{
Modified: team/russell/chan_refcount/main/astobj2.c
URL: http://svn.digium.com/view/asterisk/team/russell/chan_refcount/main/astobj2.c?view=diff&rev=82330&r1=82329&r2=82330
==============================================================================
--- team/russell/chan_refcount/main/astobj2.c (original)
+++ team/russell/chan_refcount/main/astobj2.c Thu Sep 13 12:41:24 2007
@@ -140,22 +140,13 @@
int ao2_lock_both(void *user_data1, void *user_data2)
{
- struct astobj2 *p1, *p2;
int res;
- p1 = INTERNAL_OBJ(MIN(user_data1, user_data2));
- p2 = INTERNAL_OBJ(MAX(user_data1, user_data2));
-
- res = ast_mutex_lock(&p1->priv_data.lock);
- if (!res) {
-#ifdef AO2_DEBUG
- ast_atomic_fetchadd_int(&ao2.total_locked, 1);
-#endif
- res = ast_mutex_lock(&p2->priv_data.lock);
-#ifdef AO2_DEBUG
- if (!res)
- ast_atomic_fetchadd_int(&ao2.total_locked, 1);
-#endif
+ res = ao2_lock(user_data1);
+ while (!res && ao2_trylock(user_data2)) {
+ ao2_unlock(user_data1);
+ usleep(1);
+ res = ao2_lock(user_data1);
}
return res;
@@ -187,29 +178,6 @@
ast_atomic_fetchadd_int(&ao2.total_locked, -1);
return ast_mutex_unlock(&p->priv_data.lock);
-}
-
-int ao2_unlock_both(void *user_data1, void *user_data2)
-{
- struct astobj2 *p1, *p2;
- int res;
-
- p1 = INTERNAL_OBJ(user_data1);
- p2 = INTERNAL_OBJ(user_data2);
-
- res = ast_mutex_unlock(&p1->priv_data.lock);
- if (!res) {
-#ifdef AO2_DEBUG
- ast_atomic_fetchadd_int(&ao2.total_locked, -1);
-#endif
- res = ast_mutex_unlock(&p2->priv_data.lock);
-#ifdef AO2_DEBUG
- if (!res)
- ast_atomic_fetchadd_int(&ao2.total_locked, -1);
-#endif
- }
-
- return res;
}
/*
More information about the asterisk-commits
mailing list