This is an automated email from the ASF dual-hosted git repository.

dsmiley pushed a commit to branch branch_9x
in repository https://gitbox.apache.org/repos/asf/solr.git


The following commit(s) were added to refs/heads/branch_9x by this push:
     new eb3bafab83b SOLR-17720: Fix rare deadlock in CollectionProperties 
(#3304)
eb3bafab83b is described below

commit eb3bafab83b4f3c4801835f8d97740992f6ca93d
Author: aparnasuresh85 <[email protected]>
AuthorDate: Wed Apr 23 08:35:12 2025 +0900

    SOLR-17720: Fix rare deadlock in CollectionProperties (#3304)
    
    The problem pre-dated CollectionPropertiesZkStateReader's existence.
    
    (cherry picked from commit 67a642fe0263588155627c0429ea5cf39f519c8e)
---
 solr/CHANGES.txt                                   |  2 ++
 .../cloud/CollectionPropertiesZkStateReader.java   | 25 ++++++++++++----------
 2 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 17f0dfc2e98..08cd240732e 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -83,6 +83,8 @@ Bug Fixes
 
 * SOLR-17740: When the V2 API is receiving raw files, it could sometimes skip 
the first byte. (David Smiley)
 
+* SOLR-17720: Fix rare deadlock in CollectionProperties internals.  (Aparna 
Suresh, Houston Putman)
+
 Dependency Upgrades
 ---------------------
 * SOLR-17471: Upgrade Lucene to 9.12.1. (Pierre Salagnac, Christine Poerschke)
diff --git 
a/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/CollectionPropertiesZkStateReader.java
 
b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/CollectionPropertiesZkStateReader.java
index 135251ddd5a..4242e0beee9 100644
--- 
a/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/CollectionPropertiesZkStateReader.java
+++ 
b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/CollectionPropertiesZkStateReader.java
@@ -393,19 +393,22 @@ public class CollectionPropertiesZkStateReader implements 
Closeable {
   }
 
   public void removeCollectionPropsWatcher(String collection, 
CollectionPropsWatcher watcher) {
-    collectionPropsObservers.compute(
-        collection,
-        (k, v) -> {
-          if (v == null) return null;
-          v.stateWatchers.remove(watcher);
-          if (v.canBeRemoved()) {
-            // don't want this to happen in middle of other blocks that might 
add it back.
-            synchronized (getCollectionLock(collection)) {
+    // don't want removal from watchedCollectionProps to happen in middle of 
other blocks that might
+    // add it back.
+    // Need to lock outside of the compute() call or risk a deadlock with the 
locking done in
+    // collectionPropsObservers
+    synchronized (getCollectionLock(collection)) {
+      collectionPropsObservers.compute(
+          collection,
+          (k, v) -> {
+            if (v == null) return null;
+            v.stateWatchers.remove(watcher);
+            if (v.canBeRemoved()) {
               watchedCollectionProps.remove(collection);
               return null;
             }
-          }
-          return v;
-        });
+            return v;
+          });
+    }
   }
 }

Reply via email to