提交 2de47b57 编写于 作者: S sherman

8012326: Deadlock occurs when Charset.availableCharsets() is called by several...

8012326: Deadlock occurs when Charset.availableCharsets() is called by several threads at the same time
Summary: removed the race condition risk from  ExtendedCahrset access code
Reviewed-by: mchung, alanb
上级 76bcd7d5
...@@ -87,9 +87,6 @@ build: $(FILES_genout_extcs) $(CHARSETS_JAR) ...@@ -87,9 +87,6 @@ build: $(FILES_genout_extcs) $(CHARSETS_JAR)
# #
# Extra rules to build character converters. # Extra rules to build character converters.
SERVICE_DESCRIPTION = java.nio.charset.spi.CharsetProvider
SERVICE_DESCRIPTION_PATH = META-INF/services/$(SERVICE_DESCRIPTION)
GENCSDATASRC = $(BUILDDIR)/tools/CharsetMapping GENCSDATASRC = $(BUILDDIR)/tools/CharsetMapping
GENCSSRCDIR = $(BUILDDIR)/tools/src/build/tools/charsetmapping GENCSSRCDIR = $(BUILDDIR)/tools/src/build/tools/charsetmapping
GENCSEXT = $(GENSRCDIR)/sun/nio/cs/ext GENCSEXT = $(GENSRCDIR)/sun/nio/cs/ext
...@@ -118,10 +115,6 @@ $(FILES_genout_extcs): \ ...@@ -118,10 +115,6 @@ $(FILES_genout_extcs): \
$(GENCSSRCDIR)/HKSCS.java $(GENCSSRCDIR)/HKSCS.java
$(BOOT_JAVA_CMD) -jar $(CHARSETMAPPING_JARFILE) $(GENCSDATASRC) $(GENCSEXT) dbcs $(BOOT_JAVA_CMD) -jar $(CHARSETMAPPING_JARFILE) $(GENCSDATASRC) $(GENCSEXT) dbcs
$(CLASSDESTDIR)/$(SERVICE_DESCRIPTION_PATH): \
$(SHARE_SRC)/classes/sun/nio/cs/ext/$(SERVICE_DESCRIPTION_PATH)
$(install-file)
# no compression unless requested # no compression unless requested
ifndef COMPRESS_JARS ifndef COMPRESS_JARS
CREATE_JAR_OPTS_NOMANIFEST = cf0 CREATE_JAR_OPTS_NOMANIFEST = cf0
...@@ -129,10 +122,9 @@ else ...@@ -129,10 +122,9 @@ else
CREATE_JAR_OPTS_NOMANIFEST = cf CREATE_JAR_OPTS_NOMANIFEST = cf
endif endif
$(CHARSETS_JAR): $(FILES_class) $(CLASSDESTDIR)/$(SERVICE_DESCRIPTION_PATH) $(FILES_DAT) $(CHARSETS_JAR): $(FILES_class) $(FILES_DAT)
$(BOOT_JAR_CMD) $(CREATE_JAR_OPTS_NOMANIFEST) $(CHARSETS_JAR) \ $(BOOT_JAR_CMD) $(CREATE_JAR_OPTS_NOMANIFEST) $(CHARSETS_JAR) \
-C $(CLASSDESTDIR) sun \ -C $(CLASSDESTDIR) sun \
-C $(CLASSDESTDIR) $(SERVICE_DESCRIPTION_PATH) \
$(BOOT_JAR_JFLAGS) $(BOOT_JAR_JFLAGS)
@$(java-vm-cleanup) @$(java-vm-cleanup)
......
...@@ -201,7 +201,6 @@ RT_JAR_EXCLUDES += \ ...@@ -201,7 +201,6 @@ RT_JAR_EXCLUDES += \
META-INF/services/com.sun.jdi.connect.spi.TransportService \ META-INF/services/com.sun.jdi.connect.spi.TransportService \
META-INF/services/com.sun.tools.attach.spi.AttachProvider \ META-INF/services/com.sun.tools.attach.spi.AttachProvider \
META-INF/services/com.sun.tools.xjc.Plugin \ META-INF/services/com.sun.tools.xjc.Plugin \
META-INF/services/java.nio.charset.spi.CharsetProvider \
META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor \ META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor \
org/relaxng/datatype \ org/relaxng/datatype \
sun/awt/HKSCS.class \ sun/awt/HKSCS.class \
...@@ -428,8 +427,7 @@ $(eval $(call SetupArchive,BUILD_CHARSETS_JAR,,\ ...@@ -428,8 +427,7 @@ $(eval $(call SetupArchive,BUILD_CHARSETS_JAR,,\
SUFFIXES:=.class .dat,\ SUFFIXES:=.class .dat,\
INCLUDES:=sun/nio/cs/ext,\ INCLUDES:=sun/nio/cs/ext,\
EXTRA_FILES := sun/awt/HKSCS.class \ EXTRA_FILES := sun/awt/HKSCS.class \
$(CHARSETS_EXTRA_FILES) \ $(CHARSETS_EXTRA_FILES), \
META-INF/services/java.nio.charset.spi.CharsetProvider, \
JAR:=$(IMAGES_OUTPUTDIR)/lib/charsets.jar, \ JAR:=$(IMAGES_OUTPUTDIR)/lib/charsets.jar, \
SKIP_METAINF := true, \ SKIP_METAINF := true, \
CHECK_COMPRESS_JAR:=true)) CHECK_COMPRESS_JAR:=true))
......
...@@ -427,46 +427,38 @@ public abstract class Charset ...@@ -427,46 +427,38 @@ public abstract class Charset
} }
/* The extended set of charsets */ /* The extended set of charsets */
private static Object extendedProviderLock = new Object(); private static class ExtendedProviderHolder {
private static boolean extendedProviderProbed = false; static final CharsetProvider extendedProvider = extendedProvider();
private static CharsetProvider extendedProvider = null; // returns ExtendedProvider, if installed
private static CharsetProvider extendedProvider() {
private static void probeExtendedProvider() { return AccessController.doPrivileged(
AccessController.doPrivileged(new PrivilegedAction<Object>() { new PrivilegedAction<CharsetProvider>() {
public Object run() { public CharsetProvider run() {
try { try {
Class<?> epc Class<?> epc
= Class.forName("sun.nio.cs.ext.ExtendedCharsets"); = Class.forName("sun.nio.cs.ext.ExtendedCharsets");
extendedProvider = (CharsetProvider)epc.newInstance(); return (CharsetProvider)epc.newInstance();
} catch (ClassNotFoundException x) { } catch (ClassNotFoundException x) {
// Extended charsets not available // Extended charsets not available
// (charsets.jar not present) // (charsets.jar not present)
} catch (InstantiationException x) { } catch (InstantiationException |
throw new Error(x); IllegalAccessException x) {
} catch (IllegalAccessException x) {
throw new Error(x); throw new Error(x);
} }
return null; return null;
} }
}); });
} }
}
private static Charset lookupExtendedCharset(String charsetName) { private static Charset lookupExtendedCharset(String charsetName) {
CharsetProvider ecp = null; CharsetProvider ecp = ExtendedProviderHolder.extendedProvider;
synchronized (extendedProviderLock) {
if (!extendedProviderProbed) {
probeExtendedProvider();
extendedProviderProbed = true;
}
ecp = extendedProvider;
}
return (ecp != null) ? ecp.charsetForName(charsetName) : null; return (ecp != null) ? ecp.charsetForName(charsetName) : null;
} }
private static Charset lookup(String charsetName) { private static Charset lookup(String charsetName) {
if (charsetName == null) if (charsetName == null)
throw new IllegalArgumentException("Null charset name"); throw new IllegalArgumentException("Null charset name");
Object[] a; Object[] a;
if ((a = cache1) != null && charsetName.equals(a[0])) if ((a = cache1) != null && charsetName.equals(a[0]))
return (Charset)a[1]; return (Charset)a[1];
...@@ -483,7 +475,6 @@ public abstract class Charset ...@@ -483,7 +475,6 @@ public abstract class Charset
cache1 = a; cache1 = a;
return (Charset)a[1]; return (Charset)a[1];
} }
Charset cs; Charset cs;
if ((cs = standardProvider.charsetForName(charsetName)) != null || if ((cs = standardProvider.charsetForName(charsetName)) != null ||
(cs = lookupExtendedCharset(charsetName)) != null || (cs = lookupExtendedCharset(charsetName)) != null ||
...@@ -589,6 +580,9 @@ public abstract class Charset ...@@ -589,6 +580,9 @@ public abstract class Charset
new TreeMap<String,Charset>( new TreeMap<String,Charset>(
ASCIICaseInsensitiveComparator.CASE_INSENSITIVE_ORDER); ASCIICaseInsensitiveComparator.CASE_INSENSITIVE_ORDER);
put(standardProvider.charsets(), m); put(standardProvider.charsets(), m);
CharsetProvider ecp = ExtendedProviderHolder.extendedProvider;
if (ecp != null)
put(ecp.charsets(), m);
for (Iterator<CharsetProvider> i = providers(); i.hasNext();) { for (Iterator<CharsetProvider> i = providers(); i.hasNext();) {
CharsetProvider cp = i.next(); CharsetProvider cp = i.next();
put(cp.charsets(), m); put(cp.charsets(), m);
......
...@@ -47,17 +47,17 @@ public class ISO2022_JP_2 extends ISO2022_JP ...@@ -47,17 +47,17 @@ public class ISO2022_JP_2 extends ISO2022_JP
} }
public CharsetDecoder newDecoder() { public CharsetDecoder newDecoder() {
return new Decoder(this, Decoder.DEC0208, DEC0212); return new Decoder(this, Decoder.DEC0208, CoderHolder.DEC0212);
} }
public CharsetEncoder newEncoder() { public CharsetEncoder newEncoder() {
return new Encoder(this, Encoder.ENC0208, ENC0212, true); return new Encoder(this, Encoder.ENC0208, CoderHolder.ENC0212, true);
} }
private final static DoubleByte.Decoder DEC0212 = private static class CoderHolder {
final static DoubleByte.Decoder DEC0212 =
(DoubleByte.Decoder)new JIS_X_0212().newDecoder(); (DoubleByte.Decoder)new JIS_X_0212().newDecoder();
final static DoubleByte.Encoder ENC0212 =
private final static DoubleByte.Encoder ENC0212 =
(DoubleByte.Encoder)new JIS_X_0212().newEncoder(); (DoubleByte.Encoder)new JIS_X_0212().newEncoder();
}
} }
# NIO charset SPI extended charset provider
sun.nio.cs.ext.ExtendedCharsets
...@@ -46,16 +46,17 @@ public class MSISO2022JP extends ISO2022_JP ...@@ -46,16 +46,17 @@ public class MSISO2022JP extends ISO2022_JP
} }
public CharsetDecoder newDecoder() { public CharsetDecoder newDecoder() {
return new Decoder(this, DEC0208, null); return new Decoder(this, CoderHolder.DEC0208, null);
} }
public CharsetEncoder newEncoder() { public CharsetEncoder newEncoder() {
return new Encoder(this, ENC0208, null, true); return new Encoder(this, CoderHolder.ENC0208, null, true);
} }
private final static DoubleByte.Decoder DEC0208 = private static class CoderHolder {
final static DoubleByte.Decoder DEC0208 =
(DoubleByte.Decoder)new JIS_X_0208_MS932().newDecoder(); (DoubleByte.Decoder)new JIS_X_0208_MS932().newDecoder();
final static DoubleByte.Encoder ENC0208 =
private final static DoubleByte.Encoder ENC0208 =
(DoubleByte.Encoder)new JIS_X_0208_MS932().newEncoder(); (DoubleByte.Encoder)new JIS_X_0208_MS932().newEncoder();
}
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册