8012326: Deadlock occurs when Charset.availableCharsets() is called by several threads at the same time
Removed the race condition risk from ExtendedCahrset access code Reviewed-by: mchung, alanb
This commit is contained in:
parent
4e50454550
commit
1e18db55d6
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -1,2 +0,0 @@
|
||||
# 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();
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user