From 71e1863e7634994cc1fdc292929a002957a89fbd Mon Sep 17 00:00:00 2001
From: Michael Hanselmann <hansmi@google.com>
Date: Wed, 13 Jan 2010 11:10:17 +0100
Subject: [PATCH] locking: Fix race condition in LockSet

This patch fixes a race condition when acquiring all locks in
a LockSet instance. The list of lock names needs to be sorted
to guarantee a consistent locking order, but the names were not
sorted when acquiring all locks in the set.

Signed-off-by: Michael Hanselmann <hansmi@google.com>
Reviewed-by: Iustin Pop <iustin@google.com>
---
 lib/locking.py | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/lib/locking.py b/lib/locking.py
index b738ed64d..f30e8b703 100644
--- a/lib/locking.py
+++ b/lib/locking.py
@@ -841,8 +841,6 @@ class LockSet:
         # Support passing in a single resource to acquire rather than many
         if isinstance(names, basestring):
           names = [names]
-        else:
-          names = sorted(names)
 
         return self.__acquire_inner(names, False, shared,
                                     running_timeout.Remaining, test_notify)
@@ -891,8 +889,9 @@ class LockSet:
 
     # First we look the locks up on __lockdict. We have no way of being sure
     # they will still be there after, but this makes it a lot faster should
-    # just one of them be the already wrong
-    for lname in utils.UniqueSequence(names):
+    # just one of them be the already wrong. Using a sorted sequence to prevent
+    # deadlocks.
+    for lname in sorted(utils.UniqueSequence(names)):
       try:
         lock = self.__lockdict[lname] # raises KeyError if lock is not there
       except KeyError:
-- 
GitLab