]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
FOP-3111: Make property cache thread safe
authorSimon Steiner <ssteiner@apache.org>
Fri, 23 Dec 2022 15:39:40 +0000 (15:39 +0000)
committerSimon Steiner <ssteiner@apache.org>
Fri, 23 Dec 2022 15:39:40 +0000 (15:39 +0000)
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1906188 13f79535-47bb-0310-9956-ffa450edef68

fop-core/src/main/java/org/apache/fop/fo/properties/PropertyCache.java
fop-core/src/test/java/org/apache/fop/fonts/FontSelectorTestCase.java

index 5846fb76c113e33578019a54beae528a827651cf..156290fbd8cc9135dcc4ecda47415f6a2ec9f5ce 100644 (file)
@@ -189,6 +189,14 @@ public final class PropertyCache<T> {
     }
 
     private boolean eq(Object p, Object q) {
-        return (p == q || p.equals(q));
+        if (p == q) {
+            return true;
+        }
+        cleanupLock.lock();
+        try {
+            return p.equals(q);
+        } finally {
+            cleanupLock.unlock();
+        }
     }
 }
index 0871901cdb088e87ea0de346a7d6e690e8b68dc4..10c907296b5100ae64d55c011a75692da1f378ca 100644 (file)
 
 package org.apache.fop.fonts;
 
+import java.io.PrintStream;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.invocation.InvocationOnMock;
@@ -30,12 +35,16 @@ import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import org.apache.commons.io.output.NullPrintStream;
+
 import org.apache.fop.datatypes.PercentBaseContext;
 import org.apache.fop.fo.Constants;
 import org.apache.fop.fo.FOEventHandler;
 import org.apache.fop.fo.FOText;
 import org.apache.fop.fo.PropertyList;
+import org.apache.fop.fo.StaticPropertyList;
 import org.apache.fop.fo.expr.PropertyException;
+import org.apache.fop.fo.pagination.Root;
 import org.apache.fop.fo.properties.CommonFont;
 import org.apache.fop.fo.properties.EnumProperty;
 import org.apache.fop.fo.properties.FixedLength;
@@ -43,7 +52,6 @@ import org.apache.fop.fo.properties.FontFamilyProperty;
 import org.apache.fop.fo.properties.NumberProperty;
 import org.apache.fop.fo.properties.Property;
 
-
 public class FontSelectorTestCase {
 
     private static final FontTriplet LATIN_FONT_TRIPLET = new FontTriplet("Verdana", "normal", 400);
@@ -136,4 +144,34 @@ public class FontSelectorTestCase {
         return CommonFont.getInstance(pList);
     }
 
+
+    @Test
+    public void testFontCacheWithThreads() throws Exception {
+        PrintStream old = System.err;
+        System.setErr(new NullPrintStream());
+        ExecutorService executor = Executors.newFixedThreadPool(10);
+        for (int i = 0; i < 100000; i++) {
+            executor.submit(new FontTask());
+        }
+        executor.shutdown();
+        executor.awaitTermination(1, TimeUnit.DAYS);
+        System.setErr(old);
+    }
+
+    static class FontTask implements Runnable {
+        public void run() {
+            try {
+                Root r = new Root(null);
+                StaticPropertyList pList = new StaticPropertyList(r, null);
+                Property x = new FontFamilyProperty.Maker(Constants.PR_FONT_FAMILY).make(pList, "a-963191172", null);
+                pList.putExplicit(Constants.PR_FONT_FAMILY, x);
+                CommonFont.getInstance(pList);
+                x = new FontFamilyProperty.Maker(Constants.PR_FONT_FAMILY).make(pList, "a385863058", null);
+                pList.putExplicit(Constants.PR_FONT_FAMILY, x);
+                CommonFont.getInstance(pList);
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
 }