changeset 562:69fbcc78346e jdk6-b25

7007299: FileFontStrike appears not to be threadsafe Summary: Initialize graph reference arrays first and only then mark volatile flag (glyphCacheFormat) to indicate to other threads initialization is complete. Reviewed-by: vikram Contributed-by: David Buck <david.buck@oracle.com>
author vikram
date Mon, 12 Mar 2012 02:28:47 -0700
parents 7e03e302bd8a
children 7634c063db13 eab9b661055c
files src/share/classes/sun/font/FileFontStrike.java
diffstat 1 files changed, 9 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/sun/font/FileFontStrike.java	Fri Mar 02 18:06:19 2012 +0800
+++ b/src/share/classes/sun/font/FileFontStrike.java	Mon Mar 12 02:28:47 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -56,7 +56,7 @@
     private static final int SEGINTARRAY   = 3;
     private static final int SEGLONGARRAY  = 4;
 
-    private int glyphCacheFormat = UNINITIALISED;
+    private volatile int glyphCacheFormat = UNINITIALISED;
 
     /* segmented arrays are blocks of 256 */
     private static final int SEGSHIFT = 8;
@@ -426,32 +426,34 @@
     }
 
     /* Called only from synchronized code or constructor */
-    private void initGlyphCache() {
+    private synchronized void initGlyphCache() {
 
         int numGlyphs = mapper.getNumGlyphs();
+        int tmpFormat = UNINITIALISED;
 
         if (segmentedCache) {
             int numSegments = (numGlyphs + SEGSIZE-1)/SEGSIZE;
             if (FontManager.longAddresses) {
-                glyphCacheFormat = SEGLONGARRAY;
+                tmpFormat = SEGLONGARRAY;
                 segLongGlyphImages = new long[numSegments][];
                 this.disposer.segLongGlyphImages = segLongGlyphImages;
              } else {
-                 glyphCacheFormat = SEGINTARRAY;
+                 tmpFormat = SEGINTARRAY;
                  segIntGlyphImages = new int[numSegments][];
                  this.disposer.segIntGlyphImages = segIntGlyphImages;
              }
         } else {
             if (FontManager.longAddresses) {
-                glyphCacheFormat = LONGARRAY;
+                tmpFormat = LONGARRAY;
                 longGlyphImages = new long[numGlyphs];
                 this.disposer.longGlyphImages = longGlyphImages;
             } else {
-                glyphCacheFormat = INTARRAY;
+                tmpFormat = INTARRAY;
                 intGlyphImages = new int[numGlyphs];
                 this.disposer.intGlyphImages = intGlyphImages;
             }
         }
+        glyphCacheFormat = tmpFormat;
     }
 
     /* Metrics info is always retrieved. If the GlyphInfo address is non-zero