diff --git a/lib/spack/llnl/util/lock.py b/lib/spack/llnl/util/lock.py
index 6e49bf74e6c53d36a88e5b44dd255521c063d775..dcca37687e71e288ac78f2d8c33e1a0bddacc5b5 100644
--- a/lib/spack/llnl/util/lock.py
+++ b/lib/spack/llnl/util/lock.py
@@ -95,10 +95,15 @@ def acquire_read(self, timeout=_default_timeout):
         order, but the POSIX lock is held until all local read and
         write locks are released.
 
+        Returns True if it is the first acquire and actually acquires
+        the POSIX lock, False if it is a nested transaction.
+
         """
-        if self._reads == 0 and self._writes == 0:
-            self._lock(fcntl.LOCK_SH, timeout)
         self._reads += 1
+        if self._reads == 1 and self._writes == 0:
+            self._lock(fcntl.LOCK_SH, timeout)
+            return True
+        return False
 
 
     def acquire_write(self, timeout=_default_timeout):
@@ -107,10 +112,16 @@ def acquire_write(self, timeout=_default_timeout):
         Read and write locks can be acquired and released in arbitrary
         order, but the POSIX lock is held until all local read and
         write locks are released.
+
+        Returns True if it is the first acquire and actually acquires
+        the POSIX lock, False if it is a nested transaction.
+
         """
-        if self._writes == 0:
-            self._lock(fcntl.LOCK_EX, timeout)
         self._writes += 1
+        if self._writes == 1:
+            self._lock(fcntl.LOCK_EX, timeout)
+            return True
+        return False
 
 
     def release_read(self):