From f36f899005dd9ac95eaa0004c97680ca7d1b7d5d Mon Sep 17 00:00:00 2001 From: Jesse Glick Date: Wed, 1 Feb 2023 15:49:00 -0500 Subject: [PATCH] Make `ContentContainer.contents` thread-safe --- .../jenkins/support/SupportPlugin.java | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/cloudbees/jenkins/support/SupportPlugin.java b/src/main/java/com/cloudbees/jenkins/support/SupportPlugin.java index 297eb47c1..7133107c6 100644 --- a/src/main/java/com/cloudbees/jenkins/support/SupportPlugin.java +++ b/src/main/java/com/cloudbees/jenkins/support/SupportPlugin.java @@ -100,6 +100,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.Date; +import java.util.HashSet; import java.util.List; import java.util.Optional; import java.util.Set; @@ -568,13 +569,13 @@ private static List appendManifestContents(StringBuilder manifest, errors.println(); } } - return contentsContainer.contents; + return contentsContainer.getContents(); } private static class ContentContainer extends Container { private final List contents = new ArrayList<>(); - private final Set names = new TreeSet<>(); + private final Set names = new HashSet<>(); //The filter to return the names filtered private final Optional maybeFilter; @@ -583,24 +584,31 @@ private static class ContentContainer extends Container { * We need the filter to be able to filter the contents written to the manifest * @param maybeFilter filter to use when writing the name of the contents */ - public ContentContainer(Optional maybeFilter) { + ContentContainer(Optional maybeFilter) { this.maybeFilter = maybeFilter; } @Override public void add(Content content) { if (content != null) { - contents.add(content); - names.add(getNameFiltered(maybeFilter, content.getName(), content.getFilterableParameters())); + String name = getNameFiltered(maybeFilter, content.getName(), content.getFilterableParameters()); + synchronized (this) { + contents.add(content); + names.add(name); + } } } - private Set getLatestNames() { + synchronized Set getLatestNames() { Set copy = new TreeSet<>(names); names.clear(); return copy; } + synchronized List getContents() { + return new ArrayList<>(contents); + } + } public List getAllLogRecords() {