You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by rf...@apache.org on 2021/03/13 10:58:33 UTC

[maven] branch master updated: [MNG-7111] Deadlock when reading pom

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

rfscholte pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven.git


The following commit(s) were added to refs/heads/master by this push:
     new 9e19b57  [MNG-7111] Deadlock when reading pom
9e19b57 is described below

commit 9e19b57c720d226b0b30992535819f700a665d14
Author: Guillaume Nodet <gn...@gmail.com>
AuthorDate: Sat Mar 13 11:58:02 2021 +0100

    [MNG-7111] Deadlock when reading pom
    
    Signed-off-by: rfscholte <rf...@apache.org>
---
 .../maven/model/building/DefaultModelBuilder.java  |  7 ++-
 .../model/building/DefaultTransformerContext.java  | 68 ++++++++++++++++++++--
 2 files changed, 67 insertions(+), 8 deletions(-)

diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java
index 845480c..51d2b06 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java
@@ -1571,13 +1571,16 @@ public class DefaultModelBuilder
                 public Model getRawModel( String gId, String aId )
                 {
                     return context.modelByGA.computeIfAbsent( new DefaultTransformerContext.GAKey( gId, aId ),
-                                                              k -> findRawModel( gId, aId ) );
+                                                              k -> new DefaultTransformerContext.Holder() )
+                            .computeIfAbsent( () -> findRawModel( gId, aId ) );
                 }
 
                 @Override
                 public Model getRawModel( Path path )
                 {
-                    return context.modelByPath.computeIfAbsent( path, k -> findRawModel( path ) );
+                    return context.modelByPath.computeIfAbsent( path,
+                                                                k -> new DefaultTransformerContext.Holder() )
+                            .computeIfAbsent( () -> findRawModel( path ) );
                 }
 
                 private Model findRawModel( String groupId, String artifactId )
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultTransformerContext.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultTransformerContext.java
index 080c62b..3c70b3c 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultTransformerContext.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultTransformerContext.java
@@ -20,9 +20,10 @@ package org.apache.maven.model.building;
  */
 
 import java.nio.file.Path;
-import java.util.HashMap;
 import java.util.Map;
 import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Supplier;
 
 import org.apache.maven.model.Model;
 
@@ -33,11 +34,66 @@ import org.apache.maven.model.Model;
  */
 class DefaultTransformerContext implements TransformerContext
 {
-    final Map<String, String> userProperties = new HashMap<>();
+    final Map<String, String> userProperties = new ConcurrentHashMap<>();
 
-    final Map<Path, Model> modelByPath = new HashMap<>();
+    final Map<Path, Holder> modelByPath = new ConcurrentHashMap<>();
 
-    final Map<GAKey, Model> modelByGA = new HashMap<>();
+    final Map<GAKey, Holder> modelByGA = new ConcurrentHashMap<>();
+
+    public static class Holder
+    {
+        private volatile boolean set;
+        private volatile Model model;
+
+        Holder()
+        {
+        }
+
+        public static Model deref( Holder holder )
+        {
+            return holder != null ? holder.get() : null;
+        }
+
+        public Model get()
+        {
+            if ( !set )
+            {
+                synchronized ( this )
+                {
+                    if ( !set )
+                    {
+                        try
+                        {
+                            this.wait();
+                        }
+                        catch ( InterruptedException e )
+                        {
+                            // Ignore
+                        }
+                    }
+                }
+            }
+            return model;
+        }
+
+        public Model computeIfAbsent( Supplier<Model> supplier )
+        {
+            if ( !set )
+            {
+                synchronized ( this )
+                {
+                    if ( !set )
+                    {
+                        this.set = true;
+                        this.model = supplier.get();
+                        this.notifyAll();
+                    }
+                }
+            }
+            return model;
+        }
+
+    }
 
     @Override
     public String getUserProperty( String key )
@@ -48,13 +104,13 @@ class DefaultTransformerContext implements TransformerContext
     @Override
     public Model getRawModel( Path p )
     {
-        return modelByPath.get( p );
+        return Holder.deref( modelByPath.get( p ) );
     }
 
     @Override
     public Model getRawModel( String groupId, String artifactId )
     {
-        return modelByGA.get( new GAKey( groupId, artifactId ) );
+        return Holder.deref( modelByGA.get( new GAKey( groupId, artifactId ) ) );
     }
 
     static class GAKey