diff --git a/java/com.sap.sailing.polars/src/com/sap/sailing/polars/mining/PolarDataMiner.java b/java/com.sap.sailing.polars/src/com/sap/sailing/polars/mining/PolarDataMiner.java index 36f870a3ed9..e4f240af998 100755 --- a/java/com.sap.sailing.polars/src/com/sap/sailing/polars/mining/PolarDataMiner.java +++ b/java/com.sap.sailing.polars/src/com/sap/sailing/polars/mining/PolarDataMiner.java @@ -6,6 +6,7 @@ import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Queue; import java.util.Set; @@ -427,14 +428,22 @@ public class PolarDataMiner { + (race.getRace() != null ? race.getRace().getName() : race.getRaceIdentifier().getRaceName())); for (final Competitor competitor : race.getRace().getCompetitors()) { final GPSFixTrack track = race.getTrack(competitor); + // it is necessary to release the track's lock before calling processElement + // because processElement will transitively cause obtaining the course lock, + // and other methods will first obtain the course and then the track lock, leading + // to a deadlock. See also bug 4297. + final List fixes = new ArrayList<>(); track.lockForRead(); try { for (final GPSFixMoving fix : track.getFixes()) { - preFilteringProcessor.processElement(new GPSFixMovingWithOriginInfo(fix, race, competitor)); + fixes.add(fix); } } finally { track.unlockAfterRead(); } + for (final GPSFixMoving fix : fixes) { + preFilteringProcessor.processElement(new GPSFixMovingWithOriginInfo(fix, race, competitor)); + } } logger.info("Finished injecting fixes for race " + (race.getRace() != null ? race.getRace().getName() : race.getRaceIdentifier().getRaceName())