NIFI-4436: Fixed bug that causes a deadlock when changing version of a PG. 
Before this patch, an update would obtain a write lock and then recurse 
downward through the child groups, obtaining write locks to update variable 
registries. At the same time, if a Processor is obtaining a Controller Service, 
it will obtain a Read Lock on the Process Group and then recurse upward through 
the ancestors, obtaining Read Lock. If the timing is right, we can have a group 
obtain a read lock, then try to obtain its parent's Read Lock. At the same 
time, an update to the group could hold the Write Lock on the Process Group and 
attempt to obtain a Write Lock on child (where the Processor lives), resulting 
in a deadlock.

Signed-off-by: Matt Gilman <[email protected]>


Project: http://git-wip-us.apache.org/repos/asf/nifi/repo
Commit: http://git-wip-us.apache.org/repos/asf/nifi/commit/0127b026
Tree: http://git-wip-us.apache.org/repos/asf/nifi/tree/0127b026
Diff: http://git-wip-us.apache.org/repos/asf/nifi/diff/0127b026

Branch: refs/heads/master
Commit: 0127b02617530491a1a55aa72395cee583083956
Parents: c5b0931
Author: Mark Payne <[email protected]>
Authored: Sat Dec 30 14:16:26 2017 -0500
Committer: Bryan Bende <[email protected]>
Committed: Mon Jan 8 12:44:56 2018 -0500

----------------------------------------------------------------------
 .../apache/nifi/groups/StandardProcessGroup.java  | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/nifi/blob/0127b026/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/groups/StandardProcessGroup.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/groups/StandardProcessGroup.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/groups/StandardProcessGroup.java
index 5d5d0f4..bc5ef29 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/groups/StandardProcessGroup.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/groups/StandardProcessGroup.java
@@ -2028,19 +2028,23 @@ public final class StandardProcessGroup implements 
ProcessGroup {
 
     @Override
     public Set<ControllerServiceNode> getControllerServices(final boolean 
recursive) {
+        final Set<ControllerServiceNode> services = new HashSet<>();
+
         readLock.lock();
         try {
-            final Set<ControllerServiceNode> services = new HashSet<>();
             services.addAll(controllerServices.values());
-
-            if (recursive && parent.get() != null) {
-                services.addAll(parent.get().getControllerServices(true));
-            }
-
-            return services;
         } finally {
             readLock.unlock();
         }
+
+        if (recursive) {
+            final ProcessGroup parentGroup = parent.get();
+            if (parentGroup != null) {
+                services.addAll(parentGroup.getControllerServices(true));
+            }
+        }
+
+        return services;
     }
 
     @Override

Reply via email to