org.orekit.time.LazyLoadedTimeScales#getUTC is not thread safe
org.orekit.time.LazyLoadedTimeScales#getUTC is not thread safe. When the UTCScale is not loaded yet, two threads can enter the lazy loading, and cause a ConcurrentModificationException when looping over the loaders
Patch to fix it:
Subject: [PATCH] fix_issue-1296
---
Index: src/main/java/org/orekit/time/LazyLoadedTimeScales.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/src/main/java/org/orekit/time/LazyLoadedTimeScales.java b/src/main/java/org/orekit/time/LazyLoadedTimeScales.java
--- a/src/main/java/org/orekit/time/LazyLoadedTimeScales.java (revision 4314309b071f9ab340b7740b1a7da4e46e003aa2)
+++ b/src/main/java/org/orekit/time/LazyLoadedTimeScales.java (date 1704290488132)
@@ -177,23 +177,28 @@
UTCScale refUtc = utc.get();
if (refUtc == null) {
- List<OffsetModel> entries = Collections.emptyList();
- if (loaders.isEmpty()) {
- addDefaultUTCTAIOffsetsLoaders();
- }
- for (UTCTAIOffsetsLoader loader : loaders) {
- entries = loader.loadOffsets();
- if (!entries.isEmpty()) {
- break;
- }
- }
- if (entries.isEmpty()) {
- throw new OrekitException(OrekitMessages.NO_IERS_UTC_TAI_HISTORY_DATA_LOADED);
- }
- utc.compareAndSet(null, new UTCScale(getTAI(), entries));
- refUtc = utc.get();
- }
+ synchronized (this) {
+ if (utc.get() == null) { // Check if utc was not loaded in the meantime
+ List<OffsetModel> entries = Collections.emptyList();
+ if (loaders.isEmpty()) {
+ addDefaultUTCTAIOffsetsLoaders();
+ }
+ for (UTCTAIOffsetsLoader loader : loaders) {
+ entries = loader.loadOffsets();
+ if (!entries.isEmpty()) {
+ break;
+ }
+ }
+ if (entries.isEmpty()) {
+ throw new OrekitException(OrekitMessages.NO_IERS_UTC_TAI_HISTORY_DATA_LOADED);
+ }
+ utc.compareAndSet(null, new UTCScale(getTAI(), entries));
+ }
+ refUtc = utc.get();
+ }
+ }
+
return refUtc;
}
Edited by Christopher Schank