diff --git a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/DefaultISMLocking.java b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/DefaultISMLocking.java
index 15a68b1..4c6f162 100644
--- a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/DefaultISMLocking.java
+++ b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/DefaultISMLocking.java
@@ -54,7 +54,7 @@ public class DefaultISMLocking implements ISMLocking {
 
     /**
      * Number of writer threads waiting. While greater than zero, no new
-     * readers are allowed to proceed.
+     * (unrelated) readers are allowed to proceed.
      */
     private int writersWaiting = 0;
 
@@ -63,7 +63,9 @@ public class DefaultISMLocking implements ISMLocking {
      * no write is in progress. A thread with the same identifier (i.e. the
      * same thread or another thread in the same transaction) can re-acquire
      * read or write locks without limitation, while all other readers and
-     * writers remain blocked.
+     * writers remain blocked. Note that a downgraded write lock still retains
+     * the writer thread identifier, which allows related threads to reacquire
+     * read or write locks even when there are concurrent writers waiting.
      */
     private Object writerId = null;
 
@@ -100,7 +102,8 @@ public class DefaultISMLocking implements ISMLocking {
      */
     private synchronized void releaseReadLock() {
         readerCount--;
-        if (readerCount == 0 && writerId == null) {
+        if (readerCount == 0 && writerCount == 0) {
+            writerId = null;
             notifyAll();
         }
     }
@@ -142,7 +145,9 @@ public class DefaultISMLocking implements ISMLocking {
             readerCount++;
         }
         if (writerCount == 0) {
-            writerId = null;
+            if (readerCount == 0) {
+                writerId = null;
+            }
             notifyAll();
         }
     }
