[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