Skip to content

Commit 426cea1

Browse files
committed
ICU-23247 CLDR-to-ICU: using parallel sometimes fails on Windows
1 parent e3532d0 commit 426cea1

File tree

3 files changed

+20
-4
lines changed

3 files changed

+20
-4
lines changed

tools/cldr/cldr-to-icu/src/main/java/org/unicode/icu/tool/cldrtoicu/DependencyGraph.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public DependencyGraph(String cldrVersion) {
2424
this.cldrVersion = checkNotNull(cldrVersion);
2525
}
2626

27-
void addParent(String localeId, String parentId) {
27+
synchronized void addParent(String localeId, String parentId) {
2828
// Aliases take priority (since they can be forced and will replace empty files). Note
2929
// however that this only happens in a tiny number of places due to the somewhat "hacky"
3030
// forced aliases, and in future it's perfectly possibly that there would never be an

tools/cldr/cldr-to-icu/src/main/java/org/unicode/icu/tool/cldrtoicu/IcuTextWriter.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,16 @@ static void writeToFile(
4646
IcuData icuData, Path outDir, List<String> header, boolean allowOverwrite) {
4747

4848
try {
49-
Files.createDirectories(outDir);
49+
try {
50+
Files.createDirectories(outDir);
51+
} catch (IOException e) {
52+
// On Windows, concurrent directory creation by parallel threads can transiently
53+
// produce AccessDeniedException even when the directory already exists. If the
54+
// directory is now present (created by another thread), treat it as success.
55+
if (!Files.isDirectory(outDir)) {
56+
throw e;
57+
}
58+
}
5059
Path file = outDir.resolve(icuData.getName() + ".txt");
5160
OpenOption[] fileOptions = allowOverwrite ? OVERWRITE_FILES : ONLY_NEW_FILES;
5261
try (Writer w = Files.newBufferedWriter(file, UTF_8, fileOptions);

tools/cldr/cldr-to-icu/src/main/java/org/unicode/icu/tool/cldrtoicu/LdmlConverter.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import com.google.common.collect.LinkedListMultimap;
3131
import com.google.common.collect.ListMultimap;
3232
import com.google.common.collect.Maps;
33+
import com.google.common.collect.Multimaps;
3334
import com.google.common.collect.SetMultimap;
3435
import com.google.common.collect.Sets;
3536
import com.google.common.io.CharStreams;
@@ -287,7 +288,8 @@ private void processLdml() {
287288
Map<IcuLocaleDir, DependencyGraph> graphMetadata = new HashMap<>();
288289
splitDirs.forEach(d -> graphMetadata.put(d, new DependencyGraph(cldrVersion)));
289290

290-
SetMultimap<IcuLocaleDir, String> writtenLocaleIds = HashMultimap.create();
291+
SetMultimap<IcuLocaleDir, String> writtenLocaleIds =
292+
Multimaps.synchronizedSetMultimap(HashMultimap.create());
291293
Path baseDir = config.getOutputDir();
292294

293295
System.out.println("processing standard ldml files");
@@ -650,7 +652,12 @@ private Path createDirectory(Path dir) {
650652
try {
651653
Files.createDirectories(dir);
652654
} catch (IOException e) {
653-
throw new RuntimeException("cannot create directory: " + dir, e);
655+
// On Windows, concurrent directory creation by parallel threads can transiently
656+
// produce AccessDeniedException even when the directory already exists. If the
657+
// directory is now present (created by another thread), treat it as success.
658+
if (!Files.isDirectory(dir)) {
659+
throw new RuntimeException("cannot create directory: " + dir, e);
660+
}
654661
}
655662
return dir;
656663
}

0 commit comments

Comments
 (0)