OpenJDK / jdk7u / jdk7u-dev / jdk
changeset 6619:6126a0662727
8012326: Deadlock occurs when Charset.availableCharsets() is called by several threads at the same time
Summary: removed the race condition risk from ExtendedCharset access code
Reviewed-by: sherman
author | coffeys |
---|---|
date | Wed, 16 Oct 2013 05:49:30 +0100 |
parents | cfd96c6d47c6 |
children | c421ade4c566 |
files | make/sun/nio/cs/Makefile src/share/classes/java/nio/charset/Charset.java src/share/classes/sun/nio/cs/ext/META-INF/services/java.nio.charset.spi.CharsetProvider |
diffstat | 3 files changed, 27 insertions(+), 41 deletions(-) [+] |
line wrap: on
line diff
--- a/make/sun/nio/cs/Makefile Tue Oct 15 12:55:39 2013 -0700 +++ b/make/sun/nio/cs/Makefile Wed Oct 16 05:49:30 2013 +0100 @@ -85,9 +85,6 @@ # # 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 @@ -116,10 +113,6 @@ $(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 @@ -127,10 +120,9 @@ 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)
--- a/src/share/classes/java/nio/charset/Charset.java Tue Oct 15 12:55:39 2013 -0700 +++ b/src/share/classes/java/nio/charset/Charset.java Wed Oct 16 05:49:30 2013 +0100 @@ -426,39 +426,32 @@ } /* 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; } @@ -588,6 +581,9 @@ 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 i = providers(); i.hasNext();) { CharsetProvider cp = (CharsetProvider)i.next(); put(cp.charsets(), m);