Repository: ant-ivy Updated Branches: refs/heads/master ad90d4b7e -> 30696f6e1
FIX: ModuleDescriptorMemoryCache isn't thread safe resulting in corruption of the LinkedHashMap internal structure when multiple threads simultaneously read/write to this cache. Project: http://git-wip-us.apache.org/repos/asf/ant-ivy/repo Commit: http://git-wip-us.apache.org/repos/asf/ant-ivy/commit/30696f6e Tree: http://git-wip-us.apache.org/repos/asf/ant-ivy/tree/30696f6e Diff: http://git-wip-us.apache.org/repos/asf/ant-ivy/diff/30696f6e Branch: refs/heads/master Commit: 30696f6e16b09ad3f992e409472bd2b1e97a94f1 Parents: ad90d4b Author: Maarten Coene <[email protected]> Authored: Mon Apr 23 14:03:56 2018 +0200 Committer: Maarten Coene <[email protected]> Committed: Mon Apr 23 14:03:56 2018 +0200 ---------------------------------------------------------------------- .../core/cache/ModuleDescriptorMemoryCache.java | 54 +++++++++++--------- 1 file changed, 29 insertions(+), 25 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/30696f6e/src/java/org/apache/ivy/core/cache/ModuleDescriptorMemoryCache.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/ivy/core/cache/ModuleDescriptorMemoryCache.java b/src/java/org/apache/ivy/core/cache/ModuleDescriptorMemoryCache.java index 357c130..fb4338c 100644 --- a/src/java/org/apache/ivy/core/cache/ModuleDescriptorMemoryCache.java +++ b/src/java/org/apache/ivy/core/cache/ModuleDescriptorMemoryCache.java @@ -17,16 +17,16 @@ */ package org.apache.ivy.core.cache; +import org.apache.ivy.core.module.descriptor.ModuleDescriptor; +import org.apache.ivy.plugins.parser.ParserSettings; +import org.apache.ivy.util.Message; + import java.io.File; import java.io.IOException; import java.text.ParseException; import java.util.Iterator; import java.util.LinkedHashMap; -import org.apache.ivy.core.module.descriptor.ModuleDescriptor; -import org.apache.ivy.plugins.parser.ParserSettings; -import org.apache.ivy.util.Message; - /** * Cache ModuleDescriptors so that when the same module is used twice (in multi-module build for * instance), it is parsed only once. This cache is has a limited size, and keep the most recently @@ -76,23 +76,25 @@ class ModuleDescriptorMemoryCache { // cache is disabled return null; } - CacheEntry entry = valueMap.get(ivyFile); - if (entry != null) { - if (entry.isStale(validated, ivySettings)) { - Message.debug("Entry is found in the ModuleDescriptorCache but entry should be " - + "reevaluated : " + ivyFile); - valueMap.remove(ivyFile); - return null; + synchronized (valueMap) { + CacheEntry entry = valueMap.get(ivyFile); + if (entry != null) { + if (entry.isStale(validated, ivySettings)) { + Message.debug("Entry is found in the ModuleDescriptorCache but entry should be " + + "reevaluated : " + ivyFile); + valueMap.remove(ivyFile); + return null; + } else { + // Move the entry at the end of the list + valueMap.remove(ivyFile); + valueMap.put(ivyFile, entry); + Message.debug("Entry is found in the ModuleDescriptorCache : " + ivyFile); + return entry.md; + } } else { - // Move the entry at the end of the list - valueMap.remove(ivyFile); - valueMap.put(ivyFile, entry); - Message.debug("Entry is found in the ModuleDescriptorCache : " + ivyFile); - return entry.md; + Message.debug("No entry is found in the ModuleDescriptorCache : " + ivyFile); + return null; } - } else { - Message.debug("No entry is found in the ModuleDescriptorCache : " + ivyFile); - return null; } } @@ -102,13 +104,15 @@ class ModuleDescriptorMemoryCache { // cache is disabled return; } - if (valueMap.size() >= maxSize) { - Message.debug("ModuleDescriptorCache is full, remove one entry"); - Iterator<CacheEntry> it = valueMap.values().iterator(); - it.next(); - it.remove(); + synchronized (valueMap) { + if (valueMap.size() >= maxSize) { + Message.debug("ModuleDescriptorCache is full, remove one entry"); + Iterator<CacheEntry> it = valueMap.values().iterator(); + it.next(); + it.remove(); + } + valueMap.put(url, new CacheEntry(descriptor, validated, ivySettingsMonitor)); } - valueMap.put(url, new CacheEntry(descriptor, validated, ivySettingsMonitor)); } private static class CacheEntry {
