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.
|
# 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): \
|
|||||||
$(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
|
|||||||
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 += \
|
|||||||
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,,\
|
|||||||
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
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 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
|
|||||||
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
|
|||||||
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
|
|||||||
}
|
}
|
||||||
|
|
||||||
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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() {
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user