[MNG-7111] Deadlock when reading pom

Signed-off-by: rfscholte <rfscholte@apache.org>
This commit is contained in:
Guillaume Nodet 2021-03-13 11:58:02 +01:00 committed by rfscholte
parent aa90370ff4
commit 9e19b57c72
2 changed files with 67 additions and 8 deletions

View File

@ -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 )

View File

@ -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