8221882: Use fiber-friendly java.util.concurrent.locks in JSSE

Reviewed-by: alanb, dfuchs
This commit is contained in:
Xue-Lei Andrew Fan 2019-04-05 11:28:23 -07:00
parent 6d617481d4
commit 8263b618ba
22 changed files with 1672 additions and 1020 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -26,8 +26,9 @@
package javax.net.ssl;
import java.security.*;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
import java.util.Objects;
import sun.security.jca.GetInstance;
/**
@ -58,6 +59,20 @@ public class SSLContext {
private final String protocol;
private static volatile SSLContext defaultContext;
private static final VarHandle VH_DEFAULT_CONTEXT;
static {
try {
VH_DEFAULT_CONTEXT = MethodHandles.lookup()
.findStaticVarHandle(
SSLContext.class, "defaultContext", SSLContext.class);
} catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
}
/**
* Creates an SSLContext object.
*
@ -72,8 +87,6 @@ public class SSLContext {
this.protocol = protocol;
}
private static SSLContext defaultContext;
/**
* Returns the default SSL context.
*
@ -91,12 +104,16 @@ public class SSLContext {
* {@link SSLContext#getInstance SSLContext.getInstance()} call fails
* @since 1.6
*/
public static synchronized SSLContext getDefault()
throws NoSuchAlgorithmException {
if (defaultContext == null) {
defaultContext = SSLContext.getInstance("Default");
public static SSLContext getDefault() throws NoSuchAlgorithmException {
SSLContext temporaryContext = defaultContext;
if (temporaryContext == null) {
temporaryContext = SSLContext.getInstance("Default");
if (!VH_DEFAULT_CONTEXT.compareAndSet(null, temporaryContext)) {
temporaryContext = defaultContext;
}
}
return defaultContext;
return temporaryContext;
}
/**
@ -111,7 +128,7 @@ public class SSLContext {
* {@code SSLPermission("setDefaultSSLContext")}
* @since 1.6
*/
public static synchronized void setDefault(SSLContext context) {
public static void setDefault(SSLContext context) {
if (context == null) {
throw new NullPointerException();
}
@ -119,6 +136,7 @@ public class SSLContext {
if (sm != null) {
sm.checkPermission(new SSLPermission("setDefaultSSLContext"));
}
defaultContext = context;
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -42,17 +42,7 @@ import java.security.*;
* @see SSLServerSocket
* @author David Brownell
*/
public abstract class SSLServerSocketFactory extends ServerSocketFactory
{
private static SSLServerSocketFactory theFactory;
private static boolean propertyChecked;
private static void log(String msg) {
if (SSLSocketFactory.DEBUG) {
System.out.println(msg);
}
}
public abstract class SSLServerSocketFactory extends ServerSocketFactory {
/**
* Constructor is used only by subclasses.
@ -75,39 +65,9 @@ public abstract class SSLServerSocketFactory extends ServerSocketFactory
* @return the default <code>ServerSocketFactory</code>
* @see SSLContext#getDefault
*/
public static synchronized ServerSocketFactory getDefault() {
if (theFactory != null) {
return theFactory;
}
if (propertyChecked == false) {
propertyChecked = true;
String clsName = SSLSocketFactory.getSecurityProperty
("ssl.ServerSocketFactory.provider");
if (clsName != null) {
log("setting up default SSLServerSocketFactory");
try {
Class<?> cls = null;
try {
cls = Class.forName(clsName);
} catch (ClassNotFoundException e) {
ClassLoader cl = ClassLoader.getSystemClassLoader();
if (cl != null) {
cls = cl.loadClass(clsName);
}
}
log("class " + clsName + " is loaded");
@SuppressWarnings("deprecation")
SSLServerSocketFactory fac = (SSLServerSocketFactory)cls.newInstance();
log("instantiated an instance of class " + clsName);
theFactory = fac;
return fac;
} catch (Exception e) {
log("SSLServerSocketFactory instantiation failed: " + e);
theFactory = new DefaultSSLServerSocketFactory(e);
return theFactory;
}
}
public static ServerSocketFactory getDefault() {
if (DefaultFactoryHolder.defaultFactory != null) {
return DefaultFactoryHolder.defaultFactory;
}
try {
@ -156,8 +116,50 @@ public abstract class SSLServerSocketFactory extends ServerSocketFactory
* @see #getDefaultCipherSuites()
*/
public abstract String [] getSupportedCipherSuites();
}
// lazy initialization holder class idiom for static default factory
//
// See Effective Java Second Edition: Item 71.
private static final class DefaultFactoryHolder {
private static final SSLServerSocketFactory defaultFactory;
static {
SSLServerSocketFactory mediator = null;
String clsName = SSLSocketFactory.getSecurityProperty(
"ssl.ServerSocketFactory.provider");
if (clsName != null) {
log("setting up default SSLServerSocketFactory");
try {
Class<?> cls = null;
try {
cls = Class.forName(clsName);
} catch (ClassNotFoundException e) {
ClassLoader cl = ClassLoader.getSystemClassLoader();
if (cl != null) {
cls = cl.loadClass(clsName);
}
}
log("class " + clsName + " is loaded");
mediator = (SSLServerSocketFactory)cls
.getDeclaredConstructor().newInstance();
log("instantiated an instance of class " + clsName);
} catch (Exception e) {
log("SSLServerSocketFactory instantiation failed: " + e);
mediator = new DefaultSSLServerSocketFactory(e);
}
}
defaultFactory = mediator;
}
private static void log(String msg) {
if (SSLSocketFactory.DEBUG) {
System.out.println(msg);
}
}
}
}
//
// The default factory does NOTHING.

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -42,31 +42,20 @@ import sun.security.action.GetPropertyAction;
* @see SSLSocket
* @author David Brownell
*/
public abstract class SSLSocketFactory extends SocketFactory
{
private static SSLSocketFactory theFactory;
private static boolean propertyChecked;
public abstract class SSLSocketFactory extends SocketFactory {
static final boolean DEBUG;
static {
String s = GetPropertyAction.privilegedGetProperty("javax.net.debug", "")
.toLowerCase(Locale.ENGLISH);
String s = GetPropertyAction.privilegedGetProperty(
"javax.net.debug", "").toLowerCase(Locale.ENGLISH);
DEBUG = s.contains("all") || s.contains("ssl");
}
private static void log(String msg) {
if (DEBUG) {
System.out.println(msg);
}
}
/**
* Constructor is used only by subclasses.
*/
public SSLSocketFactory() {
// blank
}
/**
@ -85,38 +74,9 @@ public abstract class SSLSocketFactory extends SocketFactory
* @return the default <code>SocketFactory</code>
* @see SSLContext#getDefault
*/
public static synchronized SocketFactory getDefault() {
if (theFactory != null) {
return theFactory;
}
if (propertyChecked == false) {
propertyChecked = true;
String clsName = getSecurityProperty("ssl.SocketFactory.provider");
if (clsName != null) {
log("setting up default SSLSocketFactory");
try {
Class<?> cls = null;
try {
cls = Class.forName(clsName);
} catch (ClassNotFoundException e) {
ClassLoader cl = ClassLoader.getSystemClassLoader();
if (cl != null) {
cls = cl.loadClass(clsName);
}
}
log("class " + clsName + " is loaded");
@SuppressWarnings("deprecation")
SSLSocketFactory fac = (SSLSocketFactory)cls.newInstance();
log("instantiated an instance of class " + clsName);
theFactory = fac;
return fac;
} catch (Exception e) {
log("SSLSocketFactory instantiation failed: " + e.toString());
theFactory = new DefaultSSLSocketFactory(e);
return theFactory;
}
}
public static SocketFactory getDefault() {
if (DefaultFactoryHolder.defaultFactory != null) {
return DefaultFactoryHolder.defaultFactory;
}
try {
@ -246,6 +206,49 @@ public abstract class SSLSocketFactory extends SocketFactory
boolean autoClose) throws IOException {
throw new UnsupportedOperationException();
}
// lazy initialization holder class idiom for static default factory
//
// See Effective Java Second Edition: Item 71.
private static final class DefaultFactoryHolder {
private static final SSLSocketFactory defaultFactory;
static {
SSLSocketFactory mediator = null;
String clsName = getSecurityProperty("ssl.SocketFactory.provider");
if (clsName != null) {
log("setting up default SSLSocketFactory");
try {
Class<?> cls = null;
try {
cls = Class.forName(clsName);
} catch (ClassNotFoundException e) {
ClassLoader cl = ClassLoader.getSystemClassLoader();
if (cl != null) {
cls = cl.loadClass(clsName);
}
}
log("class " + clsName + " is loaded");
mediator = (SSLSocketFactory)cls
.getDeclaredConstructor().newInstance();
log("instantiated an instance of class " + clsName);
} catch (Exception e) {
log("SSLSocketFactory instantiation failed: " + e);
mediator = new DefaultSSLSocketFactory(e);
}
}
defaultFactory = mediator;
}
private static void log(String msg) {
if (DEBUG) {
System.out.println(msg);
}
}
}
}