making the RaceTracker.getRace() call return a "volatile" value;

this may be the fix for races not moving to FINISHED state during mass
loading

Change-Id: I5c35d24ee9335819e59288914289a22f72ba1cda
This commit is contained in:
Axel Uhl committed 2017-03-04 23:07:18 +01:00
1 parent 51b6a9557b
commit 9f9888b3a0
4 files changed
+21 -12

No files matched your search

@@ -92,7 +92,7 @@ public class RaceLogRaceTracker extends AbstractRaceTrackerBaseImpl {
private final DynamicTrackedRegatta trackedRegatta;
private final RaceLogResolver raceLogResolver;
private DynamicTrackedRace trackedRace;
private volatile DynamicTrackedRace trackedRace;
private StartOfTrackingController startOfTrackingController;
private EndOfTrackingController endOfTrackingController;
@@ -88,7 +88,7 @@ public class SwissTimingRaceTrackerImpl extends AbstractRaceTrackerImpl
* Starts out as <code>null</code> and is set when the race definition has been created. When this happens, this object is
* {@link Object#notifyAll() notified}.
*/
private RaceDefinition race;
private volatile RaceDefinition race;
private Course course;
private StartList startList;
@@ -195,7 +195,14 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl
private final Set<Receiver> receivers;
private final DomainFactory domainFactory;
private final WindStore windStore;
private RaceDefinition race;
/**
* Needs to be {@code volatile} because one thread (e.g., the {@link RaceCourseReceiver}) writes it, another thread
* such as the callback set up by the {@link #stopped(Object)} method and executed by the last {@link Receiver}
* emptying its queue, leading to a call to
* {@link AbstractLoadingQueueDoneCallBack#executeWhenAllReceiversAreDoneLoading()} will read it. We need
* to ensure that the reading threads always read what other writers wrote.
*/
private volatile RaceDefinition race;
private final DynamicTrackedRegatta trackedRegatta;
private TrackedRaceStatus lastStatus;
private Map<Object, Util.Pair<Integer, Float>> lastProgressPerID;
@@ -676,12 +683,13 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl
updateStatusOfTrackedRaces();
if (!stopped) {
try {
// Note that due to the getRace() method returning a "volatile" (cross thread-synchronized) answer,
// we can be sure here that getRace() will return a non-null result if previously a race definition has been
// received.
if (getRace() != null) {
// See also bug 1517; with TracAPI we assume that when stopped(IEvent) is called by the
// TracAPI then
// all subscriptions have received all their data and it's therefore safe to stop all
// subscriptions
// at this point without missing any data.
// TracAPI then all subscriptions have received all their data and it's therefore safe to stop all
// subscriptions at this point without missing any data.
trackedRegattaRegistry.stopTracking(regatta, getRace());
}
} catch (InterruptedException | IOException e) {
@@ -55,11 +55,12 @@ public interface RaceTracker {
com.sap.sailing.domain.base.Regatta getRegatta();
/**
* Returns the races being tracked by this tracker. Non-blocking call that returns <code>null</code>
* if the {@link RaceDefinition} hasn't been created yet, e.g., because the course definition
* hasn't been received yet or the listener for receiving course information hasn't been registered (yet). Also
* returns a race that may have been removed from containing structures which may lead this tracker to no longer update
* their {@link TrackedRace} with new data.
* Returns the races being tracked by this tracker, in a "volatile" way, meaning that if another thread belonging to
* this tracker has established the {@link RaceDefinition} for this tracker, other threads will immediately see this
* object. Non-blocking call that returns <code>null</code> if the {@link RaceDefinition} hasn't been created yet,
* e.g., because the course definition hasn't been received yet or the listener for receiving course information
* hasn't been registered (yet). Also returns a race that may have been removed from containing structures which may
* lead this tracker to no longer update their {@link TrackedRace} with new data.
*/
RaceDefinition getRace();