From 4c8209624ff8b3d758d6edffee4ce985da8fd237 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Thu, 31 Aug 2017 19:22:25 +0200 Subject: [PATCH] bug 4297: fixing deadlock by first copying fixes, the releasing track lock, then calling processElement Change-Id: Id30d1205d807ef992ff7d2d60184e18deeec389d --- .../com/sap/sailing/polars/mining/PolarDataMiner.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) 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())