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 {

Reply via email to