From fa06dc510ee656cf165128ff8977beeced930ddb Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Thu, 1 Mar 2012 17:26:28 +0100 Subject: [PATCH] fixed bug 360: deadlock across mark passings lock and wind estimation track lock --- .../tracking/impl/RaceRankComparator.java | 66 +++++++++++-------- .../sailing/gwt/ui/adminconsole/RaceMap.java | 6 +- 2 files changed, 43 insertions(+), 29 deletions(-) diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/RaceRankComparator.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/RaceRankComparator.java index fe89f5fc8bd..833d78f59f0 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/RaceRankComparator.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/RaceRankComparator.java @@ -44,34 +44,46 @@ public class RaceRankComparator implements Comparator { result = 0; } else { NavigableSet o1MarkPassings = trackedRace.getMarkPassings(o1); + NavigableSet o1MarkPassingsBeforeTimePoint; + MarkPassing o1LastMarkPassingBeforeTimePoint; + int o1MarkPassingsBeforeTimePointSize; + TrackedLegOfCompetitor o1Leg; synchronized (o1MarkPassings) { - NavigableSet o2MarkPassings = trackedRace.getMarkPassings(o2); - synchronized (o2MarkPassings) { - NavigableSet o1MarkPassingsBeforeTimePoint = o1MarkPassings.headSet( - markPassingWithTimePoint, /* inclusive */true); - NavigableSet o2MarkPassingsBeforeTimePoint = o2MarkPassings.headSet( - markPassingWithTimePoint, /* inclusive */true); - result = o2MarkPassingsBeforeTimePoint.size() - o1MarkPassingsBeforeTimePoint.size(); // inverted: more legs means smaller rank - if (result == 0 && o1MarkPassingsBeforeTimePoint.size() > 0) { - // Competitors are on same leg and both have already started the first leg. - // TrackedLegOfCompetitor comparison also correctly uses finish times for a leg - // in case we have the final leg, so both competitors finished the race. - TrackedLegOfCompetitor o1Leg = trackedRace.getCurrentLeg(o1, timePoint); - if (o1Leg == null) { - // both must already finished race; sort by race finish time: earlier time means smaller - // (better) - // rank - result = o1MarkPassingsBeforeTimePoint.last().getTimePoint() - .compareTo(o2MarkPassingsBeforeTimePoint.last().getTimePoint()); - } else { - TrackedLegOfCompetitor o2Leg = trackedRace.getCurrentLeg(o2, timePoint); - if (o2Leg == null) { - result = 1; // o1Leg != null, so o1 has started leg already, o2 hasn't - } else { - result = new WindwardToGoComparator(trackedRace.getTrackedLeg(o1Leg.getLeg()), - timePoint).compare(o1Leg, o2Leg); - } - } + o1MarkPassingsBeforeTimePoint = o1MarkPassings.headSet( + markPassingWithTimePoint, /* inclusive */true); + o1LastMarkPassingBeforeTimePoint = o1MarkPassingsBeforeTimePoint.last(); + o1MarkPassingsBeforeTimePointSize = o1MarkPassingsBeforeTimePoint.size(); + o1Leg = trackedRace.getCurrentLeg(o1, timePoint); + } + NavigableSet o2MarkPassings = trackedRace.getMarkPassings(o2); + NavigableSet o2MarkPassingsBeforeTimePoint; + MarkPassing o2LastMarkPassingBeforeTimePoint; + int o2MarkPassingsBeforeTimePointSize; + TrackedLegOfCompetitor o2Leg; + synchronized (o2MarkPassings) { + o2MarkPassingsBeforeTimePoint = o2MarkPassings.headSet(markPassingWithTimePoint, /* inclusive */true); + o2LastMarkPassingBeforeTimePoint = o2MarkPassingsBeforeTimePoint.last(); + o2MarkPassingsBeforeTimePointSize = o2MarkPassingsBeforeTimePoint.size(); + o2Leg = trackedRace.getCurrentLeg(o2, timePoint); + } + result = o2MarkPassingsBeforeTimePointSize - o1MarkPassingsBeforeTimePointSize; // inverted: more legs means + // smaller rank + if (result == 0 && o1MarkPassingsBeforeTimePointSize > 0) { + // Competitors are on same leg and both have already started the first leg. + // TrackedLegOfCompetitor comparison also correctly uses finish times for a leg + // in case we have the final leg, so both competitors finished the race. + if (o1Leg == null) { + // both must already finished race; sort by race finish time: earlier time means smaller + // (better) + // rank + result = o1LastMarkPassingBeforeTimePoint.getTimePoint().compareTo( + o2LastMarkPassingBeforeTimePoint.getTimePoint()); + } else { + if (o2Leg == null) { + result = 1; // o1Leg != null, so o1 has started leg already, o2 hasn't + } else { + result = new WindwardToGoComparator(trackedRace.getTrackedLeg(o1Leg.getLeg()), timePoint) + .compare(o1Leg, o2Leg); } } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RaceMap.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RaceMap.java index 9935cf1f5d0..72408470777 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RaceMap.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RaceMap.java @@ -17,6 +17,8 @@ import com.google.gwt.i18n.client.NumberFormat; import com.google.gwt.maps.client.InfoWindowContent; import com.google.gwt.maps.client.MapWidget; import com.google.gwt.maps.client.Maps; +import com.google.gwt.maps.client.control.ControlAnchor; +import com.google.gwt.maps.client.control.ControlPosition; import com.google.gwt.maps.client.control.LargeMapControl3D; import com.google.gwt.maps.client.control.MenuMapTypeControl; import com.google.gwt.maps.client.control.ScaleControl; @@ -219,9 +221,9 @@ public class RaceMap extends SimplePanel implements TimeListener, CompetitorSele public void run() { map = new MapWidget(); imageResources.setMap(map); - map.addControl(new LargeMapControl3D()); + map.addControl(new LargeMapControl3D(), new ControlPosition(ControlAnchor.TOP_RIGHT, /* offsetX */ 0, /* offsetY */ 30)); map.addControl(new MenuMapTypeControl()); - map.addControl(new ScaleControl()); + map.addControl(new ScaleControl(), new ControlPosition(ControlAnchor.BOTTOM_RIGHT, /* offsetX */ 10, /* offsetY */ 20)); // Add the map to the HTML host page map.setScrollWheelZoomEnabled(true); map.setContinuousZoom(true);