提交 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)
#
# 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
GENCSSRCDIR = $(BUILDDIR)/tools/src/build/tools/charsetmapping
GENCSEXT = $(GENSRCDIR)/sun/nio/cs/ext
......@@ -118,10 +115,6 @@ $(FILES_genout_extcs): \
$(GENCSSRCDIR)/HKSCS.java
$(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
ifndef COMPRESS_JARS
CREATE_JAR_OPTS_NOMANIFEST = cf0
......@@ -129,10 +122,9 @@ else
CREATE_JAR_OPTS_NOMANIFEST = cf
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) \
-C $(CLASSDESTDIR) sun \
-C $(CLASSDESTDIR) $(SERVICE_DESCRIPTION_PATH) \
$(BOOT_JAR_JFLAGS)
@$(java-vm-cleanup)
......
......@@ -201,7 +201,6 @@ RT_JAR_EXCLUDES += \
META-INF/services/com.sun.jdi.connect.spi.TransportService \
META-INF/services/com.sun.tools.attach.spi.AttachProvider \
META-INF/services/com.sun.tools.xjc.Plugin \
META-INF/services/java.nio.charset.spi.CharsetProvider \
META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor \
org/relaxng/datatype \
sun/awt/HKSCS.class \
......@@ -428,8 +427,7 @@ $(eval $(call SetupArchive,BUILD_CHARSETS_JAR,,\
SUFFIXES:=.class .dat,\
INCLUDES:=sun/nio/cs/ext,\
EXTRA_FILES := sun/awt/HKSCS.class \
$(CHARSETS_EXTRA_FILES) \
META-INF/services/java.nio.charset.spi.CharsetProvider, \
$(CHARSETS_EXTRA_FILES), \
JAR:=$(IMAGES_OUTPUTDIR)/lib/charsets.jar, \
SKIP_METAINF := true, \
CHECK_COMPRESS_JAR:=true))
......
......@@ -427,46 +427,38 @@ public abstract class Charset
}
/* The extended set of charsets */
private static Object extendedProviderLock = new Object();
private static boolean extendedProviderProbed = false;
private static CharsetProvider extendedProvider = null;
private static void probeExtendedProvider() {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
try {
Class<?> epc
= Class.forName("sun.nio.cs.ext.ExtendedCharsets");
extendedProvider = (CharsetProvider)epc.newInstance();
} catch (ClassNotFoundException x) {
// Extended charsets not available
// (charsets.jar not present)
} catch (InstantiationException x) {
throw new Error(x);
} catch (IllegalAccessException x) {
throw new Error(x);
}
return null;
}
});
private static class ExtendedProviderHolder {
static final CharsetProvider extendedProvider = extendedProvider();
// returns ExtendedProvider, if installed
private static CharsetProvider extendedProvider() {
return AccessController.doPrivileged(
new PrivilegedAction<CharsetProvider>() {
public CharsetProvider run() {
try {
Class<?> epc
= Class.forName("sun.nio.cs.ext.ExtendedCharsets");
return (CharsetProvider)epc.newInstance();
} catch (ClassNotFoundException x) {
// Extended charsets not available
// (charsets.jar not present)
} catch (InstantiationException |
IllegalAccessException x) {
throw new Error(x);
}
return null;
}
});
}
}
private static Charset lookupExtendedCharset(String charsetName) {
CharsetProvider ecp = null;
synchronized (extendedProviderLock) {
if (!extendedProviderProbed) {
probeExtendedProvider();
extendedProviderProbed = true;
}
ecp = extendedProvider;
}
CharsetProvider ecp = ExtendedProviderHolder.extendedProvider;
return (ecp != null) ? ecp.charsetForName(charsetName) : null;
}
private static Charset lookup(String charsetName) {
if (charsetName == null)
throw new IllegalArgumentException("Null charset name");
Object[] a;
if ((a = cache1) != null && charsetName.equals(a[0]))
return (Charset)a[1];
......@@ -483,7 +475,6 @@ public abstract class Charset
cache1 = a;
return (Charset)a[1];
}
Charset cs;
if ((cs = standardProvider.charsetForName(charsetName)) != null ||
(cs = lookupExtendedCharset(charsetName)) != null ||
......@@ -589,6 +580,9 @@ public abstract class Charset
new TreeMap<String,Charset>(
ASCIICaseInsensitiveComparator.CASE_INSENSITIVE_ORDER);
put(standardProvider.charsets(), m);
CharsetProvider ecp = ExtendedProviderHolder.extendedProvider;
if (ecp != null)
put(ecp.charsets(), m);
for (Iterator<CharsetProvider> i = providers(); i.hasNext();) {
CharsetProvider cp = i.next();
put(cp.charsets(), m);
......
......@@ -47,17 +47,17 @@ public class ISO2022_JP_2 extends ISO2022_JP
}
public CharsetDecoder newDecoder() {
return new Decoder(this, Decoder.DEC0208, DEC0212);
return new Decoder(this, Decoder.DEC0208, CoderHolder.DEC0212);
}
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 =
(DoubleByte.Decoder)new JIS_X_0212().newDecoder();
private final static DoubleByte.Encoder ENC0212 =
(DoubleByte.Encoder)new JIS_X_0212().newEncoder();
private static class CoderHolder {
final static DoubleByte.Decoder DEC0212 =
(DoubleByte.Decoder)new JIS_X_0212().newDecoder();
final static DoubleByte.Encoder ENC0212 =
(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
}
public CharsetDecoder newDecoder() {
return new Decoder(this, DEC0208, null);
return new Decoder(this, CoderHolder.DEC0208, null);
}
public CharsetEncoder newEncoder() {
return new Encoder(this, ENC0208, null, true);
return new Encoder(this, CoderHolder.ENC0208, null, true);
}
private final static DoubleByte.Decoder DEC0208 =
(DoubleByte.Decoder)new JIS_X_0208_MS932().newDecoder();
private final static DoubleByte.Encoder ENC0208 =
(DoubleByte.Encoder)new JIS_X_0208_MS932().newEncoder();
private static class CoderHolder {
final static DoubleByte.Decoder DEC0208 =
(DoubleByte.Decoder)new JIS_X_0208_MS932().newDecoder();
final static DoubleByte.Encoder ENC0208 =
(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.
先完成此消息的编辑!
想要评论请 注册