This commit is contained in:
Lana Steuck 2018-02-09 02:23:34 +00:00
commit 845f7823de
1200 changed files with 35255 additions and 79887 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2018, 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
@ -66,6 +66,8 @@ class LinuxFileStore
}
// step 2: find mount point
List<UnixMountEntry> procMountsEntries =
fs.getMountEntries("/proc/mounts");
UnixPath parent = path.getParent();
while (parent != null) {
UnixFileAttributes attrs = null;
@ -74,16 +76,23 @@ class LinuxFileStore
} catch (UnixException x) {
x.rethrowAsIOException(parent);
}
if (attrs.dev() != dev())
break;
if (attrs.dev() != dev()) {
// step 3: lookup mounted file systems (use /proc/mounts to
// ensure we find the file system even when not in /etc/mtab)
byte[] dir = path.asByteArray();
for (UnixMountEntry entry : procMountsEntries) {
if (Arrays.equals(dir, entry.dir()))
return entry;
}
}
path = parent;
parent = parent.getParent();
}
// step 3: lookup mounted file systems (use /proc/mounts to ensure we
// find the file system even when not in /etc/mtab)
// step 3: lookup mounted file systems (use /proc/mounts to
// ensure we find the file system even when not in /etc/mtab)
byte[] dir = path.asByteArray();
for (UnixMountEntry entry: fs.getMountEntries("/proc/mounts")) {
for (UnixMountEntry entry : procMountsEntries) {
if (Arrays.equals(dir, entry.dir()))
return entry;
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2018, 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
@ -75,7 +75,7 @@ class LinuxFileSystem extends UnixFileSystem {
/**
* Returns object to iterate over the mount entries in the given fstab file.
*/
Iterable<UnixMountEntry> getMountEntries(String fstab) {
List<UnixMountEntry> getMountEntries(String fstab) {
ArrayList<UnixMountEntry> entries = new ArrayList<>();
try {
long fp = setmntent(Util.toBytes(fstab), Util.toBytes("r"));
@ -101,7 +101,7 @@ class LinuxFileSystem extends UnixFileSystem {
* Returns object to iterate over the mount entries in /etc/mtab
*/
@Override
Iterable<UnixMountEntry> getMountEntries() {
List<UnixMountEntry> getMountEntries() {
return getMountEntries("/etc/mtab");
}

View file

@ -48,6 +48,7 @@ class Constants {
1.8 to 1.8.X 52,0
1.9 to 1.9.X 53,0
1.10 to 1.10.X 54,0
1.11 to 1.11.X 55,0
*/
public static final Package.Version JAVA_MIN_CLASS_VERSION =
@ -71,6 +72,9 @@ class Constants {
public static final Package.Version JAVA10_MAX_CLASS_VERSION =
Package.Version.of(54, 00);
public static final Package.Version JAVA11_MAX_CLASS_VERSION =
Package.Version.of(55, 00);
public static final int JAVA_PACKAGE_MAGIC = 0xCAFED00D;
public static final Package.Version JAVA5_PACKAGE_VERSION =
@ -87,7 +91,7 @@ class Constants {
// upper limit, should point to the latest class version
public static final Package.Version JAVA_MAX_CLASS_VERSION =
JAVA10_MAX_CLASS_VERSION;
JAVA11_MAX_CLASS_VERSION;
// upper limit should point to the latest package version, for version info!.
public static final Package.Version MAX_PACKAGE_VERSION =

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2018, 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
@ -162,11 +162,12 @@ class Driver {
engProps.put((String) me.getKey(), (String) me.getValue());
}
} else if ("--version".equals(state)) {
System.out.println(MessageFormat.format(RESOURCE.getString(DriverResource.VERSION), Driver.class.getName(), "1.31, 07/05/05"));
System.out.println(MessageFormat.format(RESOURCE.getString(DriverResource.VERSION),
Driver.class.getName(), "1.31, 07/05/05"));
return;
} else if ("--help".equals(state)) {
printUsage(doPack, true, System.out);
System.exit(1);
System.exit(0);
return;
} else {
break;

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2018, 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
@ -89,7 +89,7 @@ public class DriverResource extends ListResourceBundle {
" -q, --quiet set verbosity to lowest level",
" -l{F}, --log-file={F} output to the given log file, ",
" or '-' for System.out",
" -?, -h, --help print this message",
" -?, -h, --help print this help message",
" -V, --version print program version",
" -J{X} pass option X to underlying Java VM",
"",
@ -118,7 +118,7 @@ public class DriverResource extends ListResourceBundle {
" -q, --quiet set verbosity to lowest level",
" -l{F}, --log-file={F} output to the given log file, or",
" '-' for System.out",
" -?, -h, --help print this message",
" -?, -h, --help print this help message",
" -V, --version print program version",
" -J{X} pass option X to underlying Java VM"
}

View file

@ -27,6 +27,7 @@ package java.io;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Objects;
/**
* This class implements an output stream in which the data is
@ -147,10 +148,7 @@ public class ByteArrayOutputStream extends OutputStream {
* @param len the number of bytes to write.
*/
public synchronized void write(byte b[], int off, int len) {
if ((off < 0) || (off > b.length) || (len < 0) ||
((off + len) - b.length > 0)) {
throw new IndexOutOfBoundsException();
}
Objects.checkFromIndexSize(off, len, b.length);
ensureCapacity(count + len);
System.arraycopy(b, off, buf, count, len);
count += len;

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1994, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1994, 2018, 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
@ -2256,7 +2256,7 @@ public class File
private transient volatile Path filePath;
/**
* Returns a {@link Path java.nio.file.Path} object constructed from the
* Returns a {@link Path java.nio.file.Path} object constructed from
* this abstract path. The resulting {@code Path} is associated with the
* {@link java.nio.file.FileSystems#getDefault default-filesystem}.
*

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1994, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1994, 2018, 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
@ -25,7 +25,9 @@
package java.io;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
/**
@ -53,6 +55,103 @@ public abstract class InputStream implements Closeable {
private static final int DEFAULT_BUFFER_SIZE = 8192;
/**
* Returns a new {@code InputStream} that reads no bytes. The returned
* stream is initially open. The stream is closed by calling the
* {@code close()} method. Subsequent calls to {@code close()} have no
* effect.
*
* <p> While the stream is open, the {@code available()}, {@code read()},
* {@code read(byte[])}, {@code read(byte[], int, int)},
* {@code readAllBytes()}, {@code readNBytes(byte[], int, int)},
* {@code readNBytes(int)}, {@code skip(long)}, and
* {@code transferTo()} methods all behave as if end of stream has been
* reached. After the stream has been closed, these methods all throw
* {@code IOException}.
*
* <p> The {@code markSupported()} method returns {@code false}. The
* {@code mark()} method does nothing, and the {@code reset()} method
* throws {@code IOException}.
*
* @return an {@code InputStream} which contains no bytes
*
* @since 11
*/
public static InputStream nullInputStream() {
return new InputStream() {
private volatile boolean closed;
private void ensureOpen() throws IOException {
if (closed) {
throw new IOException("Stream closed");
}
}
@Override
public int available () throws IOException {
ensureOpen();
return 0;
}
@Override
public int read() throws IOException {
ensureOpen();
return -1;
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
Objects.checkFromIndexSize(off, len, b.length);
if (len == 0) {
return 0;
}
ensureOpen();
return -1;
}
@Override
public byte[] readAllBytes() throws IOException {
ensureOpen();
return new byte[0];
}
@Override
public int readNBytes(byte[] b, int off, int len)
throws IOException {
Objects.checkFromIndexSize(off, len, b.length);
ensureOpen();
return 0;
}
@Override
public byte[] readNBytes(int len) throws IOException {
if (len < 0) {
throw new IllegalArgumentException("len < 0");
}
ensureOpen();
return new byte[0];
}
@Override
public long skip(long n) throws IOException {
ensureOpen();
return 0L;
}
@Override
public long transferTo(OutputStream out) throws IOException {
Objects.requireNonNull(out);
ensureOpen();
return 0L;
}
@Override
public void close() throws IOException {
closed = true;
}
};
}
/**
* Reads the next byte of data from the input stream. The value byte is
* returned as an <code>int</code> in the range <code>0</code> to
@ -144,8 +243,8 @@ public abstract class InputStream implements Closeable {
* <code>b</code> and the number of bytes read before the exception
* occurred is returned. The default implementation of this method blocks
* until the requested amount of input data <code>len</code> has been read,
* end of file is detected, or an exception is thrown. Subclasses are encouraged
* to provide a more efficient implementation of this method.
* end of file is detected, or an exception is thrown. Subclasses are
* encouraged to provide a more efficient implementation of this method.
*
* @param b the buffer into which the data is read.
* @param off the start offset in array <code>b</code>
@ -164,7 +263,6 @@ public abstract class InputStream implements Closeable {
* @see java.io.InputStream#read()
*/
public int read(byte b[], int off, int len) throws IOException {
Objects.requireNonNull(b);
Objects.checkFromIndexSize(off, len, b.length);
if (len == 0) {
return 0;
@ -220,39 +318,125 @@ public abstract class InputStream implements Closeable {
* It is strongly recommended that the stream be promptly closed if an I/O
* error occurs.
*
* @implSpec
* This method invokes {@link #readNBytes(int)} with a length of
* {@link Integer#MAX_VALUE}.
*
* @return a byte array containing the bytes read from this input stream
* @throws IOException if an I/O error occurs
* @throws OutOfMemoryError if an array of the required size cannot be
* allocated. For example, if an array larger than {@code 2GB} would
* be required to store the bytes.
* allocated.
*
* @since 9
*/
public byte[] readAllBytes() throws IOException {
byte[] buf = new byte[DEFAULT_BUFFER_SIZE];
int capacity = buf.length;
int nread = 0;
int n;
for (;;) {
// read to EOF which may read more or less than initial buffer size
while ((n = read(buf, nread, capacity - nread)) > 0)
nread += n;
return readNBytes(Integer.MAX_VALUE);
}
// if the last call to read returned -1, then we're done
if (n < 0)
break;
// need to allocate a larger buffer
if (capacity <= MAX_BUFFER_SIZE - capacity) {
capacity = capacity << 1;
} else {
if (capacity == MAX_BUFFER_SIZE)
throw new OutOfMemoryError("Required array size too large");
capacity = MAX_BUFFER_SIZE;
}
buf = Arrays.copyOf(buf, capacity);
/**
* Reads up to a specified number of bytes from the input stream. This
* method blocks until the requested number of bytes have been read, end
* of stream is detected, or an exception is thrown. This method does not
* close the input stream.
*
* <p> The length of the returned array equals the number of bytes read
* from the stream. If {@code len} is zero, then no bytes are read and
* an empty byte array is returned. Otherwise, up to {@code len} bytes
* are read from the stream. Fewer than {@code len} bytes may be read if
* end of stream is encountered.
*
* <p> When this stream reaches end of stream, further invocations of this
* method will return an empty byte array.
*
* <p> Note that this method is intended for simple cases where it is
* convenient to read the specified number of bytes into a byte array. The
* total amount of memory allocated by this method is proportional to the
* number of bytes read from the stream which is bounded by {@code len}.
* Therefore, the method may be safely called with very large values of
* {@code len} provided sufficient memory is available.
*
* <p> The behavior for the case where the input stream is <i>asynchronously
* closed</i>, or the thread interrupted during the read, is highly input
* stream specific, and therefore not specified.
*
* <p> If an I/O error occurs reading from the input stream, then it may do
* so after some, but not all, bytes have been read. Consequently the input
* stream may not be at end of stream and may be in an inconsistent state.
* It is strongly recommended that the stream be promptly closed if an I/O
* error occurs.
*
* @implNote
* The number of bytes allocated to read data from this stream and return
* the result is bounded by {@code 2*(long)len}, inclusive.
*
* @param len the maximum number of bytes to read
* @return a byte array containing the bytes read from this input stream
* @throws IllegalArgumentException if {@code length} is negative
* @throws IOException if an I/O error occurs
* @throws OutOfMemoryError if an array of the required size cannot be
* allocated.
*
* @since 11
*/
public byte[] readNBytes(int len) throws IOException {
if (len < 0) {
throw new IllegalArgumentException("len < 0");
}
return (capacity == nread) ? buf : Arrays.copyOf(buf, nread);
List<byte[]> bufs = null;
byte[] result = null;
int total = 0;
int remaining = len;
int n;
do {
byte[] buf = new byte[Math.min(remaining, DEFAULT_BUFFER_SIZE)];
int nread = 0;
// read to EOF which may read more or less than buffer size
while ((n = read(buf, nread,
Math.min(buf.length - nread, remaining))) > 0) {
nread += n;
remaining -= n;
}
if (nread > 0) {
if (MAX_BUFFER_SIZE - total < nread) {
throw new OutOfMemoryError("Required array size too large");
}
total += nread;
if (result == null) {
result = buf;
} else {
if (bufs == null) {
bufs = new ArrayList<>();
bufs.add(result);
}
bufs.add(buf);
}
}
// if the last call to read returned -1 or the number of bytes
// requested have been read then break
} while (n >= 0 && remaining > 0);
if (bufs == null) {
if (result == null) {
return new byte[0];
}
return result.length == total ?
result : Arrays.copyOf(result, total);
}
result = new byte[total];
int offset = 0;
remaining = total;
for (byte[] b : bufs) {
int count = Math.min(b.length, remaining);
System.arraycopy(b, 0, result, offset, count);
offset += count;
remaining -= count;
}
return result;
}
/**
@ -299,7 +483,6 @@ public abstract class InputStream implements Closeable {
* @since 9
*/
public int readNBytes(byte[] b, int off, int len) throws IOException {
Objects.requireNonNull(b);
Objects.checkFromIndexSize(off, len, b.length);
int n = 0;

View file

@ -1296,7 +1296,6 @@ public class ObjectInputStream
* @throws InvalidClassException if the filter rejects creation
*/
private void checkArray(Class<?> arrayType, int arrayLength) throws InvalidClassException {
Objects.requireNonNull(arrayType);
if (! arrayType.isArray()) {
throw new IllegalArgumentException("not an array type");
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1994, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1994, 2018, 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
@ -46,6 +46,51 @@ import java.util.Objects;
* @since 1.0
*/
public abstract class OutputStream implements Closeable, Flushable {
/**
* Returns a new {@code OutputStream} which discards all bytes. The
* returned stream is initially open. The stream is closed by calling
* the {@code close()} method. Subsequent calls to {@code close()} have
* no effect.
*
* <p> While the stream is open, the {@code write(int)}, {@code
* write(byte[])}, and {@code write(byte[], int, int)} methods do nothing.
* After the stream has been closed, these methods all throw {@code
* IOException}.
*
* <p> The {@code flush()} method does nothing.
*
* @return an {@code OutputStream} which discards all bytes
*
* @since 11
*/
public static OutputStream nullOutputStream() {
return new OutputStream() {
private volatile boolean closed;
private void ensureOpen() throws IOException {
if (closed) {
throw new IOException("Stream closed");
}
}
@Override
public void write(int b) throws IOException {
ensureOpen();
}
@Override
public void write(byte b[], int off, int len) throws IOException {
Objects.checkFromIndexSize(off, len, b.length);
ensureOpen();
}
@Override
public void close() {
closed = true;
}
};
}
/**
* Writes the specified byte to this output stream. The general
* contract for <code>write</code> is that one byte is written
@ -106,7 +151,6 @@ public abstract class OutputStream implements Closeable, Flushable {
* stream is closed.
*/
public void write(byte b[], int off, int len) throws IOException {
Objects.requireNonNull(b);
Objects.checkFromIndexSize(off, len, b.length);
// len == 0 condition implicitly handled by loop bounds
for (int i = 0 ; i < len ; i++) {

View file

@ -1876,14 +1876,15 @@ public abstract class ClassLoader {
* value until the system is fully initialized.
*
* <p> The name of the built-in system class loader is {@code "app"}.
* The class path used by the built-in system class loader is determined
* by the system property "{@code java.class.path}" during early
* initialization of the VM. If the system property is not defined,
* or its value is an empty string, then there is no class path
* when the initial module is a module on the application module path,
* i.e. <em>a named module</em>. If the initial module is not on
* the application module path then the class path defaults to
* the current working directory.
* The system property "{@code java.class.path}" is read during early
* initialization of the VM to determine the class path.
* An empty value of "{@code java.class.path}" property is interpreted
* differently depending on whether the initial module (the module
* containing the main class) is named or unnamed:
* If named, the built-in system class loader will have no class path and
* will search for classes and resources using the application module path;
* otherwise, if unnamed, it will set the class path to the current
* working directory.
*
* @return The system {@code ClassLoader}
*

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1995, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1995, 2018, 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
@ -1099,16 +1099,23 @@ public class Runtime {
m.group(VersionPattern.OPT_GROUP));
// empty '+'
if ((m.group(VersionPattern.PLUS_GROUP) != null)
&& !build.isPresent()) {
if (optional.isPresent()) {
if (pre.isPresent())
throw new IllegalArgumentException("'+' found with"
+ " pre-release and optional components:'" + s
+ "'");
if (!build.isPresent()) {
if (m.group(VersionPattern.PLUS_GROUP) != null) {
if (optional.isPresent()) {
if (pre.isPresent())
throw new IllegalArgumentException("'+' found with"
+ " pre-release and optional components:'" + s
+ "'");
} else {
throw new IllegalArgumentException("'+' found with neither"
+ " build or optional components: '" + s + "'");
}
} else {
throw new IllegalArgumentException("'+' found with neither"
+ " build or optional components: '" + s + "'");
if (optional.isPresent() && !pre.isPresent()) {
throw new IllegalArgumentException("optional component"
+ " must be preceeded by a pre-release component"
+ " or '+': '" + s + "'");
}
}
}
return new Version(List.of(version), pre, build, optional);

View file

@ -631,7 +631,8 @@ public final class System {
* <tr><th scope="row"><code>java.class.version</code></th>
* <td>Java class format version number</td></tr>
* <tr><th scope="row"><code>java.class.path</code></th>
* <td>Java class path</td></tr>
* <td>Java class path (refer to
* {@link ClassLoader#getSystemClassLoader()} for details)</td></tr>
* <tr><th scope="row"><code>java.library.path</code></th>
* <td>List of paths to search when loading libraries</td></tr>
* <tr><th scope="row"><code>java.io.tmpdir</code></th>

View file

@ -166,15 +166,8 @@ class VersionProps {
* Print version info.
*/
private static void print(boolean err, boolean newln) {
boolean isHeadless = false;
PrintStream ps = err ? System.err : System.out;
/* Report that we're running headless if the property is true */
String headless = System.getProperty("java.awt.headless");
if ( (headless != null) && (headless.equalsIgnoreCase("true")) ) {
isHeadless = true;
}
/* First line: platform version. */
if (err) {
ps.println(launcher_name + " version \"" + java_version + "\""

View file

@ -1667,6 +1667,7 @@ assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString());
/** Craft a LambdaForm customized for this particular MethodHandle */
/*non-public*/
void customize() {
final LambdaForm form = this.form;
if (form.customized == null) {
LambdaForm newForm = form.customize(this);
updateForm(newForm);

View file

@ -3766,6 +3766,7 @@ assertEquals("xy", h3.invoke("x", "y", 1, "a", "b", "c"));
* specified in the elements of the {@code filters} array.
* The first element of the filter array corresponds to the {@code pos}
* argument of the target, and so on in sequence.
* The filter functions are invoked in left to right order.
* <p>
* Null arguments in the array are treated as identity functions,
* and the corresponding arguments left unchanged.
@ -3836,11 +3837,12 @@ assertEquals("XY", (String) f2.invokeExact("x", "y")); // XY
MethodHandle filterArguments(MethodHandle target, int pos, MethodHandle... filters) {
filterArgumentsCheckArity(target, pos, filters);
MethodHandle adapter = target;
int curPos = pos-1; // pre-incremented
for (MethodHandle filter : filters) {
curPos += 1;
// process filters in reverse order so that the invocation of
// the resulting adapter will invoke the filters in left-to-right order
for (int i = filters.length - 1; i >= 0; --i) {
MethodHandle filter = filters[i];
if (filter == null) continue; // ignore null elements of filters
adapter = filterArgument(adapter, curPos, filter);
adapter = filterArgument(adapter, pos + i, filter);
}
return adapter;
}

View file

@ -2521,7 +2521,7 @@ public class ModuleDescriptor
* the {@code packageFinder} throws an {@link UncheckedIOException} then
* {@link IOException} cause will be re-thrown. </p>
*
* <p> The module descriptor is read from the buffer stating at index
* <p> The module descriptor is read from the buffer starting at index
* {@code p}, where {@code p} is the buffer's {@link ByteBuffer#position()
* position} when this method is invoked. Upon return the buffer's position
* will be equal to {@code p + n} where {@code n} is the number of bytes

View file

@ -140,14 +140,6 @@ public abstract class Reference<T> {
}
}
/*
* system property to disable clearing before enqueuing.
*/
private static final class ClearBeforeEnqueue {
static final boolean DISABLE =
Boolean.getBoolean("jdk.lang.ref.disableClearBeforeEnqueue");
}
/*
* Atomically get and clear (set to null) the VM's pending list.
*/
@ -299,8 +291,7 @@ public abstract class Reference<T> {
* it was not registered with a queue when it was created
*/
public boolean enqueue() {
if (!ClearBeforeEnqueue.DISABLE)
this.referent = null;
this.referent = null;
return this.queue.enqueue(this);
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2018, 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,11 +26,11 @@ package java.net;
import java.io.FileDescriptor;
import java.io.IOException;
import java.security.AccessController;
import sun.net.ResourceManager;
import java.util.Set;
import java.util.HashSet;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import sun.net.ResourceManager;
import sun.security.action.GetPropertyAction;
/**
@ -115,6 +115,7 @@ abstract class AbstractPlainDatagramSocketImpl extends DatagramSocketImpl
fd = new FileDescriptor();
try {
datagramSocketCreate();
SocketCleanable.register(fd);
} catch (SocketException ioe) {
ResourceManager.afterUdpClose();
fd = null;
@ -265,6 +266,7 @@ abstract class AbstractPlainDatagramSocketImpl extends DatagramSocketImpl
*/
protected void close() {
if (fd != null) {
SocketCleanable.unregister(fd);
datagramSocketClose();
ResourceManager.afterUdpClose();
fd = null;
@ -275,11 +277,6 @@ abstract class AbstractPlainDatagramSocketImpl extends DatagramSocketImpl
return (fd == null) ? true : false;
}
@SuppressWarnings("deprecation")
protected void finalize() {
close();
}
/**
* set a value - since we only support (setting) binary options
* here, o must be a Boolean

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1995, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1995, 2018, 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
@ -25,17 +25,18 @@
package java.net;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.FileDescriptor;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import sun.net.ConnectionResetException;
import sun.net.NetHooks;
import sun.net.ResourceManager;
import java.util.Set;
import java.util.HashSet;
import java.util.Collections;
/**
* Default Socket Implementation. This implementation does
@ -136,6 +137,7 @@ abstract class AbstractPlainSocketImpl extends SocketImpl
fd = new FileDescriptor();
try {
socketCreate(false);
SocketCleanable.register(fd);
} catch (IOException ioe) {
ResourceManager.afterUdpClose();
fd = null;
@ -144,6 +146,7 @@ abstract class AbstractPlainSocketImpl extends SocketImpl
} else {
fd = new FileDescriptor();
socketCreate(true);
SocketCleanable.register(fd);
}
if (socket != null)
socket.setCreated();
@ -643,14 +646,6 @@ abstract class AbstractPlainSocketImpl extends SocketImpl
socketSendUrgentData (data);
}
/**
* Cleans up if the user forgets to close it.
*/
@SuppressWarnings("deprecation")
protected void finalize() throws IOException {
close();
}
/*
* "Acquires" and returns the FileDescriptor for this impl
*
@ -748,6 +743,7 @@ abstract class AbstractPlainSocketImpl extends SocketImpl
* Close the socket (and release the file descriptor).
*/
protected void socketClose() throws IOException {
SocketCleanable.unregister(fd);
socketClose0(false);
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2018, 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
@ -595,7 +595,7 @@ class Inet6Address extends InetAddress {
}
ObjectInputStream.GetField gf = s.readFields();
byte[] ipaddress = (byte[])gf.get("ipaddress", null);
byte[] ipaddress = (byte[])gf.get("ipaddress", new byte[0]);
int scope_id = gf.get("scope_id", -1);
boolean scope_id_set = gf.get("scope_id_set", false);
boolean scope_ifname_set = gf.get("scope_ifname_set", false);

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2018, 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
@ -317,10 +317,9 @@ public class InetSocketAddress
}
/**
*
* Gets the {@code InetAddress}.
*
* @return the InetAdress or {@code null} if it is unresolved.
* @return the InetAddress or {@code null} if it is unresolved.
*/
public final InetAddress getAddress() {
return holder.getAddress();

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1995, 2018, 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
@ -549,6 +549,7 @@ class ServerSocket implements java.io.Closeable {
si.address = new InetAddress();
si.fd = new FileDescriptor();
getImpl().accept(si);
SocketCleanable.register(si.fd); // raw fd has been set
SecurityManager security = System.getSecurityManager();
if (security != null) {

View file

@ -0,0 +1,107 @@
/*
* Copyright (c) 2018, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.net;
import jdk.internal.misc.JavaIOFileDescriptorAccess;
import jdk.internal.misc.SharedSecrets;
import jdk.internal.ref.CleanerFactory;
import jdk.internal.ref.PhantomCleanable;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.lang.ref.Cleaner;
/**
* Cleanup for a socket/datagramsocket FileDescriptor when it becomes phantom reachable.
* Create a cleanup if the raw fd != -1. Windows closes sockets using the fd.
* Subclassed from {@code PhantomCleanable} so that {@code clear} can be
* called to disable the cleanup when the socket fd is closed by any means
* other than calling {@link FileDescriptor#close}.
* Otherwise, it would incorrectly close the handle or fd after it has been reused.
*/
final class SocketCleanable extends PhantomCleanable<Object> {
// Access to FileDescriptor internals
private static final JavaIOFileDescriptorAccess fdAccess =
SharedSecrets.getJavaIOFileDescriptorAccess();
// Native function to call NET_SocketClose(fd)
private static native void cleanupClose0(int fd) throws IOException;
// The raw fd to close
private final int fd;
/**
* Register a socket specific Cleanable with the FileDescriptor
* if the FileDescriptor is non-null and the raw fd is != -1.
*
* @param fdo the FileDescriptor; may be null
*/
static void register(FileDescriptor fdo) {
if (fdo != null) {
int fd = fdAccess.get(fdo);
if (fd != -1) {
fdAccess.registerCleanup(fdo,
new SocketCleanable(fdo, CleanerFactory.cleaner(), fd));
}
}
}
/**
* Unregister a Cleanable from the FileDescriptor.
* @param fdo the FileDescriptor; may be null
*/
static void unregister(FileDescriptor fdo) {
if (fdo != null) {
fdAccess.unregisterCleanup(fdo);
}
}
/**
* Constructor for a phantom cleanable reference.
*
* @param obj the object to monitor
* @param cleaner the cleaner
* @param fd file descriptor to close
*/
private SocketCleanable(Object obj, Cleaner cleaner, int fd) {
super(obj, cleaner);
this.fd = fd;
}
/**
* Close the native handle or fd.
*/
@Override
protected void performCleanup() {
try {
cleanupClose0(fd);
} catch (IOException ioe) {
throw new UncheckedIOException("close", ioe);
}
}
}

View file

@ -63,38 +63,38 @@ class Bits { // package-private
// -- Unsafe access --
private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final Unsafe UNSAFE = Unsafe.getUnsafe();
static Unsafe unsafe() {
return unsafe;
return UNSAFE;
}
// -- Processor and memory-system properties --
private static final ByteOrder byteOrder
= unsafe.isBigEndian() ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
private static final ByteOrder BYTE_ORDER
= UNSAFE.isBigEndian() ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
static ByteOrder byteOrder() {
return byteOrder;
return BYTE_ORDER;
}
private static int pageSize = -1;
private static int PAGE_SIZE = -1;
static int pageSize() {
if (pageSize == -1)
pageSize = unsafe().pageSize();
return pageSize;
if (PAGE_SIZE == -1)
PAGE_SIZE = unsafe().pageSize();
return PAGE_SIZE;
}
static int pageCount(long size) {
return (int)(size + (long)pageSize() - 1L) / pageSize();
}
private static boolean unaligned = unsafe.unalignedAccess();
private static boolean UNALIGNED = UNSAFE.unalignedAccess();
static boolean unaligned() {
return unaligned;
return UNALIGNED;
}
@ -103,11 +103,11 @@ class Bits { // package-private
// A user-settable upper limit on the maximum amount of allocatable
// direct buffer memory. This value may be changed during VM
// initialization if it is launched with "-XX:MaxDirectMemorySize=<size>".
private static volatile long maxMemory = VM.maxDirectMemory();
private static final AtomicLong reservedMemory = new AtomicLong();
private static final AtomicLong totalCapacity = new AtomicLong();
private static final AtomicLong count = new AtomicLong();
private static volatile boolean memoryLimitSet;
private static volatile long MAX_MEMORY = VM.maxDirectMemory();
private static final AtomicLong RESERVED_MEMORY = new AtomicLong();
private static final AtomicLong TOTAL_CAPACITY = new AtomicLong();
private static final AtomicLong COUNT = new AtomicLong();
private static volatile boolean MEMORY_LIMIT_SET;
// max. number of sleeps during try-reserving with exponentially
// increasing delay before throwing OutOfMemoryError:
@ -120,9 +120,9 @@ class Bits { // package-private
// which a process may access. All sizes are specified in bytes.
static void reserveMemory(long size, int cap) {
if (!memoryLimitSet && VM.initLevel() >= 1) {
maxMemory = VM.maxDirectMemory();
memoryLimitSet = true;
if (!MEMORY_LIMIT_SET && VM.initLevel() >= 1) {
MAX_MEMORY = VM.maxDirectMemory();
MEMORY_LIMIT_SET = true;
}
// optimist!
@ -200,10 +200,10 @@ class Bits { // package-private
// actual memory usage, which will differ when buffers are page
// aligned.
long totalCap;
while (cap <= maxMemory - (totalCap = totalCapacity.get())) {
if (totalCapacity.compareAndSet(totalCap, totalCap + cap)) {
reservedMemory.addAndGet(size);
count.incrementAndGet();
while (cap <= MAX_MEMORY - (totalCap = TOTAL_CAPACITY.get())) {
if (TOTAL_CAPACITY.compareAndSet(totalCap, totalCap + cap)) {
RESERVED_MEMORY.addAndGet(size);
COUNT.incrementAndGet();
return true;
}
}
@ -213,9 +213,9 @@ class Bits { // package-private
static void unreserveMemory(long size, int cap) {
long cnt = count.decrementAndGet();
long reservedMem = reservedMemory.addAndGet(-size);
long totalCap = totalCapacity.addAndGet(-cap);
long cnt = COUNT.decrementAndGet();
long reservedMem = RESERVED_MEMORY.addAndGet(-size);
long totalCap = TOTAL_CAPACITY.addAndGet(-cap);
assert cnt >= 0 && reservedMem >= 0 && totalCap >= 0;
}
@ -234,15 +234,15 @@ class Bits { // package-private
}
@Override
public long getCount() {
return Bits.count.get();
return Bits.COUNT.get();
}
@Override
public long getTotalCapacity() {
return Bits.totalCapacity.get();
return Bits.TOTAL_CAPACITY.get();
}
@Override
public long getMemoryUsed() {
return Bits.reservedMemory.get();
return Bits.RESERVED_MEMORY.get();
}
};
}

View file

@ -26,6 +26,7 @@
package java.nio;
import jdk.internal.HotSpotIntrinsicCandidate;
import jdk.internal.misc.Unsafe;
import java.util.Spliterator;
@ -181,6 +182,8 @@ import java.util.Spliterator;
*/
public abstract class Buffer {
// Cached unsafe-access object
static final Unsafe UNSAFE = Bits.unsafe();
/**
* The characteristics of Spliterators that traverse and split elements
@ -616,6 +619,14 @@ public abstract class Buffer {
// -- Package-private methods for bounds checking, etc. --
/**
*
* @return the base reference, paired with the address
* field, which in combination can be used for unsafe access into a heap
* buffer or direct byte buffer (and views of).
*/
abstract Object base();
/**
* Checks the current position against the limit, throwing a {@link
* BufferUnderflowException} if it is not smaller than the limit, and then

View file

@ -0,0 +1,198 @@
/*
* Copyright (c) 2017, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.nio;
import jdk.internal.util.ArraysSupport;
/**
* Mismatch methods for buffers
*/
final class BufferMismatch {
static int mismatch(ByteBuffer a, int aOff, ByteBuffer b, int bOff, int length) {
int i = 0;
if (length > 7) {
i = ArraysSupport.vectorizedMismatch(
a.base(), a.address + aOff,
b.base(), b.address + bOff,
length,
ArraysSupport.LOG2_ARRAY_BYTE_INDEX_SCALE);
if (i >= 0) return i;
i = length - ~i;
}
for (; i < length; i++) {
if (a.get(aOff + i) != b.get(bOff + i))
return i;
}
return -1;
}
static int mismatch(CharBuffer a, int aOff, CharBuffer b, int bOff, int length) {
int i = 0;
// Ensure only heap or off-heap buffer instances use the
// vectorized mismatch. If either buffer is a StringCharBuffer
// (order is null) then the slow path is taken
if (length > 3 && a.charRegionOrder() == b.charRegionOrder()
&& a.charRegionOrder() != null && b.charRegionOrder() != null) {
i = ArraysSupport.vectorizedMismatch(
a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_CHAR_INDEX_SCALE),
b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_CHAR_INDEX_SCALE),
length,
ArraysSupport.LOG2_ARRAY_CHAR_INDEX_SCALE);
if (i >= 0) return i;
i = length - ~i;
}
for (; i < length; i++) {
if (a.get(aOff + i) != b.get(bOff + i))
return i;
}
return -1;
}
static int mismatch(ShortBuffer a, int aOff, ShortBuffer b, int bOff, int length) {
int i = 0;
if (length > 3 && a.order() == b.order()) {
i = ArraysSupport.vectorizedMismatch(
a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_SHORT_INDEX_SCALE),
b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_SHORT_INDEX_SCALE),
length,
ArraysSupport.LOG2_ARRAY_SHORT_INDEX_SCALE);
if (i >= 0) return i;
i = length - ~i;
}
for (; i < length; i++) {
if (a.get(aOff + i) != b.get(bOff + i))
return i;
}
return -1;
}
static int mismatch(IntBuffer a, int aOff, IntBuffer b, int bOff, int length) {
int i = 0;
if (length > 1 && a.order() == b.order()) {
i = ArraysSupport.vectorizedMismatch(
a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_INT_INDEX_SCALE),
b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_INT_INDEX_SCALE),
length,
ArraysSupport.LOG2_ARRAY_INT_INDEX_SCALE);
if (i >= 0) return i;
i = length - ~i;
}
for (; i < length; i++) {
if (a.get(aOff + i) != b.get(bOff + i))
return i;
}
return -1;
}
static int mismatch(FloatBuffer a, int aOff, FloatBuffer b, int bOff, int length) {
int i = 0;
if (length > 1 && a.order() == b.order()) {
i = ArraysSupport.vectorizedMismatch(
a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_FLOAT_INDEX_SCALE),
b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_FLOAT_INDEX_SCALE),
length,
ArraysSupport.LOG2_ARRAY_FLOAT_INDEX_SCALE);
// Mismatched
if (i >= 0) {
// Check if mismatch is not associated with two NaN values; and
// is not associated with +0 and -0
float av = a.get(aOff + i);
float bv = b.get(bOff + i);
if (av != bv && (!Float.isNaN(av) || !Float.isNaN(bv)))
return i;
// Fall back to slow mechanism
// ISSUE: Consider looping over vectorizedMismatch adjusting ranges
// However, requires that returned value be relative to input ranges
i++;
}
// Matched
else {
i = length - ~i;
}
}
for (; i < length; i++) {
float av = a.get(aOff + i);
float bv = b.get(bOff + i);
if (av != bv && (!Float.isNaN(av) || !Float.isNaN(bv)))
return i;
}
return -1;
}
static int mismatch(LongBuffer a, int aOff, LongBuffer b, int bOff, int length) {
int i = 0;
if (length > 0 && a.order() == b.order()) {
i = ArraysSupport.vectorizedMismatch(
a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_LONG_INDEX_SCALE),
b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_LONG_INDEX_SCALE),
length,
ArraysSupport.LOG2_ARRAY_LONG_INDEX_SCALE);
return i >= 0 ? i : -1;
}
for (; i < length; i++) {
if (a.get(aOff + i) != b.get(bOff + i))
return i;
}
return -1;
}
static int mismatch(DoubleBuffer a, int aOff, DoubleBuffer b, int bOff, int length) {
int i = 0;
if (length > 0 && a.order() == b.order()) {
i = ArraysSupport.vectorizedMismatch(
a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_DOUBLE_INDEX_SCALE),
b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_DOUBLE_INDEX_SCALE),
length,
ArraysSupport.LOG2_ARRAY_DOUBLE_INDEX_SCALE);
// Mismatched
if (i >= 0) {
// Check if mismatch is not associated with two NaN values; and
// is not associated with +0 and -0
double av = a.get(aOff + i);
double bv = b.get(bOff + i);
if (av != bv && (!Double.isNaN(av) || !Double.isNaN(bv)))
return i;
// Fall back to slow mechanism
// ISSUE: Consider looping over vectorizedMismatch adjusting ranges
// However, requires that returned value be relative to input ranges
i++;
}
// Matched
else {
return -1;
}
}
for (; i < length; i++) {
double av = a.get(aOff + i);
double bv = b.get(bOff + i);
if (av != bv && (!Double.isNaN(av) || !Double.isNaN(bv)))
return i;
}
return -1;
}
}

View file

@ -36,9 +36,6 @@ class ByteBufferAs$Type$Buffer$RW$$BO$ // package-private
#if[rw]
// Cached unsafe-access object
private static final Unsafe unsafe = Bits.unsafe();
protected final ByteBuffer bb;
#end[rw]
@ -74,6 +71,11 @@ class ByteBufferAs$Type$Buffer$RW$$BO$ // package-private
#end[rw]
}
@Override
Object base() {
return bb.hb;
}
public $Type$Buffer slice() {
int pos = this.position();
int lim = this.limit();
@ -117,20 +119,20 @@ class ByteBufferAs$Type$Buffer$RW$$BO$ // package-private
}
public $type$ get() {
$memtype$ x = unsafe.get$Memtype$Unaligned(bb.hb, byteOffset(nextGetIndex()),
$memtype$ x = UNSAFE.get$Memtype$Unaligned(bb.hb, byteOffset(nextGetIndex()),
{#if[boB]?true:false});
return $fromBits$(x);
}
public $type$ get(int i) {
$memtype$ x = unsafe.get$Memtype$Unaligned(bb.hb, byteOffset(checkIndex(i)),
$memtype$ x = UNSAFE.get$Memtype$Unaligned(bb.hb, byteOffset(checkIndex(i)),
{#if[boB]?true:false});
return $fromBits$(x);
}
#if[streamableType]
$type$ getUnchecked(int i) {
$memtype$ x = unsafe.get$Memtype$Unaligned(bb.hb, byteOffset(i),
$memtype$ x = UNSAFE.get$Memtype$Unaligned(bb.hb, byteOffset(i),
{#if[boB]?true:false});
return $fromBits$(x);
}
@ -141,7 +143,7 @@ class ByteBufferAs$Type$Buffer$RW$$BO$ // package-private
public $Type$Buffer put($type$ x) {
#if[rw]
$memtype$ y = $toBits$(x);
unsafe.put$Memtype$Unaligned(bb.hb, byteOffset(nextPutIndex()), y,
UNSAFE.put$Memtype$Unaligned(bb.hb, byteOffset(nextPutIndex()), y,
{#if[boB]?true:false});
return this;
#else[rw]
@ -152,7 +154,7 @@ class ByteBufferAs$Type$Buffer$RW$$BO$ // package-private
public $Type$Buffer put(int i, $type$ x) {
#if[rw]
$memtype$ y = $toBits$(x);
unsafe.put$Memtype$Unaligned(bb.hb, byteOffset(checkIndex(i)), y,
UNSAFE.put$Memtype$Unaligned(bb.hb, byteOffset(checkIndex(i)), y,
{#if[boB]?true:false});
return this;
#else[rw]
@ -241,4 +243,9 @@ class ByteBufferAs$Type$Buffer$RW$$BO$ // package-private
#end[boL]
}
#if[char]
ByteOrder charRegionOrder() {
return order();
}
#end[char]
}

View file

@ -32,7 +32,7 @@ class XXX {
#if[rw]
private $type$ get$Type$(long a) {
$memtype$ x = unsafe.get$Memtype$Unaligned(null, a, bigEndian);
$memtype$ x = UNSAFE.get$Memtype$Unaligned(null, a, bigEndian);
return $fromBits$(x);
}
@ -49,7 +49,7 @@ class XXX {
private ByteBuffer put$Type$(long a, $type$ x) {
#if[rw]
$memtype$ y = $toBits$(x);
unsafe.put$Memtype$Unaligned(null, a, y, bigEndian);
UNSAFE.put$Memtype$Unaligned(null, a, y, bigEndian);
return this;
#else[rw]
throw new ReadOnlyBufferException();
@ -81,7 +81,7 @@ class XXX {
int rem = (off <= lim ? lim - off : 0);
int size = rem >> $LG_BYTES_PER_VALUE$;
if (!unaligned && ((address + off) % $BYTES_PER_VALUE$ != 0)) {
if (!UNALIGNED && ((address + off) % $BYTES_PER_VALUE$ != 0)) {
return (bigEndian
? ($Type$Buffer)(new ByteBufferAs$Type$Buffer$RW$B(this,
-1,

View file

@ -28,7 +28,6 @@
package java.nio;
import java.io.FileDescriptor;
import jdk.internal.misc.Unsafe;
import jdk.internal.misc.VM;
import jdk.internal.ref.Cleaner;
import sun.nio.ch.DirectBuffer;
@ -45,14 +44,11 @@ class Direct$Type$Buffer$RW$$BO$
#if[rw]
// Cached unsafe-access object
protected static final Unsafe unsafe = Bits.unsafe();
// Cached array base offset
private static final long arrayBaseOffset = (long)unsafe.arrayBaseOffset($type$[].class);
private static final long ARRAY_BASE_OFFSET = UNSAFE.arrayBaseOffset($type$[].class);
// Cached unaligned-access capability
protected static final boolean unaligned = Bits.unaligned();
protected static final boolean UNALIGNED = Bits.unaligned();
// Base address, used in all indexing calculations
// NOTE: moved up to Buffer.java for speed in JNI GetDirectBufferAddress
@ -73,8 +69,6 @@ class Direct$Type$Buffer$RW$$BO$
implements Runnable
{
private static Unsafe unsafe = Unsafe.getUnsafe();
private long address;
private long size;
private int capacity;
@ -91,7 +85,7 @@ class Direct$Type$Buffer$RW$$BO$
// Paranoia
return;
}
unsafe.freeMemory(address);
UNSAFE.freeMemory(address);
address = 0;
Bits.unreserveMemory(size, capacity);
}
@ -124,12 +118,12 @@ class Direct$Type$Buffer$RW$$BO$
long base = 0;
try {
base = unsafe.allocateMemory(size);
base = UNSAFE.allocateMemory(size);
} catch (OutOfMemoryError x) {
Bits.unreserveMemory(size, cap);
throw x;
}
unsafe.setMemory(base, size, (byte) 0);
UNSAFE.setMemory(base, size, (byte) 0);
if (pa && (base % ps != 0)) {
// Round up to page boundary
address = base + ps - (base & (ps - 1));
@ -206,6 +200,11 @@ class Direct$Type$Buffer$RW$$BO$
#end[rw]
}
@Override
Object base() {
return null;
}
public $Type$Buffer slice() {
int pos = this.position();
int lim = this.limit();
@ -258,16 +257,16 @@ class Direct$Type$Buffer$RW$$BO$
}
public $type$ get() {
return $fromBits$($swap$(unsafe.get$Swaptype$(ix(nextGetIndex()))));
return $fromBits$($swap$(UNSAFE.get$Swaptype$(ix(nextGetIndex()))));
}
public $type$ get(int i) {
return $fromBits$($swap$(unsafe.get$Swaptype$(ix(checkIndex(i)))));
return $fromBits$($swap$(UNSAFE.get$Swaptype$(ix(checkIndex(i)))));
}
#if[streamableType]
$type$ getUnchecked(int i) {
return $fromBits$($swap$(unsafe.get$Swaptype$(ix(i))));
return $fromBits$($swap$(UNSAFE.get$Swaptype$(ix(i))));
}
#end[streamableType]
@ -282,10 +281,10 @@ class Direct$Type$Buffer$RW$$BO$
if (length > rem)
throw new BufferUnderflowException();
long dstOffset = arrayBaseOffset + ((long)offset << $LG_BYTES_PER_VALUE$);
long dstOffset = ARRAY_BASE_OFFSET + ((long)offset << $LG_BYTES_PER_VALUE$);
#if[!byte]
if (order() != ByteOrder.nativeOrder())
unsafe.copySwapMemory(null,
UNSAFE.copySwapMemory(null,
ix(pos),
dst,
dstOffset,
@ -293,7 +292,7 @@ class Direct$Type$Buffer$RW$$BO$
(long)1 << $LG_BYTES_PER_VALUE$);
else
#end[!byte]
unsafe.copyMemory(null,
UNSAFE.copyMemory(null,
ix(pos),
dst,
dstOffset,
@ -312,7 +311,7 @@ class Direct$Type$Buffer$RW$$BO$
public $Type$Buffer put($type$ x) {
#if[rw]
unsafe.put$Swaptype$(ix(nextPutIndex()), $swap$($toBits$(x)));
UNSAFE.put$Swaptype$(ix(nextPutIndex()), $swap$($toBits$(x)));
return this;
#else[rw]
throw new ReadOnlyBufferException();
@ -321,7 +320,7 @@ class Direct$Type$Buffer$RW$$BO$
public $Type$Buffer put(int i, $type$ x) {
#if[rw]
unsafe.put$Swaptype$(ix(checkIndex(i)), $swap$($toBits$(x)));
UNSAFE.put$Swaptype$(ix(checkIndex(i)), $swap$($toBits$(x)));
return this;
#else[rw]
throw new ReadOnlyBufferException();
@ -347,7 +346,7 @@ class Direct$Type$Buffer$RW$$BO$
if (srem > rem)
throw new BufferOverflowException();
unsafe.copyMemory(sb.ix(spos), ix(pos), (long)srem << $LG_BYTES_PER_VALUE$);
UNSAFE.copyMemory(sb.ix(spos), ix(pos), (long)srem << $LG_BYTES_PER_VALUE$);
sb.position(spos + srem);
position(pos + srem);
} else if (src.hb != null) {
@ -380,10 +379,10 @@ class Direct$Type$Buffer$RW$$BO$
if (length > rem)
throw new BufferOverflowException();
long srcOffset = arrayBaseOffset + ((long)offset << $LG_BYTES_PER_VALUE$);
long srcOffset = ARRAY_BASE_OFFSET + ((long)offset << $LG_BYTES_PER_VALUE$);
#if[!byte]
if (order() != ByteOrder.nativeOrder())
unsafe.copySwapMemory(src,
UNSAFE.copySwapMemory(src,
srcOffset,
null,
ix(pos),
@ -391,7 +390,7 @@ class Direct$Type$Buffer$RW$$BO$
(long)1 << $LG_BYTES_PER_VALUE$);
else
#end[!byte]
unsafe.copyMemory(src,
UNSAFE.copyMemory(src,
srcOffset,
null,
ix(pos),
@ -413,7 +412,7 @@ class Direct$Type$Buffer$RW$$BO$
assert (pos <= lim);
int rem = (pos <= lim ? lim - pos : 0);
unsafe.copyMemory(ix(pos), ix(0), (long)rem << $LG_BYTES_PER_VALUE$);
UNSAFE.copyMemory(ix(pos), ix(0), (long)rem << $LG_BYTES_PER_VALUE$);
position(rem);
limit(capacity());
discardMark();
@ -490,17 +489,22 @@ class Direct$Type$Buffer$RW$$BO$
#end[!byte]
#if[char]
ByteOrder charRegionOrder() {
return order();
}
#end[char]
#if[byte]
byte _get(int i) { // package-private
return unsafe.getByte(address + i);
return UNSAFE.getByte(address + i);
}
void _put(int i, byte b) { // package-private
#if[rw]
unsafe.putByte(address + i, b);
UNSAFE.putByte(address + i, b);
#else[rw]
throw new ReadOnlyBufferException();
#end[rw]

View file

@ -27,8 +27,6 @@
package java.nio;
import jdk.internal.misc.Unsafe;
/**
#if[rw]
* A read/write Heap$Type$Buffer.
@ -43,6 +41,11 @@ import jdk.internal.misc.Unsafe;
class Heap$Type$Buffer$RW$
extends {#if[ro]?Heap}$Type$Buffer
{
// Cached array base offset
private static final long ARRAY_BASE_OFFSET = UNSAFE.arrayBaseOffset($type$[].class);
// Cached array base offset
private static final long ARRAY_INDEX_SCALE = UNSAFE.arrayIndexScale($type$[].class);
// For speed these fields are actually declared in X-Buffer;
// these declarations are here as documentation
@ -53,16 +56,6 @@ class Heap$Type$Buffer$RW$
#end[rw]
*/
#if[byte]
// Cached unsafe-access object
private static final Unsafe unsafe = Bits.unsafe();
// Cached array base offset
private static final long arrayBaseOffset = unsafe.arrayBaseOffset($type$[].class);
#end[byte]
Heap$Type$Buffer$RW$(int cap, int lim) { // package-private
#if[rw]
super(-1, 0, lim, cap, new $type$[cap], 0);
@ -70,13 +63,11 @@ class Heap$Type$Buffer$RW$
hb = new $type$[cap];
offset = 0;
*/
this.address = ARRAY_BASE_OFFSET;
#else[rw]
super(cap, lim);
this.isReadOnly = true;
#end[rw]
#if[byte]
this.address = arrayBaseOffset;
#end[byte]
}
Heap$Type$Buffer$RW$($type$[] buf, int off, int len) { // package-private
@ -86,13 +77,11 @@ class Heap$Type$Buffer$RW$
hb = buf;
offset = 0;
*/
this.address = ARRAY_BASE_OFFSET;
#else[rw]
super(buf, off, len);
this.isReadOnly = true;
#end[rw]
#if[byte]
this.address = arrayBaseOffset;
#end[byte]
}
protected Heap$Type$Buffer$RW$($type$[] buf,
@ -105,13 +94,11 @@ class Heap$Type$Buffer$RW$
hb = buf;
offset = off;
*/
this.address = ARRAY_BASE_OFFSET + off * ARRAY_INDEX_SCALE;
#else[rw]
super(buf, mark, pos, lim, cap, off);
this.isReadOnly = true;
#end[rw]
#if[byte]
this.address = arrayBaseOffset + off;
#end[byte]
}
public $Type$Buffer slice() {
@ -296,18 +283,18 @@ class Heap$Type$Buffer$RW$
#if[rw]
public char getChar() {
return unsafe.getCharUnaligned(hb, byteOffset(nextGetIndex(2)), bigEndian);
return UNSAFE.getCharUnaligned(hb, byteOffset(nextGetIndex(2)), bigEndian);
}
public char getChar(int i) {
return unsafe.getCharUnaligned(hb, byteOffset(checkIndex(i, 2)), bigEndian);
return UNSAFE.getCharUnaligned(hb, byteOffset(checkIndex(i, 2)), bigEndian);
}
#end[rw]
public $Type$Buffer putChar(char x) {
#if[rw]
unsafe.putCharUnaligned(hb, byteOffset(nextPutIndex(2)), x, bigEndian);
UNSAFE.putCharUnaligned(hb, byteOffset(nextPutIndex(2)), x, bigEndian);
return this;
#else[rw]
throw new ReadOnlyBufferException();
@ -316,7 +303,7 @@ class Heap$Type$Buffer$RW$
public $Type$Buffer putChar(int i, char x) {
#if[rw]
unsafe.putCharUnaligned(hb, byteOffset(checkIndex(i, 2)), x, bigEndian);
UNSAFE.putCharUnaligned(hb, byteOffset(checkIndex(i, 2)), x, bigEndian);
return this;
#else[rw]
throw new ReadOnlyBufferException();
@ -347,18 +334,18 @@ class Heap$Type$Buffer$RW$
#if[rw]
public short getShort() {
return unsafe.getShortUnaligned(hb, byteOffset(nextGetIndex(2)), bigEndian);
return UNSAFE.getShortUnaligned(hb, byteOffset(nextGetIndex(2)), bigEndian);
}
public short getShort(int i) {
return unsafe.getShortUnaligned(hb, byteOffset(checkIndex(i, 2)), bigEndian);
return UNSAFE.getShortUnaligned(hb, byteOffset(checkIndex(i, 2)), bigEndian);
}
#end[rw]
public $Type$Buffer putShort(short x) {
#if[rw]
unsafe.putShortUnaligned(hb, byteOffset(nextPutIndex(2)), x, bigEndian);
UNSAFE.putShortUnaligned(hb, byteOffset(nextPutIndex(2)), x, bigEndian);
return this;
#else[rw]
throw new ReadOnlyBufferException();
@ -367,7 +354,7 @@ class Heap$Type$Buffer$RW$
public $Type$Buffer putShort(int i, short x) {
#if[rw]
unsafe.putShortUnaligned(hb, byteOffset(checkIndex(i, 2)), x, bigEndian);
UNSAFE.putShortUnaligned(hb, byteOffset(checkIndex(i, 2)), x, bigEndian);
return this;
#else[rw]
throw new ReadOnlyBufferException();
@ -398,18 +385,18 @@ class Heap$Type$Buffer$RW$
#if[rw]
public int getInt() {
return unsafe.getIntUnaligned(hb, byteOffset(nextGetIndex(4)), bigEndian);
return UNSAFE.getIntUnaligned(hb, byteOffset(nextGetIndex(4)), bigEndian);
}
public int getInt(int i) {
return unsafe.getIntUnaligned(hb, byteOffset(checkIndex(i, 4)), bigEndian);
return UNSAFE.getIntUnaligned(hb, byteOffset(checkIndex(i, 4)), bigEndian);
}
#end[rw]
public $Type$Buffer putInt(int x) {
#if[rw]
unsafe.putIntUnaligned(hb, byteOffset(nextPutIndex(4)), x, bigEndian);
UNSAFE.putIntUnaligned(hb, byteOffset(nextPutIndex(4)), x, bigEndian);
return this;
#else[rw]
throw new ReadOnlyBufferException();
@ -418,7 +405,7 @@ class Heap$Type$Buffer$RW$
public $Type$Buffer putInt(int i, int x) {
#if[rw]
unsafe.putIntUnaligned(hb, byteOffset(checkIndex(i, 4)), x, bigEndian);
UNSAFE.putIntUnaligned(hb, byteOffset(checkIndex(i, 4)), x, bigEndian);
return this;
#else[rw]
throw new ReadOnlyBufferException();
@ -449,18 +436,18 @@ class Heap$Type$Buffer$RW$
#if[rw]
public long getLong() {
return unsafe.getLongUnaligned(hb, byteOffset(nextGetIndex(8)), bigEndian);
return UNSAFE.getLongUnaligned(hb, byteOffset(nextGetIndex(8)), bigEndian);
}
public long getLong(int i) {
return unsafe.getLongUnaligned(hb, byteOffset(checkIndex(i, 8)), bigEndian);
return UNSAFE.getLongUnaligned(hb, byteOffset(checkIndex(i, 8)), bigEndian);
}
#end[rw]
public $Type$Buffer putLong(long x) {
#if[rw]
unsafe.putLongUnaligned(hb, byteOffset(nextPutIndex(8)), x, bigEndian);
UNSAFE.putLongUnaligned(hb, byteOffset(nextPutIndex(8)), x, bigEndian);
return this;
#else[rw]
throw new ReadOnlyBufferException();
@ -469,7 +456,7 @@ class Heap$Type$Buffer$RW$
public $Type$Buffer putLong(int i, long x) {
#if[rw]
unsafe.putLongUnaligned(hb, byteOffset(checkIndex(i, 8)), x, bigEndian);
UNSAFE.putLongUnaligned(hb, byteOffset(checkIndex(i, 8)), x, bigEndian);
return this;
#else[rw]
throw new ReadOnlyBufferException();
@ -500,12 +487,12 @@ class Heap$Type$Buffer$RW$
#if[rw]
public float getFloat() {
int x = unsafe.getIntUnaligned(hb, byteOffset(nextGetIndex(4)), bigEndian);
int x = UNSAFE.getIntUnaligned(hb, byteOffset(nextGetIndex(4)), bigEndian);
return Float.intBitsToFloat(x);
}
public float getFloat(int i) {
int x = unsafe.getIntUnaligned(hb, byteOffset(checkIndex(i, 4)), bigEndian);
int x = UNSAFE.getIntUnaligned(hb, byteOffset(checkIndex(i, 4)), bigEndian);
return Float.intBitsToFloat(x);
}
@ -514,7 +501,7 @@ class Heap$Type$Buffer$RW$
public $Type$Buffer putFloat(float x) {
#if[rw]
int y = Float.floatToRawIntBits(x);
unsafe.putIntUnaligned(hb, byteOffset(nextPutIndex(4)), y, bigEndian);
UNSAFE.putIntUnaligned(hb, byteOffset(nextPutIndex(4)), y, bigEndian);
return this;
#else[rw]
throw new ReadOnlyBufferException();
@ -524,7 +511,7 @@ class Heap$Type$Buffer$RW$
public $Type$Buffer putFloat(int i, float x) {
#if[rw]
int y = Float.floatToRawIntBits(x);
unsafe.putIntUnaligned(hb, byteOffset(checkIndex(i, 4)), y, bigEndian);
UNSAFE.putIntUnaligned(hb, byteOffset(checkIndex(i, 4)), y, bigEndian);
return this;
#else[rw]
throw new ReadOnlyBufferException();
@ -555,12 +542,12 @@ class Heap$Type$Buffer$RW$
#if[rw]
public double getDouble() {
long x = unsafe.getLongUnaligned(hb, byteOffset(nextGetIndex(8)), bigEndian);
long x = UNSAFE.getLongUnaligned(hb, byteOffset(nextGetIndex(8)), bigEndian);
return Double.longBitsToDouble(x);
}
public double getDouble(int i) {
long x = unsafe.getLongUnaligned(hb, byteOffset(checkIndex(i, 8)), bigEndian);
long x = UNSAFE.getLongUnaligned(hb, byteOffset(checkIndex(i, 8)), bigEndian);
return Double.longBitsToDouble(x);
}
@ -569,7 +556,7 @@ class Heap$Type$Buffer$RW$
public $Type$Buffer putDouble(double x) {
#if[rw]
long y = Double.doubleToRawLongBits(x);
unsafe.putLongUnaligned(hb, byteOffset(nextPutIndex(8)), y, bigEndian);
UNSAFE.putLongUnaligned(hb, byteOffset(nextPutIndex(8)), y, bigEndian);
return this;
#else[rw]
throw new ReadOnlyBufferException();
@ -579,7 +566,7 @@ class Heap$Type$Buffer$RW$
public $Type$Buffer putDouble(int i, double x) {
#if[rw]
long y = Double.doubleToRawLongBits(x);
unsafe.putLongUnaligned(hb, byteOffset(checkIndex(i, 8)), y, bigEndian);
UNSAFE.putLongUnaligned(hb, byteOffset(checkIndex(i, 8)), y, bigEndian);
return this;
#else[rw]
throw new ReadOnlyBufferException();
@ -643,7 +630,11 @@ class Heap$Type$Buffer$RW$
public ByteOrder order() {
return ByteOrder.nativeOrder();
}
#end[!byte]
#if[char]
ByteOrder charRegionOrder() {
return order();
}
#end[char]
}

View file

@ -127,4 +127,30 @@ class StringCharBuffer // package-private
return ByteOrder.nativeOrder();
}
ByteOrder charRegionOrder() {
return null;
}
public boolean equals(Object ob) {
if (this == ob)
return true;
if (!(ob instanceof CharBuffer))
return false;
CharBuffer that = (CharBuffer)ob;
if (this.remaining() != that.remaining())
return false;
return BufferMismatch.mismatch(this, this.position(),
that, that.position(),
this.remaining()) < 0;
}
public int compareTo(CharBuffer that) {
int i = BufferMismatch.mismatch(this, this.position(),
that, that.position(),
Math.min(this.remaining(), that.remaining()));
if (i >= 0) {
return Character.compare(this.get(this.position() + i), that.get(this.position() + i));
}
return this.remaining() - that.remaining();
}
}

View file

@ -36,6 +36,8 @@ import java.util.stream.StreamSupport;
import java.util.stream.$Streamtype$Stream;
#end[streamableType]
import jdk.internal.util.ArraysSupport;
/**
* $A$ $type$ buffer.
*
@ -287,6 +289,11 @@ public abstract class $Type$Buffer
this(mark, pos, lim, cap, null, 0);
}
@Override
Object base() {
return hb;
}
#if[byte]
/**
@ -1297,19 +1304,9 @@ public abstract class $Type$Buffer
$Type$Buffer that = ($Type$Buffer)ob;
if (this.remaining() != that.remaining())
return false;
int p = this.position();
for (int i = this.limit() - 1, j = that.limit() - 1; i >= p; i--, j--)
if (!equals(this.get(i), that.get(j)))
return false;
return true;
}
private static boolean equals($type$ x, $type$ y) {
#if[floatingPointType]
return (x == y) || ($Fulltype$.isNaN(x) && $Fulltype$.isNaN(y));
#else[floatingPointType]
return x == y;
#end[floatingPointType]
return BufferMismatch.mismatch(this, this.position(),
that, that.position(),
this.remaining()) < 0;
}
/**
@ -1336,11 +1333,11 @@ public abstract class $Type$Buffer
* is less than, equal to, or greater than the given buffer
*/
public int compareTo($Type$Buffer that) {
int n = this.position() + Math.min(this.remaining(), that.remaining());
for (int i = this.position(), j = that.position(); i < n; i++, j++) {
int cmp = compare(this.get(i), that.get(j));
if (cmp != 0)
return cmp;
int i = BufferMismatch.mismatch(this, this.position(),
that, that.position(),
Math.min(this.remaining(), that.remaining()));
if (i >= 0) {
return compare(this.get(this.position() + i), that.get(this.position() + i));
}
return this.remaining() - that.remaining();
}
@ -1571,6 +1568,12 @@ public abstract class $Type$Buffer
#end[!byte]
#if[char]
// The order or null if the buffer does not cover a memory region,
// such as StringCharBuffer
abstract ByteOrder charRegionOrder();
#end[char]
#if[byte]
boolean bigEndian // package-private

View file

@ -121,7 +121,7 @@ public abstract class SelectableChannel
// keySet, may be empty but is never null, typ. a tiny array
// boolean isRegistered, protected by key set
// regLock, lock object to prevent duplicate registrations
// boolean isBlocking, protected by regLock
// blocking mode, protected by regLock
/**
* Tells whether or not this channel is currently registered with any

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2018, 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,7 +26,14 @@
package java.nio.channels.spi;
import java.io.IOException;
import java.nio.channels.*;
import java.nio.channels.CancelledKeyException;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.ClosedSelectorException;
import java.nio.channels.IllegalBlockingModeException;
import java.nio.channels.IllegalSelectorException;
import java.nio.channels.SelectableChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
/**
@ -67,8 +74,8 @@ public abstract class AbstractSelectableChannel
// Lock for registration and configureBlocking operations
private final Object regLock = new Object();
// Blocking mode, protected by regLock
boolean blocking = true;
// True when non-blocking, need regLock to change;
private volatile boolean nonBlocking;
/**
* Initializes a new instance of this class.
@ -197,7 +204,7 @@ public abstract class AbstractSelectableChannel
throw new ClosedChannelException();
if ((ops & ~validOps()) != 0)
throw new IllegalArgumentException();
if (blocking)
if (isBlocking())
throw new IllegalBlockingModeException();
SelectionKey k = findKey(sel);
if (k != null) {
@ -264,9 +271,7 @@ public abstract class AbstractSelectableChannel
// -- Blocking --
public final boolean isBlocking() {
synchronized (regLock) {
return blocking;
}
return !nonBlocking;
}
public final Object blockingLock() {
@ -287,12 +292,13 @@ public abstract class AbstractSelectableChannel
synchronized (regLock) {
if (!isOpen())
throw new ClosedChannelException();
if (blocking == block)
return this;
if (block && haveValidKeys())
throw new IllegalBlockingModeException();
implConfigureBlocking(block);
blocking = block;
boolean blocking = !nonBlocking;
if (block != blocking) {
if (block && haveValidKeys())
throw new IllegalBlockingModeException();
implConfigureBlocking(block);
nonBlocking = !block;
}
}
return this;
}

View file

@ -2954,22 +2954,6 @@ public final class Files {
return newBufferedWriter(path, StandardCharsets.UTF_8, options);
}
/**
* Reads all bytes from an input stream and writes them to an output stream.
*/
private static long copy(InputStream source, OutputStream sink)
throws IOException
{
long nread = 0L;
byte[] buf = new byte[BUFFER_SIZE];
int n;
while ((n = source.read(buf)) > 0) {
sink.write(buf, 0, n);
nread += n;
}
return nread;
}
/**
* Copies all bytes from an input stream to a file. On return, the input
* stream will be at end of stream.
@ -3082,7 +3066,7 @@ public final class Files {
// do the copy
try (OutputStream out = ostream) {
return copy(in, out);
return in.transferTo(out);
}
}
@ -3124,7 +3108,7 @@ public final class Files {
Objects.requireNonNull(out);
try (InputStream in = newInputStream(source)) {
return copy(in, out);
return in.transferTo(out);
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2018, 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
@ -394,6 +394,12 @@ public class DateFormatSymbols implements Serializable, Cloneable {
/**
* Gets month strings. For example: "January", "February", etc.
* An array with either 12 or 13 elements will be returned depending
* on whether or not {@link java.util.Calendar#UNDECIMBER Calendar.UNDECIMBER}
* is supported. Use
* {@link java.util.Calendar#JANUARY Calendar.JANUARY},
* {@link java.util.Calendar#FEBRUARY Calendar.FEBRUARY},
* etc. to index the result array.
*
* <p>If the language requires different forms for formatting and
* stand-alone usages, this method returns month names in the
@ -405,10 +411,9 @@ public class DateFormatSymbols implements Serializable, Cloneable {
* Calendar Elements in the Unicode Locale Data Markup Language
* (LDML) specification</a> for more details.
*
* @return the month strings. Use
* {@link java.util.Calendar#JANUARY Calendar.JANUARY},
* {@link java.util.Calendar#FEBRUARY Calendar.FEBRUARY},
* etc. to index the result array.
* @implSpec This method returns 13 elements since
* {@link java.util.Calendar#UNDECIMBER Calendar.UNDECIMBER} is supported.
* @return the month strings.
*/
public String[] getMonths() {
return Arrays.copyOf(months, months.length);
@ -427,6 +432,12 @@ public class DateFormatSymbols implements Serializable, Cloneable {
/**
* Gets short month strings. For example: "Jan", "Feb", etc.
* An array with either 12 or 13 elements will be returned depending
* on whether or not {@link java.util.Calendar#UNDECIMBER Calendar.UNDECIMBER}
* is supported. Use
* {@link java.util.Calendar#JANUARY Calendar.JANUARY},
* {@link java.util.Calendar#FEBRUARY Calendar.FEBRUARY},
* etc. to index the result array.
*
* <p>If the language requires different forms for formatting and
* stand-alone usages, this method returns short month names in
@ -438,10 +449,9 @@ public class DateFormatSymbols implements Serializable, Cloneable {
* Calendar Elements in the Unicode Locale Data Markup Language
* (LDML) specification</a> for more details.
*
* @return the short month strings. Use
* {@link java.util.Calendar#JANUARY Calendar.JANUARY},
* {@link java.util.Calendar#FEBRUARY Calendar.FEBRUARY},
* etc. to index the result array.
* @implSpec This method returns 13 elements since
* {@link java.util.Calendar#UNDECIMBER Calendar.UNDECIMBER} is supported.
* @return the short month strings.
*/
public String[] getShortMonths() {
return Arrays.copyOf(shortMonths, shortMonths.length);

View file

@ -610,7 +610,7 @@ public final class Instant
* <p>
* The epoch second count is a simple incrementing count of seconds where
* second 0 is 1970-01-01T00:00:00Z.
* The nanosecond part of the day is returned by {@link #getNano}.
* The nanosecond part is returned by {@link #getNano}.
*
* @return the seconds from the epoch of 1970-01-01T00:00:00Z
*/

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2018, 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
@ -708,9 +708,8 @@ public final class IsoFields {
return (R) temporal.with(WEEK_BASED_YEAR,
Math.addExact(temporal.get(WEEK_BASED_YEAR), amount));
case QUARTER_YEARS:
// no overflow (256 is multiple of 4)
return (R) temporal.plus(amount / 256, YEARS)
.plus((amount % 256) * 3, MONTHS);
return (R) temporal.plus(amount / 4, YEARS)
.plus((amount % 4) * 3, MONTHS);
default:
throw new IllegalStateException("Unreachable");
}

View file

@ -1143,6 +1143,23 @@ public class ArrayList<E> extends AbstractList<E>
return modified;
}
public Object[] toArray() {
checkForComodification();
return Arrays.copyOfRange(root.elementData, offset, offset + size);
}
@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a) {
checkForComodification();
if (a.length < size)
return (T[]) Arrays.copyOfRange(
root.elementData, offset, offset + size, a.getClass());
System.arraycopy(root.elementData, offset, a, 0, size);
if (a.length > size)
a[size] = null;
return a;
}
public Iterator<E> iterator() {
return listIterator();
}
@ -1550,7 +1567,6 @@ public class ArrayList<E> extends AbstractList<E>
setBit(deathRow, i - beg);
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
expectedModCount++;
modCount++;
int w = beg;
for (i = beg; i < end; i++)

View file

@ -26,6 +26,7 @@
package java.util;
import jdk.internal.HotSpotIntrinsicCandidate;
import jdk.internal.util.ArraysSupport;
import java.lang.reflect.Array;
import java.util.concurrent.ForkJoinPool;

View file

@ -116,8 +116,8 @@ public class Base64 {
*
* @param lineLength
* the length of each output line (rounded down to nearest multiple
* of 4). If {@code lineLength <= 0} the output will not be separated
* in lines
* of 4). If the rounded down line length is not a positive value,
* the output will not be separated in lines
* @param lineSeparator
* the line separator for each output line
*
@ -135,10 +135,12 @@ public class Base64 {
throw new IllegalArgumentException(
"Illegal base64 line separator character 0x" + Integer.toString(b, 16));
}
// round down to nearest multiple of 4
lineLength &= ~0b11;
if (lineLength <= 0) {
return Encoder.RFC4648;
}
return new Encoder(false, lineSeparator, lineLength >> 2 << 2, true);
return new Encoder(false, lineSeparator, lineLength, true);
}
/**

View file

@ -808,17 +808,26 @@ public final class Locale implements Cloneable, Serializable {
}
static Locale getInstance(BaseLocale baseloc, LocaleExtensions extensions) {
LocaleKey key = new LocaleKey(baseloc, extensions);
return LOCALECACHE.get(key);
if (extensions == null) {
return LOCALECACHE.get(baseloc);
} else {
LocaleKey key = new LocaleKey(baseloc, extensions);
return LOCALECACHE.get(key);
}
}
private static class Cache extends LocaleObjectCache<LocaleKey, Locale> {
private static class Cache extends LocaleObjectCache<Object, Locale> {
private Cache() {
}
@Override
protected Locale createObject(LocaleKey key) {
return new Locale(key.base, key.exts);
protected Locale createObject(Object key) {
if (key instanceof BaseLocale) {
return new Locale((BaseLocale)key, null);
} else {
LocaleKey lk = (LocaleKey)key;
return new Locale(lk.base, lk.exts);
}
}
}

View file

@ -1023,7 +1023,6 @@ public class Vector<E>
setBit(deathRow, i - beg);
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
expectedModCount++;
modCount++;
int w = beg;
for (i = beg; i < end; i++)

View file

@ -245,8 +245,7 @@ public abstract class AbstractExecutorService implements ExecutorService {
Future<T> f = futures.get(i);
if (!f.isDone()) {
try { f.get(); }
catch (CancellationException ignore) {}
catch (ExecutionException ignore) {}
catch (CancellationException | ExecutionException ignore) {}
}
}
return futures;
@ -283,8 +282,7 @@ public abstract class AbstractExecutorService implements ExecutorService {
Future<T> f = futures.get(j);
if (!f.isDone()) {
try { f.get(deadline - System.nanoTime(), NANOSECONDS); }
catch (CancellationException ignore) {}
catch (ExecutionException ignore) {}
catch (CancellationException | ExecutionException ignore) {}
catch (TimeoutException timedOut) {
break timedOut;
}

View file

@ -717,12 +717,12 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
*/
static Class<?> comparableClassFor(Object x) {
if (x instanceof Comparable) {
Class<?> c; Type[] ts, as; Type t; ParameterizedType p;
Class<?> c; Type[] ts, as; ParameterizedType p;
if ((c = x.getClass()) == String.class) // bypass checks
return c;
if ((ts = c.getGenericInterfaces()) != null) {
for (int i = 0; i < ts.length; ++i) {
if (((t = ts[i]) instanceof ParameterizedType) &&
for (Type t : ts) {
if ((t instanceof ParameterizedType) &&
((p = (ParameterizedType)t).getRawType() ==
Comparable.class) &&
(as = p.getActualTypeArguments()) != null &&
@ -2328,15 +2328,15 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
* @param check if <0, don't check resize, if <= 1 only check if uncontended
*/
private final void addCount(long x, int check) {
CounterCell[] as; long b, s;
if ((as = counterCells) != null ||
CounterCell[] cs; long b, s;
if ((cs = counterCells) != null ||
!U.compareAndSetLong(this, BASECOUNT, b = baseCount, s = b + x)) {
CounterCell a; long v; int m;
CounterCell c; long v; int m;
boolean uncontended = true;
if (as == null || (m = as.length - 1) < 0 ||
(a = as[ThreadLocalRandom.getProbe() & m]) == null ||
if (cs == null || (m = cs.length - 1) < 0 ||
(c = cs[ThreadLocalRandom.getProbe() & m]) == null ||
!(uncontended =
U.compareAndSetLong(a, CELLVALUE, v = a.value, v + x))) {
U.compareAndSetLong(c, CELLVALUE, v = c.value, v + x))) {
fullAddCount(x, uncontended);
return;
}
@ -2574,13 +2574,12 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
}
final long sumCount() {
CounterCell[] as = counterCells; CounterCell a;
CounterCell[] cs = counterCells;
long sum = baseCount;
if (as != null) {
for (int i = 0; i < as.length; ++i) {
if ((a = as[i]) != null)
sum += a.value;
}
if (cs != null) {
for (CounterCell c : cs)
if (c != null)
sum += c.value;
}
return sum;
}
@ -2595,9 +2594,9 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
}
boolean collide = false; // True if last slot nonempty
for (;;) {
CounterCell[] as; CounterCell a; int n; long v;
if ((as = counterCells) != null && (n = as.length) > 0) {
if ((a = as[(n - 1) & h]) == null) {
CounterCell[] cs; CounterCell c; int n; long v;
if ((cs = counterCells) != null && (n = cs.length) > 0) {
if ((c = cs[(n - 1) & h]) == null) {
if (cellsBusy == 0) { // Try to attach new Cell
CounterCell r = new CounterCell(x); // Optimistic create
if (cellsBusy == 0 &&
@ -2623,21 +2622,17 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
}
else if (!wasUncontended) // CAS already known to fail
wasUncontended = true; // Continue after rehash
else if (U.compareAndSetLong(a, CELLVALUE, v = a.value, v + x))
else if (U.compareAndSetLong(c, CELLVALUE, v = c.value, v + x))
break;
else if (counterCells != as || n >= NCPU)
else if (counterCells != cs || n >= NCPU)
collide = false; // At max size or stale
else if (!collide)
collide = true;
else if (cellsBusy == 0 &&
U.compareAndSetInt(this, CELLSBUSY, 0, 1)) {
try {
if (counterCells == as) {// Expand table unless stale
CounterCell[] rs = new CounterCell[n << 1];
for (int i = 0; i < n; ++i)
rs[i] = as[i];
counterCells = rs;
}
if (counterCells == cs) // Expand table unless stale
counterCells = Arrays.copyOf(cs, n << 1);
} finally {
cellsBusy = 0;
}
@ -2646,11 +2641,11 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
}
h = ThreadLocalRandom.advanceProbe(h);
}
else if (cellsBusy == 0 && counterCells == as &&
else if (cellsBusy == 0 && counterCells == cs &&
U.compareAndSetInt(this, CELLSBUSY, 0, 1)) {
boolean init = false;
try { // Initialize table
if (counterCells == as) {
if (counterCells == cs) {
CounterCell[] rs = new CounterCell[2];
rs[h & 1] = new CounterCell(x);
counterCells = rs;

View file

@ -2204,9 +2204,7 @@ public class ConcurrentSkipListMap<K,V> extends AbstractMap<K,V>
Collection<?> c = (Collection<?>) o;
try {
return containsAll(c) && c.containsAll(this);
} catch (ClassCastException unused) {
return false;
} catch (NullPointerException unused) {
} catch (ClassCastException | NullPointerException unused) {
return false;
}
}
@ -2331,9 +2329,7 @@ public class ConcurrentSkipListMap<K,V> extends AbstractMap<K,V>
Collection<?> c = (Collection<?>) o;
try {
return containsAll(c) && c.containsAll(this);
} catch (ClassCastException unused) {
return false;
} catch (NullPointerException unused) {
} catch (ClassCastException | NullPointerException unused) {
return false;
}
}
@ -2453,9 +2449,7 @@ public class ConcurrentSkipListMap<K,V> extends AbstractMap<K,V>
if (k == null) // pass by markers and headers
return true;
int c = cpr(cmp, k, hi);
if (c > 0 || (c == 0 && !hiInclusive))
return false;
return true;
return c < 0 || (c == 0 && hiInclusive);
}
/**

View file

@ -309,9 +309,7 @@ public class ConcurrentSkipListSet<E>
Collection<?> c = (Collection<?>) o;
try {
return containsAll(c) && c.containsAll(this);
} catch (ClassCastException unused) {
return false;
} catch (NullPointerException unused) {
} catch (ClassCastException | NullPointerException unused) {
return false;
}
}

View file

@ -508,7 +508,7 @@ public class CopyOnWriteArrayList<E>
public boolean remove(Object o) {
Object[] snapshot = getArray();
int index = indexOf(o, snapshot, 0, snapshot.length);
return (index < 0) ? false : remove(o, snapshot, index);
return index >= 0 && remove(o, snapshot, index);
}
/**
@ -587,8 +587,8 @@ public class CopyOnWriteArrayList<E>
*/
public boolean addIfAbsent(E e) {
Object[] snapshot = getArray();
return indexOf(e, snapshot, 0, snapshot.length) >= 0 ? false :
addIfAbsent(e, snapshot);
return indexOf(e, snapshot, 0, snapshot.length) < 0
&& addIfAbsent(e, snapshot);
}
/**
@ -980,13 +980,10 @@ public class CopyOnWriteArrayList<E>
List<?> list = (List<?>)o;
Iterator<?> it = list.iterator();
Object[] elements = getArray();
for (int i = 0, len = elements.length; i < len; i++)
if (!it.hasNext() || !Objects.equals(elements[i], it.next()))
for (Object element : getArray())
if (!it.hasNext() || !Objects.equals(element, it.next()))
return false;
if (it.hasNext())
return false;
return true;
return !it.hasNext();
}
/**

View file

@ -1353,17 +1353,16 @@ public class LinkedBlockingDeque<E>
@SuppressWarnings("unchecked")
private boolean bulkRemove(Predicate<? super E> filter) {
boolean removed = false;
Node<E> p = null;
final ReentrantLock lock = this.lock;
Node<E> p = null;
Node<E>[] nodes = null;
int n, len = 0;
do {
// 1. Extract batch of up to 64 elements while holding the lock.
long deathRow = 0; // "bitset" of size 64
lock.lock();
try {
if (nodes == null) {
if (p == null) p = first;
if (nodes == null) { // first batch; initialize
p = first;
for (Node<E> q = p; q != null; q = succ(q))
if (q.item != null && ++len == 64)
break;
@ -1376,6 +1375,7 @@ public class LinkedBlockingDeque<E>
}
// 2. Run the filter on the elements while lock is free.
long deathRow = 0L; // "bitset" of size 64
for (int i = 0; i < n; i++) {
final E e;
if ((e = nodes[i].item) != null && filter.test(e))
@ -1393,6 +1393,7 @@ public class LinkedBlockingDeque<E>
unlink(q);
removed = true;
}
nodes[i] = null; // help GC
}
} finally {
lock.unlock();

View file

@ -1060,11 +1060,10 @@ public class LinkedBlockingQueue<E> extends AbstractQueue<E>
int n, len = 0;
do {
// 1. Extract batch of up to 64 elements while holding the lock.
long deathRow = 0; // "bitset" of size 64
fullyLock();
try {
if (nodes == null) {
if (p == null) p = head.next;
if (nodes == null) { // first batch; initialize
p = head.next;
for (Node<E> q = p; q != null; q = succ(q))
if (q.item != null && ++len == 64)
break;
@ -1077,6 +1076,7 @@ public class LinkedBlockingQueue<E> extends AbstractQueue<E>
}
// 2. Run the filter on the elements while lock is free.
long deathRow = 0L; // "bitset" of size 64
for (int i = 0; i < n; i++) {
final E e;
if ((e = nodes[i].item) != null && filter.test(e))
@ -1095,6 +1095,7 @@ public class LinkedBlockingQueue<E> extends AbstractQueue<E>
unlink(q, ancestor);
removed = true;
}
nodes[i] = null; // help GC
}
} finally {
fullyUnlock();

View file

@ -772,9 +772,8 @@ public class LinkedTransferQueue<E> extends AbstractQueue<E>
Node first = null;
restartFromHead: for (;;) {
Node h = head, p = h;
for (; p != null;) {
final Object item;
if ((item = p.item) != null) {
while (p != null) {
if (p.item != null) {
if (p.isData) {
first = p;
break;
@ -1602,8 +1601,7 @@ public class LinkedTransferQueue<E> extends AbstractQueue<E>
// Read in elements until trailing null sentinel found
Node h = null, t = null;
for (Object item; (item = s.readObject()) != null; ) {
@SuppressWarnings("unchecked")
Node newNode = new Node((E) item);
Node newNode = new Node(item);
if (h == null)
h = t = newNode;
else

View file

@ -269,8 +269,8 @@ public class PriorityBlockingQueue<E> extends AbstractQueue<E>
if (a.getClass() != Object[].class)
a = Arrays.copyOf(a, n, Object[].class);
if (screen && (n == 1 || this.comparator != null)) {
for (int i = 0; i < n; ++i)
if (a[i] == null)
for (Object elt : a)
if (elt == null)
throw new NullPointerException();
}
this.queue = a;

View file

@ -753,8 +753,10 @@ public class SubmissionPublisher<T> implements Publisher<T>,
else
pred.next = next;
}
else
else {
subs.add(b.subscriber);
pred = b;
}
}
}
return subs;

View file

@ -67,7 +67,7 @@ import jdk.internal.misc.VM;
* {@code ThreadLocalRandom.current().nextX(...)} (where
* {@code X} is {@code Int}, {@code Long}, etc).
* When all usages are of this form, it is never possible to
* accidently share a {@code ThreadLocalRandom} across multiple threads.
* accidentally share a {@code ThreadLocalRandom} across multiple threads.
*
* <p>This class also provides additional commonly used bounded random
* generation methods.

View file

@ -264,13 +264,12 @@ import java.util.concurrent.locks.ReentrantLock;
* assist in storage reclamation when large numbers of queued tasks
* become cancelled.</dd>
*
* <dt>Finalization</dt>
* <dt>Reclamation</dt>
*
* <dd>A pool that is no longer referenced in a program <em>AND</em>
* has no remaining threads will be {@code shutdown} automatically. If
* you would like to ensure that unreferenced pools are reclaimed even
* if users forget to call {@link #shutdown}, then you must arrange
* that unused threads eventually die, by setting appropriate
* has no remaining threads may be reclaimed (garbage collected)
* without being explicity shutdown. You can configure a pool to allow
* all unused threads to eventually die by setting appropriate
* keep-alive times, using a lower bound of zero core threads and/or
* setting {@link #allowCoreThreadTimeOut(boolean)}. </dd>
*
@ -361,7 +360,7 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
* time, but need not hit each state. The transitions are:
*
* RUNNING -> SHUTDOWN
* On invocation of shutdown(), perhaps implicitly in finalize()
* On invocation of shutdown()
* (RUNNING or SHUTDOWN) -> STOP
* On invocation of shutdownNow()
* SHUTDOWN -> TIDYING
@ -581,9 +580,6 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
private static final RuntimePermission shutdownPerm =
new RuntimePermission("modifyThread");
/** The context to be used when executing the finalizer, or null. */
private final AccessControlContext acc;
/**
* Class Worker mainly maintains interrupt control state for
* threads running tasks, along with other minor bookkeeping.
@ -1300,9 +1296,6 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.acc = (System.getSecurityManager() == null)
? null
: AccessController.getContext();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
@ -1469,33 +1462,6 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
}
}
/**
* Invokes {@code shutdown} when this executor is no longer
* referenced and it has no threads.
*
* <p>This method is invoked with privileges that are restricted by
* the security context of the caller that invokes the constructor.
*
* @deprecated The {@code finalize} method has been deprecated.
* Subclasses that override {@code finalize} in order to perform cleanup
* should be modified to use alternative cleanup mechanisms and
* to remove the overriding {@code finalize} method.
* When overriding the {@code finalize} method, its implementation must explicitly
* ensure that {@code super.finalize()} is invoked as described in {@link Object#finalize}.
* See the specification for {@link Object#finalize()} for further
* information about migration options.
*/
@Deprecated(since="9")
protected void finalize() {
SecurityManager sm = System.getSecurityManager();
if (sm == null || acc == null) {
shutdown();
} else {
PrivilegedAction<Void> pa = () -> { shutdown(); return null; };
AccessController.doPrivileged(pa, acc);
}
}
/**
* Sets the thread factory used to create new threads.
*

View file

@ -320,7 +320,9 @@ public abstract class AbstractQueuedLongSynchronizer
// predNext is the apparent node to unsplice. CASes below will
// fail if not, in which case, we lost race vs another cancel
// or signal, so no further action is necessary.
// or signal, so no further action is necessary, although with
// a possibility that a cancelled node may transiently remain
// reachable.
Node predNext = pred.next;
// Can use unconditional write instead of CAS here.
@ -912,13 +914,13 @@ public abstract class AbstractQueuedLongSynchronizer
* at any time, a {@code true} return does not guarantee that any
* other thread will ever acquire.
*
* <p>In this implementation, this operation returns in
* constant time.
*
* @return {@code true} if there may be other threads waiting to acquire
*/
public final boolean hasQueuedThreads() {
return head != tail;
for (Node p = tail, h = head; p != h && p != null; p = p.prev)
if (p.waitStatus <= 0)
return true;
return false;
}
/**
@ -1067,17 +1069,21 @@ public abstract class AbstractQueuedLongSynchronizer
* @since 1.7
*/
public final boolean hasQueuedPredecessors() {
// The correctness of this depends on head being initialized
// before tail and on head.next being accurate if the current
// thread is first in queue.
Node t = tail; // Read fields in reverse initialization order
Node h = head;
Node s;
return h != t &&
((s = h.next) == null || s.thread != Thread.currentThread());
Node h, s;
if ((h = head) != null) {
if ((s = h.next) == null || s.waitStatus > 0) {
s = null; // traverse in case of concurrent cancellation
for (Node p = tail; p != h && p != null; p = p.prev) {
if (p.waitStatus <= 0)
s = p;
}
}
if (s != null && s.thread != Thread.currentThread())
return true;
}
return false;
}
// Instrumentation and monitoring methods
/**

View file

@ -800,7 +800,9 @@ public abstract class AbstractQueuedSynchronizer
// predNext is the apparent node to unsplice. CASes below will
// fail if not, in which case, we lost race vs another cancel
// or signal, so no further action is necessary.
// or signal, so no further action is necessary, although with
// a possibility that a cancelled node may transiently remain
// reachable.
Node predNext = pred.next;
// Can use unconditional write instead of CAS here.
@ -1392,13 +1394,13 @@ public abstract class AbstractQueuedSynchronizer
* at any time, a {@code true} return does not guarantee that any
* other thread will ever acquire.
*
* <p>In this implementation, this operation returns in
* constant time.
*
* @return {@code true} if there may be other threads waiting to acquire
*/
public final boolean hasQueuedThreads() {
return head != tail;
for (Node p = tail, h = head; p != h && p != null; p = p.prev)
if (p.waitStatus <= 0)
return true;
return false;
}
/**
@ -1547,17 +1549,21 @@ public abstract class AbstractQueuedSynchronizer
* @since 1.7
*/
public final boolean hasQueuedPredecessors() {
// The correctness of this depends on head being initialized
// before tail and on head.next being accurate if the current
// thread is first in queue.
Node t = tail; // Read fields in reverse initialization order
Node h = head;
Node s;
return h != t &&
((s = h.next) == null || s.thread != Thread.currentThread());
Node h, s;
if ((h = head) != null) {
if ((s = h.next) == null || s.waitStatus > 0) {
s = null; // traverse in case of concurrent cancellation
for (Node p = tail; p != h && p != null; p = p.prev) {
if (p.waitStatus <= 0)
s = p;
}
}
if (s != null && s.thread != Thread.currentThread())
return true;
}
return false;
}
// Instrumentation and monitoring methods
/**

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2018, 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
@ -953,6 +953,12 @@ public final class Pattern
*/
private int flags;
/**
* The temporary pattern flags used during compiling. The flags might be turn
* on and off by embedded flag.
*/
private transient int flags0;
/**
* Boolean indicating this Pattern is compiled; this is necessary in order
* to lazily compile deserialized Patterns.
@ -1137,7 +1143,7 @@ public final class Pattern
* @return The match flags specified when this pattern was compiled
*/
public int flags() {
return flags;
return flags0;
}
/**
@ -1369,6 +1375,9 @@ public final class Pattern
// Read in all fields
s.defaultReadObject();
// reset the flags
flags0 = flags;
// Initialize counts
capturingGroupCount = 1;
localCount = 0;
@ -1400,6 +1409,9 @@ public final class Pattern
if ((flags & UNICODE_CHARACTER_CLASS) != 0)
flags |= UNICODE_CASE;
// 'flags' for compiling
flags0 = flags;
// Reset group index count
capturingGroupCount = 1;
localCount = 0;
@ -1841,7 +1853,7 @@ loop: for(int x=0, offset=0; x<nCodePoints; x++, offset+=len) {
* Indicates whether a particular flag is set or not.
*/
private boolean has(int f) {
return (flags & f) != 0;
return (flags0 & f) != 0;
}
/**
@ -2718,7 +2730,7 @@ loop: for(int x=0, offset=0; x<nCodePoints; x++, offset+=len) {
ch == 0x53 || ch == 0x73 || //S and s
ch == 0x4b || ch == 0x6b || //K and k
ch == 0xc5 || ch == 0xe5))) { //A+ring
bits.add(ch, flags());
bits.add(ch, flags0);
return null;
}
return single(ch);
@ -2931,7 +2943,7 @@ loop: for(int x=0, offset=0; x<nCodePoints; x++, offset+=len) {
boolean capturingGroup = false;
Node head = null;
Node tail = null;
int save = flags;
int save = flags0;
int saveTCNCount = topClosureNodes.size();
root = null;
int ch = next();
@ -3032,7 +3044,7 @@ loop: for(int x=0, offset=0; x<nCodePoints; x++, offset+=len) {
}
accept(')', "Unclosed group");
flags = save;
flags0 = save;
// Check for quantifiers
Node node = closure(head);
@ -3135,28 +3147,28 @@ loop: for(int x=0, offset=0; x<nCodePoints; x++, offset+=len) {
for (;;) {
switch (ch) {
case 'i':
flags |= CASE_INSENSITIVE;
flags0 |= CASE_INSENSITIVE;
break;
case 'm':
flags |= MULTILINE;
flags0 |= MULTILINE;
break;
case 's':
flags |= DOTALL;
flags0 |= DOTALL;
break;
case 'd':
flags |= UNIX_LINES;
flags0 |= UNIX_LINES;
break;
case 'u':
flags |= UNICODE_CASE;
flags0 |= UNICODE_CASE;
break;
case 'c':
flags |= CANON_EQ;
flags0 |= CANON_EQ;
break;
case 'x':
flags |= COMMENTS;
flags0 |= COMMENTS;
break;
case 'U':
flags |= (UNICODE_CHARACTER_CLASS | UNICODE_CASE);
flags0 |= (UNICODE_CHARACTER_CLASS | UNICODE_CASE);
break;
case '-': // subFlag then fall through
ch = next();
@ -3178,28 +3190,28 @@ loop: for(int x=0, offset=0; x<nCodePoints; x++, offset+=len) {
for (;;) {
switch (ch) {
case 'i':
flags &= ~CASE_INSENSITIVE;
flags0 &= ~CASE_INSENSITIVE;
break;
case 'm':
flags &= ~MULTILINE;
flags0 &= ~MULTILINE;
break;
case 's':
flags &= ~DOTALL;
flags0 &= ~DOTALL;
break;
case 'd':
flags &= ~UNIX_LINES;
flags0 &= ~UNIX_LINES;
break;
case 'u':
flags &= ~UNICODE_CASE;
flags0 &= ~UNICODE_CASE;
break;
case 'c':
flags &= ~CANON_EQ;
flags0 &= ~CANON_EQ;
break;
case 'x':
flags &= ~COMMENTS;
flags0 &= ~COMMENTS;
break;
case 'U':
flags &= ~(UNICODE_CHARACTER_CLASS | UNICODE_CASE);
flags0 &= ~(UNICODE_CHARACTER_CLASS | UNICODE_CASE);
break;
default:
return;

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2007, 2018, 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
@ -27,6 +27,8 @@ package jdk.internal.misc;
import java.io.FileDescriptor;
import java.io.IOException;
import jdk.internal.ref.PhantomCleanable;
/*
* @author Chris Hegarty
*/
@ -38,6 +40,8 @@ public interface JavaIOFileDescriptorAccess {
public boolean getAppend(FileDescriptor fdo);
public void close(FileDescriptor fdo) throws IOException;
public void registerCleanup(FileDescriptor fdo);
public void registerCleanup(FileDescriptor fdo, PhantomCleanable<Object> cleanable);
public void unregisterCleanup(FileDescriptor fdo);
// Only valid on Windows
public void setHandle(FileDescriptor fdo, long handle);

View file

@ -64,7 +64,7 @@ import static jdk.internal.module.ClassFileConstants.*;
public final class ModuleInfo {
private final int JAVA_MIN_SUPPORTED_VERSION = 53;
private final int JAVA_MAX_SUPPORTED_VERSION = 54;
private final int JAVA_MAX_SUPPORTED_VERSION = 55;
private static final JavaLangModuleAccess JLMA
= SharedSecrets.getJavaLangModuleAccess();

View file

@ -185,7 +185,7 @@ public class ClassReader {
public ClassReader(final byte[] b, final int off, final int len) {
this.b = b;
// checks the class version
if (readShort(off + 6) > Opcodes.V10) {
if (readShort(off + 6) > Opcodes.V11) {
throw new IllegalArgumentException();
}
// parses the constant pool

View file

@ -90,6 +90,7 @@ public interface Opcodes {
int V1_8 = 0 << 16 | 52;
int V9 = 0 << 16 | 53;
int V10 = 0 << 16 | 54;
int V11 = 0 << 16 | 55;
// access flags

View file

@ -64,14 +64,6 @@ public class Reflection {
@HotSpotIntrinsicCandidate
public static native Class<?> getCallerClass();
/**
* @deprecated This method will be removed.
* This method is a private JDK API and retained temporarily to
* simplify the implementation of sun.misc.Reflection.getCallerClass.
*/
@Deprecated(forRemoval=true)
public static native Class<?> getCallerClass(int depth);
/** Retrieves the access flags written to the class file. For
inner classes these flags may differ from those returned by
Class.getModifiers(), which searches the InnerClasses

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2017 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
@ -22,7 +22,7 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.util;
package jdk.internal.util;
import jdk.internal.HotSpotIntrinsicCandidate;
import jdk.internal.misc.Unsafe;
@ -50,19 +50,19 @@ import jdk.internal.misc.Unsafe;
* responsibility of the caller (direct or otherwise) to perform such checks
* before calling this method.
*/
class ArraysSupport {
public class ArraysSupport {
static final Unsafe U = Unsafe.getUnsafe();
private static final boolean BIG_ENDIAN = U.isBigEndian();
private static final int LOG2_ARRAY_BOOLEAN_INDEX_SCALE = exactLog2(Unsafe.ARRAY_BOOLEAN_INDEX_SCALE);
private static final int LOG2_ARRAY_BYTE_INDEX_SCALE = exactLog2(Unsafe.ARRAY_BYTE_INDEX_SCALE);
private static final int LOG2_ARRAY_CHAR_INDEX_SCALE = exactLog2(Unsafe.ARRAY_CHAR_INDEX_SCALE);
private static final int LOG2_ARRAY_SHORT_INDEX_SCALE = exactLog2(Unsafe.ARRAY_SHORT_INDEX_SCALE);
private static final int LOG2_ARRAY_INT_INDEX_SCALE = exactLog2(Unsafe.ARRAY_INT_INDEX_SCALE);
private static final int LOG2_ARRAY_LONG_INDEX_SCALE = exactLog2(Unsafe.ARRAY_LONG_INDEX_SCALE);
private static final int LOG2_ARRAY_FLOAT_INDEX_SCALE = exactLog2(Unsafe.ARRAY_FLOAT_INDEX_SCALE);
private static final int LOG2_ARRAY_DOUBLE_INDEX_SCALE = exactLog2(Unsafe.ARRAY_DOUBLE_INDEX_SCALE);
public static final int LOG2_ARRAY_BOOLEAN_INDEX_SCALE = exactLog2(Unsafe.ARRAY_BOOLEAN_INDEX_SCALE);
public static final int LOG2_ARRAY_BYTE_INDEX_SCALE = exactLog2(Unsafe.ARRAY_BYTE_INDEX_SCALE);
public static final int LOG2_ARRAY_CHAR_INDEX_SCALE = exactLog2(Unsafe.ARRAY_CHAR_INDEX_SCALE);
public static final int LOG2_ARRAY_SHORT_INDEX_SCALE = exactLog2(Unsafe.ARRAY_SHORT_INDEX_SCALE);
public static final int LOG2_ARRAY_INT_INDEX_SCALE = exactLog2(Unsafe.ARRAY_INT_INDEX_SCALE);
public static final int LOG2_ARRAY_LONG_INDEX_SCALE = exactLog2(Unsafe.ARRAY_LONG_INDEX_SCALE);
public static final int LOG2_ARRAY_FLOAT_INDEX_SCALE = exactLog2(Unsafe.ARRAY_FLOAT_INDEX_SCALE);
public static final int LOG2_ARRAY_DOUBLE_INDEX_SCALE = exactLog2(Unsafe.ARRAY_DOUBLE_INDEX_SCALE);
private static final int LOG2_BYTE_BIT_SIZE = exactLog2(Byte.SIZE);
@ -107,10 +107,10 @@ class ArraysSupport {
* the tail of the two arrays.
*/
@HotSpotIntrinsicCandidate
static int vectorizedMismatch(Object a, long aOffset,
Object b, long bOffset,
int length,
int log2ArrayIndexScale) {
public static int vectorizedMismatch(Object a, long aOffset,
Object b, long bOffset,
int length,
int log2ArrayIndexScale) {
// assert a.getClass().isArray();
// assert b.getClass().isArray();
// assert 0 <= length <= sizeOf(a)
@ -161,9 +161,9 @@ class ArraysSupport {
// Booleans
// Each boolean element takes up one byte
static int mismatch(boolean[] a,
boolean[] b,
int length) {
public static int mismatch(boolean[] a,
boolean[] b,
int length) {
int i = 0;
if (length > 7) {
i = vectorizedMismatch(
@ -181,9 +181,9 @@ class ArraysSupport {
return -1;
}
static int mismatch(boolean[] a, int aFromIndex,
boolean[] b, int bFromIndex,
int length) {
public static int mismatch(boolean[] a, int aFromIndex,
boolean[] b, int bFromIndex,
int length) {
int i = 0;
if (length > 7) {
int aOffset = Unsafe.ARRAY_BOOLEAN_BASE_OFFSET + aFromIndex;
@ -219,9 +219,9 @@ class ArraysSupport {
* no mismatch. The index will be within the range of (inclusive) 0 to
* (exclusive) the smaller of the two array lengths.
*/
static int mismatch(byte[] a,
byte[] b,
int length) {
public static int mismatch(byte[] a,
byte[] b,
int length) {
// ISSUE: defer to index receiving methods if performance is good
// assert length <= a.length
// assert length <= b.length
@ -264,9 +264,9 @@ class ArraysSupport {
* otherwise -1 if no mismatch. The index will be within the range of
* (inclusive) 0 to (exclusive) the smaller of the two array bounds.
*/
static int mismatch(byte[] a, int aFromIndex,
byte[] b, int bFromIndex,
int length) {
public static int mismatch(byte[] a, int aFromIndex,
byte[] b, int bFromIndex,
int length) {
// assert 0 <= aFromIndex < a.length
// assert 0 <= aFromIndex + length <= a.length
// assert 0 <= bFromIndex < b.length
@ -295,9 +295,9 @@ class ArraysSupport {
// Chars
static int mismatch(char[] a,
char[] b,
int length) {
public static int mismatch(char[] a,
char[] b,
int length) {
int i = 0;
if (length > 3) {
i = vectorizedMismatch(
@ -315,9 +315,9 @@ class ArraysSupport {
return -1;
}
static int mismatch(char[] a, int aFromIndex,
char[] b, int bFromIndex,
int length) {
public static int mismatch(char[] a, int aFromIndex,
char[] b, int bFromIndex,
int length) {
int i = 0;
if (length > 3) {
int aOffset = Unsafe.ARRAY_CHAR_BASE_OFFSET + (aFromIndex << LOG2_ARRAY_CHAR_INDEX_SCALE);
@ -340,9 +340,9 @@ class ArraysSupport {
// Shorts
static int mismatch(short[] a,
short[] b,
int length) {
public static int mismatch(short[] a,
short[] b,
int length) {
int i = 0;
if (length > 3) {
i = vectorizedMismatch(
@ -360,9 +360,9 @@ class ArraysSupport {
return -1;
}
static int mismatch(short[] a, int aFromIndex,
short[] b, int bFromIndex,
int length) {
public static int mismatch(short[] a, int aFromIndex,
short[] b, int bFromIndex,
int length) {
int i = 0;
if (length > 3) {
int aOffset = Unsafe.ARRAY_SHORT_BASE_OFFSET + (aFromIndex << LOG2_ARRAY_SHORT_INDEX_SCALE);
@ -385,9 +385,9 @@ class ArraysSupport {
// Ints
static int mismatch(int[] a,
int[] b,
int length) {
public static int mismatch(int[] a,
int[] b,
int length) {
int i = 0;
if (length > 1) {
i = vectorizedMismatch(
@ -405,9 +405,9 @@ class ArraysSupport {
return -1;
}
static int mismatch(int[] a, int aFromIndex,
int[] b, int bFromIndex,
int length) {
public static int mismatch(int[] a, int aFromIndex,
int[] b, int bFromIndex,
int length) {
int i = 0;
if (length > 1) {
int aOffset = Unsafe.ARRAY_INT_BASE_OFFSET + (aFromIndex << LOG2_ARRAY_INT_INDEX_SCALE);
@ -430,15 +430,15 @@ class ArraysSupport {
// Floats
static int mismatch(float[] a,
float[] b,
int length) {
public static int mismatch(float[] a,
float[] b,
int length) {
return mismatch(a, 0, b, 0, length);
}
static int mismatch(float[] a, int aFromIndex,
float[] b, int bFromIndex,
int length) {
public static int mismatch(float[] a, int aFromIndex,
float[] b, int bFromIndex,
int length) {
int i = 0;
if (length > 1) {
int aOffset = Unsafe.ARRAY_FLOAT_BASE_OFFSET + (aFromIndex << LOG2_ARRAY_FLOAT_INDEX_SCALE);
@ -475,9 +475,9 @@ class ArraysSupport {
// Long
static int mismatch(long[] a,
long[] b,
int length) {
public static int mismatch(long[] a,
long[] b,
int length) {
if (length == 0) {
return -1;
}
@ -488,9 +488,9 @@ class ArraysSupport {
return i >= 0 ? i : -1;
}
static int mismatch(long[] a, int aFromIndex,
long[] b, int bFromIndex,
int length) {
public static int mismatch(long[] a, int aFromIndex,
long[] b, int bFromIndex,
int length) {
if (length == 0) {
return -1;
}
@ -506,15 +506,15 @@ class ArraysSupport {
// Double
static int mismatch(double[] a,
double[] b,
int length) {
public static int mismatch(double[] a,
double[] b,
int length) {
return mismatch(a, 0, b, 0, length);
}
static int mismatch(double[] a, int aFromIndex,
double[] b, int bFromIndex,
int length) {
public static int mismatch(double[] a, int aFromIndex,
double[] b, int bFromIndex,
int length) {
if (length == 0) {
return -1;
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2018, 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
@ -142,7 +142,7 @@ module java.base {
java.instrument,
java.logging;
exports jdk.internal.jmod to
jdk.compiler, // reflective dependency
jdk.compiler,
jdk.jlink;
exports jdk.internal.logger to
java.logging;
@ -172,7 +172,7 @@ module java.base {
java.xml,
jdk.attach,
jdk.charsets,
jdk.compiler, // reflective dependency
jdk.compiler,
jdk.incubator.httpclient,
jdk.jdeps,
jdk.jlink,

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2018, 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
@ -136,7 +136,7 @@ abstract class AsynchronousFileChannelImpl
if (fileLockTable == null) {
synchronized (this) {
if (fileLockTable == null) {
fileLockTable = FileLockTable.newSharedFileLockTable(this, fdObj);
fileLockTable = new FileLockTable(this, fdObj);
}
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2018, 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
@ -27,11 +27,32 @@ package sun.nio.ch;
import java.io.FileDescriptor;
import java.io.IOException;
import java.net.*;
import java.net.DatagramSocket;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.net.PortUnreachableException;
import java.net.ProtocolFamily;
import java.net.SocketAddress;
import java.net.SocketOption;
import java.net.StandardProtocolFamily;
import java.net.StandardSocketOptions;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.nio.channels.spi.*;
import java.util.*;
import java.nio.channels.AlreadyBoundException;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.DatagramChannel;
import java.nio.channels.MembershipKey;
import java.nio.channels.NotYetConnectedException;
import java.nio.channels.SelectionKey;
import java.nio.channels.UnsupportedAddressTypeException;
import java.nio.channels.spi.SelectorProvider;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.locks.ReentrantLock;
import sun.net.ResourceManager;
import sun.net.ext.ExtendedSocketOptions;
@ -49,9 +70,6 @@ class DatagramChannelImpl
// Our file descriptor
private final FileDescriptor fd;
// fd value needed for dev/poll. This value will remain valid
// even after the value in the file descriptor object has been set to -1
private final int fdVal;
// The protocol family of the socket
@ -67,10 +85,10 @@ class DatagramChannelImpl
private int cachedSenderPort;
// Lock held by current reading or connecting thread
private final Object readLock = new Object();
private final ReentrantLock readLock = new ReentrantLock();
// Lock held by current writing or connecting thread
private final Object writeLock = new Object();
private final ReentrantLock writeLock = new ReentrantLock();
// Lock held by any thread that modifies the state fields declared below
// DO NOT invoke a blocking I/O operation while holding this lock!
@ -103,7 +121,6 @@ class DatagramChannelImpl
// -- End of fields protected by stateLock
public DatagramChannelImpl(SelectorProvider sp)
throws IOException
{
@ -138,16 +155,27 @@ class DatagramChannelImpl
throw new UnsupportedOperationException("IPv6 not available");
}
}
this.family = family;
this.fd = Net.socket(family, false);
this.fdVal = IOUtil.fdVal(fd);
this.state = ST_UNCONNECTED;
ResourceManager.beforeUdpCreate();
try {
this.family = family;
this.fd = Net.socket(family, false);
this.fdVal = IOUtil.fdVal(fd);
this.state = ST_UNCONNECTED;
} catch (IOException ioe) {
ResourceManager.afterUdpClose();
throw ioe;
}
}
public DatagramChannelImpl(SelectorProvider sp, FileDescriptor fd)
throws IOException
{
super(sp);
// increment UDP count to match decrement when closing
ResourceManager.beforeUdpCreate();
this.family = Net.isIPv6Available() ?
StandardProtocolFamily.INET6 : StandardProtocolFamily.INET;
this.fd = fd;
@ -328,7 +356,8 @@ class DatagramChannelImpl
public SocketAddress receive(ByteBuffer dst) throws IOException {
if (dst.isReadOnly())
throw new IllegalArgumentException("Read-only buffer");
synchronized (readLock) {
readLock.lock();
try {
ensureOpen();
// Socket was not bound before attempting receive
if (localAddress() == null)
@ -348,6 +377,8 @@ class DatagramChannelImpl
if (n == IOStatus.UNAVAILABLE)
return null;
} else {
// Cannot receive into user's buffer when running with a
// security manager and not connected
bb = Util.getTemporaryDirectBuffer(dst.remaining());
for (;;) {
do {
@ -379,6 +410,8 @@ class DatagramChannelImpl
end((n > 0) || (n == IOStatus.UNAVAILABLE));
assert IOStatus.check(n);
}
} finally {
readLock.unlock();
}
}
@ -425,7 +458,8 @@ class DatagramChannelImpl
if (src == null)
throw new NullPointerException();
synchronized (writeLock) {
writeLock.lock();
try {
ensureOpen();
InetSocketAddress isa = Net.checkAddress(target);
InetAddress ia = isa.getAddress();
@ -474,6 +508,8 @@ class DatagramChannelImpl
end((n > 0) || (n == IOStatus.UNAVAILABLE));
assert IOStatus.check(n);
}
} finally {
writeLock.unlock();
}
}
@ -534,7 +570,8 @@ class DatagramChannelImpl
public int read(ByteBuffer buf) throws IOException {
if (buf == null)
throw new NullPointerException();
synchronized (readLock) {
readLock.lock();
try {
synchronized (stateLock) {
ensureOpen();
if (!isConnected())
@ -555,6 +592,8 @@ class DatagramChannelImpl
end((n > 0) || (n == IOStatus.UNAVAILABLE));
assert IOStatus.check(n);
}
} finally {
readLock.unlock();
}
}
@ -563,7 +602,8 @@ class DatagramChannelImpl
{
if ((offset < 0) || (length < 0) || (offset > dsts.length - length))
throw new IndexOutOfBoundsException();
synchronized (readLock) {
readLock.lock();
try {
synchronized (stateLock) {
ensureOpen();
if (!isConnected())
@ -584,13 +624,16 @@ class DatagramChannelImpl
end((n > 0) || (n == IOStatus.UNAVAILABLE));
assert IOStatus.check(n);
}
} finally {
readLock.unlock();
}
}
public int write(ByteBuffer buf) throws IOException {
if (buf == null)
throw new NullPointerException();
synchronized (writeLock) {
writeLock.lock();
try {
synchronized (stateLock) {
ensureOpen();
if (!isConnected())
@ -611,6 +654,8 @@ class DatagramChannelImpl
end((n > 0) || (n == IOStatus.UNAVAILABLE));
assert IOStatus.check(n);
}
} finally {
writeLock.unlock();
}
}
@ -619,7 +664,8 @@ class DatagramChannelImpl
{
if ((offset < 0) || (length < 0) || (offset > srcs.length - length))
throw new IndexOutOfBoundsException();
synchronized (writeLock) {
writeLock.lock();
try {
synchronized (stateLock) {
ensureOpen();
if (!isConnected())
@ -640,6 +686,8 @@ class DatagramChannelImpl
end((n > 0) || (n == IOStatus.UNAVAILABLE));
assert IOStatus.check(n);
}
} finally {
writeLock.unlock();
}
}
@ -661,8 +709,10 @@ class DatagramChannelImpl
@Override
public DatagramChannel bind(SocketAddress local) throws IOException {
synchronized (readLock) {
synchronized (writeLock) {
readLock.lock();
try {
writeLock.lock();
try {
synchronized (stateLock) {
ensureOpen();
if (localAddress != null)
@ -692,7 +742,11 @@ class DatagramChannelImpl
Net.bind(family, fd, isa.getAddress(), isa.getPort());
localAddress = Net.localAddress(fd);
}
} finally {
writeLock.unlock();
}
} finally {
readLock.unlock();
}
return this;
}
@ -714,8 +768,10 @@ class DatagramChannelImpl
@Override
public DatagramChannel connect(SocketAddress sa) throws IOException {
synchronized(readLock) {
synchronized(writeLock) {
readLock.lock();
try {
writeLock.lock();
try {
synchronized (stateLock) {
ensureOpenAndUnconnected();
InetSocketAddress isa = Net.checkAddress(sa);
@ -741,10 +797,9 @@ class DatagramChannelImpl
localAddress = Net.localAddress(fd);
// flush any packets already received.
boolean blocking = false;
synchronized (blockingLock()) {
boolean blocking = isBlocking();
try {
blocking = isBlocking();
ByteBuffer tmpBuf = ByteBuffer.allocate(100);
if (blocking) {
configureBlocking(false);
@ -759,14 +814,20 @@ class DatagramChannelImpl
}
}
}
} finally {
writeLock.unlock();
}
} finally {
readLock.unlock();
}
return this;
}
public DatagramChannel disconnect() throws IOException {
synchronized(readLock) {
synchronized(writeLock) {
readLock.lock();
try {
writeLock.lock();
try {
synchronized (stateLock) {
if (!isConnected() || !isOpen())
return this;
@ -783,7 +844,11 @@ class DatagramChannelImpl
// refresh local address
localAddress = Net.localAddress(fd);
}
} finally {
writeLock.unlock();
}
} finally {
readLock.unlock();
}
return this;
}
@ -1087,7 +1152,8 @@ class DatagramChannelImpl
int poll(int events, long timeout) throws IOException {
assert Thread.holdsLock(blockingLock()) && !isBlocking();
synchronized (readLock) {
readLock.lock();
try {
int n = 0;
try {
begin();
@ -1102,6 +1168,8 @@ class DatagramChannelImpl
end(n > 0);
}
return n;
} finally {
readLock.unlock();
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2018, 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
@ -25,10 +25,22 @@
package sun.nio.ch;
import java.io.*;
import java.net.*;
import java.nio.*;
import java.nio.channels.*;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.DatagramSocketImpl;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.net.SocketAddress;
import java.net.SocketException;
import java.net.SocketOption;
import java.net.SocketTimeoutException;
import java.net.StandardSocketOptions;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.DatagramChannel;
import java.nio.channels.IllegalBlockingModeException;
// Make a datagram-socket channel look like a datagram socket.
@ -178,7 +190,6 @@ public class DatagramSocketAdaptor
dc.configureBlocking(false);
try {
int n;
SocketAddress sender;
if ((sender = dc.receive(bb)) != null)
return sender;
@ -188,19 +199,18 @@ public class DatagramSocketAdaptor
throw new ClosedChannelException();
long st = System.currentTimeMillis();
int result = dc.poll(Net.POLLIN, to);
if (result > 0 &&
((result & Net.POLLIN) != 0)) {
if (result > 0 && ((result & Net.POLLIN) != 0)) {
if ((sender = dc.receive(bb)) != null)
return sender;
}
to -= System.currentTimeMillis() - st;
if (to <= 0)
throw new SocketTimeoutException();
}
} finally {
if (dc.isOpen())
try {
dc.configureBlocking(true);
} catch (ClosedChannelException e) { }
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2018, 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
@ -1083,49 +1083,19 @@ public class FileChannelImpl
// -- Locks --
// keeps track of locks on this file
private volatile FileLockTable fileLockTable;
// indicates if file locks are maintained system-wide (as per spec)
private static boolean isSharedFileLockTable;
// indicates if the disableSystemWideOverlappingFileLockCheck property
// has been checked
private static volatile boolean propertyChecked;
// The lock list in J2SE 1.4/5.0 was local to each FileChannel instance so
// the overlap check wasn't system wide when there were multiple channels to
// the same file. This property is used to get 1.4/5.0 behavior if desired.
private static boolean isSharedFileLockTable() {
if (!propertyChecked) {
synchronized (FileChannelImpl.class) {
if (!propertyChecked) {
String value = GetPropertyAction.privilegedGetProperty(
"sun.nio.ch.disableSystemWideOverlappingFileLockCheck");
isSharedFileLockTable = ((value == null) || value.equals("false"));
propertyChecked = true;
}
}
}
return isSharedFileLockTable;
}
private FileLockTable fileLockTable() throws IOException {
if (fileLockTable == null) {
synchronized (this) {
if (fileLockTable == null) {
if (isSharedFileLockTable()) {
int ti = threads.add();
try {
ensureOpen();
fileLockTable = FileLockTable.newSharedFileLockTable(this, fd);
} finally {
threads.remove(ti);
}
} else {
fileLockTable = new SimpleFileLockTable();
int ti = threads.add();
try {
ensureOpen();
fileLockTable = new FileLockTable(this, fd);
} finally {
threads.remove(ti);
}
}
}
@ -1229,59 +1199,6 @@ public class FileChannelImpl
fileLockTable.remove(fli);
}
// -- File lock support --
/**
* A simple file lock table that maintains a list of FileLocks obtained by a
* FileChannel. Use to get 1.4/5.0 behaviour.
*/
private static class SimpleFileLockTable extends FileLockTable {
// synchronize on list for access
private final List<FileLock> lockList = new ArrayList<FileLock>(2);
public SimpleFileLockTable() {
}
private void checkList(long position, long size)
throws OverlappingFileLockException
{
assert Thread.holdsLock(lockList);
for (FileLock fl: lockList) {
if (fl.overlaps(position, size)) {
throw new OverlappingFileLockException();
}
}
}
public void add(FileLock fl) throws OverlappingFileLockException {
synchronized (lockList) {
checkList(fl.position(), fl.size());
lockList.add(fl);
}
}
public void remove(FileLock fl) {
synchronized (lockList) {
lockList.remove(fl);
}
}
public List<FileLock> removeAll() {
synchronized(lockList) {
List<FileLock> result = new ArrayList<FileLock>(lockList);
lockList.clear();
return result;
}
}
public void replace(FileLock fl1, FileLock fl2) {
synchronized (lockList) {
lockList.remove(fl1);
lockList.add(fl2);
}
}
}
// -- Native methods --
// Creates a new mapping

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2018, 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
@ -25,64 +25,27 @@
package sun.nio.ch;
import java.nio.channels.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.lang.ref.*;
import java.io.FileDescriptor;
import java.io.IOException;
abstract class FileLockTable {
protected FileLockTable() {
}
/**
* Creates and returns a file lock table for a channel that is connected to
* the a system-wide map of all file locks for the Java virtual machine.
*/
public static FileLockTable newSharedFileLockTable(Channel channel,
FileDescriptor fd)
throws IOException
{
return new SharedFileLockTable(channel, fd);
}
/**
* Adds a file lock to the table.
*
* @throws OverlappingFileLockException if the file lock overlaps
* with an existing file lock in the table
*/
public abstract void add(FileLock fl) throws OverlappingFileLockException;
/**
* Remove an existing file lock from the table.
*/
public abstract void remove(FileLock fl);
/**
* Removes all file locks from the table.
*
* @return The list of file locks removed
*/
public abstract List<FileLock> removeAll();
/**
* Replaces an existing file lock in the table.
*/
public abstract void replace(FileLock fl1, FileLock fl2);
}
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.nio.channels.Channel;
import java.nio.channels.FileLock;
import java.nio.channels.OverlappingFileLockException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
* A file lock table that is over a system-wide map of all file locks.
*/
class SharedFileLockTable extends FileLockTable {
class FileLockTable {
/**
* A weak reference to a FileLock.
* <p>
* SharedFileLockTable uses a list of file lock references to avoid keeping the
* FileLockTable uses a list of file lock references to avoid keeping the
* FileLock (and FileChannel) alive.
*/
private static class FileLockReference extends WeakReference<FileLock> {
@ -115,13 +78,20 @@ class SharedFileLockTable extends FileLockTable {
// File key for the file that this channel is connected to
private final FileKey fileKey;
SharedFileLockTable(Channel channel, FileDescriptor fd) throws IOException {
// Locks obtained for this channel
private final Set<FileLock> locks;
/**
* Creates a file lock table for a channel that is connected to the
* system-wide map of all file locks for the Java virtual machine.
*/
FileLockTable(Channel channel, FileDescriptor fd) throws IOException {
this.channel = channel;
this.fileKey = FileKey.create(fd);
this.locks = new HashSet<FileLock>();
}
@Override
public void add(FileLock fl) throws OverlappingFileLockException {
void add(FileLock fl) throws OverlappingFileLockException {
List<FileLockReference> list = lockMap.get(fileKey);
for (;;) {
@ -135,6 +105,7 @@ class SharedFileLockTable extends FileLockTable {
if (prev == null) {
// we successfully created the key so we add the file lock
list.add(new FileLockReference(fl, queue, fileKey));
locks.add(fl);
break;
}
}
@ -151,6 +122,7 @@ class SharedFileLockTable extends FileLockTable {
if (list == current) {
checkList(list, fl.position(), fl.size());
list.add(new FileLockReference(fl, queue, fileKey));
locks.add(fl);
break;
}
list = current;
@ -170,8 +142,7 @@ class SharedFileLockTable extends FileLockTable {
}
}
@Override
public void remove(FileLock fl) {
void remove(FileLock fl) {
assert fl != null;
// the lock must exist so the list of locks must be present
@ -187,6 +158,7 @@ class SharedFileLockTable extends FileLockTable {
assert (lock != null) && (lock.acquiredBy() == channel);
ref.clear();
list.remove(index);
locks.remove(fl);
break;
}
index++;
@ -194,8 +166,7 @@ class SharedFileLockTable extends FileLockTable {
}
}
@Override
public List<FileLock> removeAll() {
List<FileLock> removeAll() {
List<FileLock> result = new ArrayList<FileLock>();
List<FileLockReference> list = lockMap.get(fileKey);
if (list != null) {
@ -220,13 +191,14 @@ class SharedFileLockTable extends FileLockTable {
// once the lock list is empty we remove it from the map
removeKeyIfEmpty(fileKey, list);
locks.clear();
}
}
return result;
}
@Override
public void replace(FileLock fromLock, FileLock toLock) {
void replace(FileLock fromLock, FileLock toLock) {
// the lock must exist so there must be a list
List<FileLockReference> list = lockMap.get(fileKey);
assert list != null;
@ -238,6 +210,8 @@ class SharedFileLockTable extends FileLockTable {
if (lock == fromLock) {
ref.clear();
list.set(index, new FileLockReference(toLock, queue, fileKey));
locks.remove(fromLock);
locks.add(toLock);
break;
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2018, 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
@ -78,7 +78,7 @@ public class IOUtil {
src.position(pos);
int n = writeFromNativeBuffer(fd, bb, position,
directIO, alignment, nd);
directIO, alignment, nd);
if (n > 0) {
// now update src
src.position(pos + n);
@ -161,8 +161,7 @@ public class IOUtil {
if (!(buf instanceof DirectBuffer)) {
ByteBuffer shadow;
if (directIO)
shadow = Util.getTemporaryAlignedDirectBuffer(rem,
alignment);
shadow = Util.getTemporaryAlignedDirectBuffer(rem, alignment);
else
shadow = Util.getTemporaryDirectBuffer(rem);
shadow.put(buf);
@ -241,8 +240,7 @@ public class IOUtil {
int rem = dst.remaining();
if (directIO) {
Util.checkRemainingBufferSizeAligned(rem, alignment);
bb = Util.getTemporaryAlignedDirectBuffer(rem,
alignment);
bb = Util.getTemporaryAlignedDirectBuffer(rem, alignment);
} else {
bb = Util.getTemporaryDirectBuffer(rem);
}
@ -277,8 +275,7 @@ public class IOUtil {
return 0;
int n = 0;
if (position != -1) {
n = nd.pread(fd, ((DirectBuffer)bb).address() + pos,
rem, position);
n = nd.pread(fd, ((DirectBuffer)bb).address() + pos, rem, position);
} else {
n = nd.read(fd, ((DirectBuffer)bb).address() + pos, rem);
}
@ -332,8 +329,7 @@ public class IOUtil {
if (!(buf instanceof DirectBuffer)) {
ByteBuffer shadow;
if (directIO) {
shadow = Util.getTemporaryAlignedDirectBuffer(rem,
alignment);
shadow = Util.getTemporaryAlignedDirectBuffer(rem, alignment);
} else {
shadow = Util.getTemporaryDirectBuffer(rem);
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2018, 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
@ -25,9 +25,20 @@
package sun.nio.ch;
import java.io.*;
import java.net.*;
import java.nio.channels.*;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.StandardSocketOptions;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.IllegalBlockingModeException;
import java.nio.channels.NotYetBoundException;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
// Make a server-socket channel look like a server socket.
@ -37,7 +48,7 @@ import java.nio.channels.*;
// class.
//
public class ServerSocketAdaptor // package-private
class ServerSocketAdaptor // package-private
extends ServerSocket
{
@ -96,13 +107,18 @@ public class ServerSocketAdaptor // package-private
try {
if (!ssc.isBound())
throw new NotYetBoundException();
if (timeout == 0) {
// for compatibility reasons: accept connection if available
// when configured non-blocking
SocketChannel sc = ssc.accept();
if (sc == null && !ssc.isBlocking())
throw new IllegalBlockingModeException();
return sc.socket();
}
if (!ssc.isBlocking())
throw new IllegalBlockingModeException();
ssc.configureBlocking(false);
try {
SocketChannel sc;
@ -121,10 +137,10 @@ public class ServerSocketAdaptor // package-private
throw new SocketTimeoutException();
}
} finally {
if (ssc.isOpen())
try {
ssc.configureBlocking(true);
} catch (ClosedChannelException e) { }
}
} catch (Exception x) {
Net.translateException(x);
assert false;
@ -178,8 +194,7 @@ public class ServerSocketAdaptor // package-private
if (!isBound())
return "ServerSocket[unbound]";
return "ServerSocket[addr=" + getInetAddress() +
// ",port=" + getPort() +
",localport=" + getLocalPort() + "]";
",localport=" + getLocalPort() + "]";
}
public void setReceiveBufferSize(int size) throws SocketException {

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2018, 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
@ -27,10 +27,25 @@ package sun.nio.ch;
import java.io.FileDescriptor;
import java.io.IOException;
import java.net.*;
import java.nio.channels.*;
import java.nio.channels.spi.*;
import java.util.*;
import java.net.InetSocketAddress;
import java.net.ProtocolFamily;
import java.net.ServerSocket;
import java.net.SocketAddress;
import java.net.SocketOption;
import java.net.StandardProtocolFamily;
import java.net.StandardSocketOptions;
import java.nio.channels.AlreadyBoundException;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.NotYetBoundException;
import java.nio.channels.SelectionKey;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.channels.spi.SelectorProvider;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.locks.ReentrantLock;
import sun.net.NetHooks;
/**
@ -47,16 +62,13 @@ class ServerSocketChannelImpl
// Our file descriptor
private final FileDescriptor fd;
// fd value needed for dev/poll. This value will remain valid
// even after the value in the file descriptor object has been set to -1
private int fdVal;
private final int fdVal;
// ID of native thread currently blocked in this channel, for signalling
private volatile long thread;
// Lock held by thread currently blocked in this channel
private final Object lock = new Object();
private final ReentrantLock acceptLock = new ReentrantLock();
// Lock held by any thread that modifies the state fields declared below
// DO NOT invoke a blocking I/O operation while holding this lock!
@ -77,7 +89,7 @@ class ServerSocketChannelImpl
private boolean isReuseAddress;
// Our socket adaptor, if any
ServerSocket socket;
private ServerSocket socket;
// -- End of fields protected by stateLock
@ -211,7 +223,8 @@ class ServerSocketChannelImpl
@Override
public ServerSocketChannel bind(SocketAddress local, int backlog) throws IOException {
synchronized (lock) {
acceptLock.lock();
try {
if (!isOpen())
throw new ClosedChannelException();
if (isBound())
@ -227,12 +240,15 @@ class ServerSocketChannelImpl
synchronized (stateLock) {
localAddress = Net.localAddress(fd);
}
} finally {
acceptLock.unlock();
}
return this;
}
public SocketChannel accept() throws IOException {
synchronized (lock) {
acceptLock.lock();
try {
if (!isOpen())
throw new ClosedChannelException();
if (!isBound())
@ -278,6 +294,8 @@ class ServerSocketChannelImpl
}
return sc;
} finally {
acceptLock.unlock();
}
}
@ -353,7 +371,8 @@ class ServerSocketChannelImpl
int poll(int events, long timeout) throws IOException {
assert Thread.holdsLock(blockingLock()) && !isBlocking();
synchronized (lock) {
acceptLock.lock();
try {
int n = 0;
try {
begin();
@ -368,6 +387,8 @@ class ServerSocketChannelImpl
end(n > 0);
}
return n;
} finally {
acceptLock.unlock();
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2018, 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
@ -25,10 +25,23 @@
package sun.nio.ch;
import java.io.*;
import java.net.*;
import java.nio.*;
import java.nio.channels.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketException;
import java.net.SocketImpl;
import java.net.SocketOption;
import java.net.SocketTimeoutException;
import java.net.StandardSocketOptions;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.IllegalBlockingModeException;
import java.nio.channels.SocketChannel;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;
import java.util.concurrent.TimeUnit;
@ -45,7 +58,7 @@ import java.util.concurrent.TimeUnit;
// java.net.Socket so as to simplify tracking future changes to that class.
//
public class SocketAdaptor
class SocketAdaptor
extends Socket
{
@ -89,7 +102,6 @@ public class SocketAdaptor
throw new IllegalBlockingModeException();
try {
if (timeout == 0) {
sc.connect(remote);
return;
@ -119,8 +131,9 @@ public class SocketAdaptor
}
}
} finally {
if (sc.isOpen())
try {
sc.configureBlocking(true);
} catch (ClosedChannelException e) { }
}
} catch (Exception x) {
@ -188,10 +201,11 @@ public class SocketAdaptor
synchronized (sc.blockingLock()) {
if (!sc.isBlocking())
throw new IllegalBlockingModeException();
if (timeout == 0)
return sc.read(bb);
sc.configureBlocking(false);
sc.configureBlocking(false);
try {
int n;
if ((n = sc.read(bb)) != 0)
@ -213,10 +227,10 @@ public class SocketAdaptor
throw new SocketTimeoutException();
}
} finally {
if (sc.isOpen())
try {
sc.configureBlocking(true);
} catch (ClosedChannelException e) { }
}
}
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2018, 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
@ -27,11 +27,30 @@ package sun.nio.ch;
import java.io.FileDescriptor;
import java.io.IOException;
import java.net.*;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ProtocolFamily;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketOption;
import java.net.StandardProtocolFamily;
import java.net.StandardSocketOptions;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.nio.channels.spi.*;
import java.util.*;
import java.nio.channels.AlreadyBoundException;
import java.nio.channels.AlreadyConnectedException;
import java.nio.channels.AsynchronousCloseException;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.ConnectionPendingException;
import java.nio.channels.NoConnectionPendingException;
import java.nio.channels.NotYetConnectedException;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;
import java.nio.channels.spi.SelectorProvider;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.locks.ReentrantLock;
import sun.net.NetHooks;
import sun.net.ext.ExtendedSocketOptions;
@ -49,9 +68,6 @@ class SocketChannelImpl
// Our file descriptor object
private final FileDescriptor fd;
// fd value needed for dev/poll. This value will remain valid
// even after the value in the file descriptor object has been set to -1
private final int fdVal;
// IDs of native threads doing reads and writes, for signalling
@ -59,10 +75,10 @@ class SocketChannelImpl
private volatile long writerThread;
// Lock held by current reading or connecting thread
private final Object readLock = new Object();
private final ReentrantLock readLock = new ReentrantLock();
// Lock held by current writing or connecting thread
private final Object writeLock = new Object();
private final ReentrantLock writeLock = new ReentrantLock();
// Lock held by any thread that modifies the state fields declared below
// DO NOT invoke a blocking I/O operation while holding this lock!
@ -89,7 +105,6 @@ class SocketChannelImpl
// Input/Output open
private boolean isInputOpen = true;
private boolean isOutputOpen = true;
private boolean readyToConnect = false;
// Socket adaptor, created on demand
private Socket socket;
@ -298,7 +313,8 @@ class SocketChannelImpl
if (buf == null)
throw new NullPointerException();
synchronized (readLock) {
readLock.lock();
try {
if (!ensureReadOpen())
return -1;
int n = 0;
@ -418,6 +434,8 @@ class SocketChannelImpl
assert IOStatus.check(n);
}
} finally {
readLock.unlock();
}
}
@ -426,7 +444,8 @@ class SocketChannelImpl
{
if ((offset < 0) || (length < 0) || (offset > dsts.length - length))
throw new IndexOutOfBoundsException();
synchronized (readLock) {
readLock.lock();
try {
if (!ensureReadOpen())
return -1;
long n = 0;
@ -453,13 +472,16 @@ class SocketChannelImpl
}
assert IOStatus.check(n);
}
} finally {
readLock.unlock();
}
}
public int write(ByteBuffer buf) throws IOException {
if (buf == null)
throw new NullPointerException();
synchronized (writeLock) {
writeLock.lock();
try {
ensureWriteOpen();
int n = 0;
try {
@ -484,6 +506,8 @@ class SocketChannelImpl
}
assert IOStatus.check(n);
}
} finally {
writeLock.unlock();
}
}
@ -492,7 +516,8 @@ class SocketChannelImpl
{
if ((offset < 0) || (length < 0) || (offset > srcs.length - length))
throw new IndexOutOfBoundsException();
synchronized (writeLock) {
writeLock.lock();
try {
ensureWriteOpen();
long n = 0;
try {
@ -517,12 +542,15 @@ class SocketChannelImpl
}
assert IOStatus.check(n);
}
} finally {
writeLock.unlock();
}
}
// package-private
int sendOutOfBandData(byte b) throws IOException {
synchronized (writeLock) {
writeLock.lock();
try {
ensureWriteOpen();
int n = 0;
try {
@ -547,6 +575,8 @@ class SocketChannelImpl
}
assert IOStatus.check(n);
}
} finally {
writeLock.unlock();
}
}
@ -568,8 +598,10 @@ class SocketChannelImpl
@Override
public SocketChannel bind(SocketAddress local) throws IOException {
synchronized (readLock) {
synchronized (writeLock) {
readLock.lock();
try {
writeLock.lock();
try {
synchronized (stateLock) {
if (!isOpen())
throw new ClosedChannelException();
@ -587,7 +619,11 @@ class SocketChannelImpl
Net.bind(fd, isa.getAddress(), isa.getPort());
localAddress = Net.localAddress(fd);
}
} finally {
writeLock.unlock();
}
} finally {
readLock.unlock();
}
return this;
}
@ -616,14 +652,16 @@ class SocketChannelImpl
}
public boolean connect(SocketAddress sa) throws IOException {
synchronized (readLock) {
synchronized (writeLock) {
readLock.lock();
try {
writeLock.lock();
try {
ensureOpenAndUnconnected();
InetSocketAddress isa = Net.checkAddress(sa);
SecurityManager sm = System.getSecurityManager();
if (sm != null)
sm.checkConnect(isa.getAddress().getHostAddress(),
isa.getPort());
isa.getPort());
synchronized (blockingLock()) {
int n = 0;
try {
@ -636,8 +674,8 @@ class SocketChannelImpl
// notify hook only if unbound
if (localAddress == null) {
NetHooks.beforeTcpConnect(fd,
isa.getAddress(),
isa.getPort());
isa.getAddress(),
isa.getPort());
}
readerThread = NativeThread.current();
}
@ -646,10 +684,9 @@ class SocketChannelImpl
if (ia.isAnyLocalAddress())
ia = InetAddress.getLocalHost();
n = Net.connect(fd,
ia,
isa.getPort());
if ( (n == IOStatus.INTERRUPTED)
&& isOpen())
ia,
isa.getPort());
if ((n == IOStatus.INTERRUPTED) && isOpen())
continue;
break;
}
@ -686,13 +723,19 @@ class SocketChannelImpl
}
}
return false;
} finally {
writeLock.unlock();
}
} finally {
readLock.unlock();
}
}
public boolean finishConnect() throws IOException {
synchronized (readLock) {
synchronized (writeLock) {
readLock.lock();
try {
writeLock.lock();
try {
synchronized (stateLock) {
if (!isOpen())
throw new ClosedChannelException();
@ -714,24 +757,20 @@ class SocketChannelImpl
}
if (!isBlocking()) {
for (;;) {
n = checkConnect(fd, false,
readyToConnect);
if ( (n == IOStatus.INTERRUPTED)
&& isOpen())
n = checkConnect(fd, false);
if ((n == IOStatus.INTERRUPTED) && isOpen())
continue;
break;
}
} else {
for (;;) {
n = checkConnect(fd, true,
readyToConnect);
n = checkConnect(fd, true);
if (n == 0) {
// Loop in case of
// spurious notifications
continue;
}
if ( (n == IOStatus.INTERRUPTED)
&& isOpen())
if ((n == IOStatus.INTERRUPTED) && isOpen())
continue;
break;
}
@ -769,7 +808,11 @@ class SocketChannelImpl
return true;
}
return false;
} finally {
writeLock.unlock();
}
} finally {
readLock.unlock();
}
}
@ -903,9 +946,6 @@ class SocketChannelImpl
if ((ops & (Net.POLLERR | Net.POLLHUP)) != 0) {
newOps = intOps;
sk.nioReadyOps(newOps);
// No need to poll again in checkConnect,
// the error will be detected there
readyToConnect = true;
return (newOps & ~oldOps) != 0;
}
@ -918,7 +958,6 @@ class SocketChannelImpl
((intOps & SelectionKey.OP_CONNECT) != 0) &&
((state == ST_UNCONNECTED) || (state == ST_PENDING))) {
newOps |= SelectionKey.OP_CONNECT;
readyToConnect = true;
}
if (((ops & Net.POLLOUT) != 0) &&
@ -942,7 +981,8 @@ class SocketChannelImpl
int poll(int events, long timeout) throws IOException {
assert Thread.holdsLock(blockingLock()) && !isBlocking();
synchronized (readLock) {
readLock.lock();
try {
int n = 0;
try {
begin();
@ -957,6 +997,8 @@ class SocketChannelImpl
end(n > 0);
}
return n;
} finally {
readLock.unlock();
}
}
@ -1024,8 +1066,7 @@ class SocketChannelImpl
// -- Native methods --
private static native int checkConnect(FileDescriptor fd,
boolean block, boolean ready)
private static native int checkConnect(FileDescriptor fd, boolean block)
throws IOException;
private static native int sendOutOfBandData(FileDescriptor fd, byte data)

View file

@ -236,10 +236,8 @@ public class DoubleByte {
int b2 = src[sp++] & 0xff;
if (b2 < b2Min || b2 > b2Max ||
(c = b2c[b1][b2 - b2Min]) == UNMAPPABLE_DECODING) {
if (b2c[b1] == B2C_UNMAPPABLE || // isNotLeadingByte
b2c[b2] != B2C_UNMAPPABLE || // isLeadingByte
decodeSingle(b2) != UNMAPPABLE_DECODING) {
sp--;
if (crMalformedOrUnmappable(b1, b2).length() == 1) {
sp--;
}
}
}
@ -472,6 +470,13 @@ public class DoubleByte {
b2cSB_UNMAPPABLE = new char[0x100];
Arrays.fill(b2cSB_UNMAPPABLE, UNMAPPABLE_DECODING);
}
// always returns unmappableForLenth(2) for doublebyte_only
@Override
protected CoderResult crMalformedOrUnmappable(int b1, int b2) {
return CoderResult.unmappableForLength(2);
}
public Decoder_DBCSONLY(Charset cs, char[][] b2c, char[] b2cSB, int b2Min, int b2Max,
boolean isASCIICompatible) {
super(cs, 0.5f, 1.0f, b2c, b2cSB_UNMAPPABLE, b2Min, b2Max, isASCIICompatible);

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2018, 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
@ -580,8 +580,8 @@ public class PolicyFile extends java.security.Policy {
k.add(policy);
return k;
});
Object[] source = {policy, pe.getLocalizedMessage()};
System.err.println(LocalizedMessage.getMessage
Object[] source = {policy, pe.getNonlocalizedMessage()};
System.err.println(LocalizedMessage.getNonlocalized
(POLICY + ".error.parsing.policy.message", source));
if (debug != null) {
pe.printStackTrace();
@ -808,14 +808,14 @@ public class PolicyFile extends java.security.Policy {
Object[] source = {pe.permission,
ite.getTargetException().toString()};
System.err.println(
LocalizedMessage.getMessage(
LocalizedMessage.getNonlocalized(
POLICY + ".error.adding.Permission.perm.message",
source));
} catch (Exception e) {
Object[] source = {pe.permission,
e.toString()};
System.err.println(
LocalizedMessage.getMessage(
LocalizedMessage.getNonlocalized(
POLICY + ".error.adding.Permission.perm.message",
source));
}
@ -826,7 +826,7 @@ public class PolicyFile extends java.security.Policy {
} catch (Exception e) {
Object[] source = {e.toString()};
System.err.println(
LocalizedMessage.getMessage(
LocalizedMessage.getNonlocalized(
POLICY + ".error.adding.Entry.message",
source));
}
@ -1803,7 +1803,7 @@ public class PolicyFile extends java.security.Policy {
if (colonIndex == -1) {
Object[] source = {pe.name};
throw new Exception(
LocalizedMessage.getMessage(
LocalizedMessage.getNonlocalized(
"alias.name.not.provided.pe.name.",
source));
}
@ -1811,7 +1811,7 @@ public class PolicyFile extends java.security.Policy {
if ((suffix = getDN(suffix, keystore)) == null) {
Object[] source = {value.substring(colonIndex+1)};
throw new Exception(
LocalizedMessage.getMessage(
LocalizedMessage.getNonlocalized(
"unable.to.perform.substitution.on.alias.suffix",
source));
}
@ -1821,7 +1821,7 @@ public class PolicyFile extends java.security.Policy {
} else {
Object[] source = {prefix};
throw new Exception(
LocalizedMessage.getMessage(
LocalizedMessage.getNonlocalized(
"substitution.value.prefix.unsupported",
source));
}
@ -2037,7 +2037,7 @@ public class PolicyFile extends java.security.Policy {
super(type);
if (type == null) {
throw new NullPointerException
(LocalizedMessage.getMessage("type.can.t.be.null"));
(LocalizedMessage.getNonlocalized("type.can.t.be.null"));
}
this.type = type;
this.name = name;

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2018, 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
@ -205,8 +205,8 @@ public class PolicyParser {
if (!domainEntries.containsKey(domainName)) {
domainEntries.put(domainName, de);
} else {
LocalizedMessage localizedMsg =
new LocalizedMessage("duplicate.keystore.domain.name");
LocalizedMessage localizedMsg = new LocalizedMessage(
"duplicate.keystore.domain.name");
Object[] source = {domainName};
String msg = "duplicate keystore domain name: " +
domainName;
@ -220,7 +220,7 @@ public class PolicyParser {
}
if (keyStoreUrlString == null && storePassURL != null) {
throw new ParsingException(LocalizedMessage.getMessage
throw new ParsingException(LocalizedMessage.getNonlocalized
("keystorePasswordURL.can.not.be.specified.without.also.specifying.keystore"));
}
}
@ -362,7 +362,7 @@ public class PolicyParser {
keyStoreType = match("quoted string");
} else {
throw new ParsingException(st.lineno(),
LocalizedMessage.getMessage("expected.keystore.type"));
LocalizedMessage.getNonlocalized("expected.keystore.type"));
}
// parse keystore provider
@ -375,7 +375,7 @@ public class PolicyParser {
keyStoreProvider = match("quoted string");
} else {
throw new ParsingException(st.lineno(),
LocalizedMessage.getMessage("expected.keystore.provider"));
LocalizedMessage.getNonlocalized("expected.keystore.provider"));
}
}
@ -425,7 +425,7 @@ public class PolicyParser {
if (e.codeBase != null)
throw new ParsingException(
st.lineno(),
LocalizedMessage.getMessage
LocalizedMessage.getNonlocalized
("multiple.Codebase.expressions"));
e.codeBase = match("quoted string");
peekAndMatch(",");
@ -433,7 +433,7 @@ public class PolicyParser {
if (e.signedBy != null)
throw new ParsingException(
st.lineno(),
LocalizedMessage.getMessage
LocalizedMessage.getNonlocalized
("multiple.SignedBy.expressions"));
e.signedBy = match("quoted string");
@ -452,7 +452,7 @@ public class PolicyParser {
if (actr <= cctr)
throw new ParsingException(
st.lineno(),
LocalizedMessage.getMessage
LocalizedMessage.getNonlocalized
("SignedBy.has.empty.alias"));
peekAndMatch(",");
@ -495,7 +495,7 @@ public class PolicyParser {
}
throw new ParsingException
(st.lineno(),
LocalizedMessage.getMessage
LocalizedMessage.getNonlocalized
("can.not.specify.Principal.with.a.wildcard.class.without.a.wildcard.name"));
}
}
@ -532,7 +532,7 @@ public class PolicyParser {
} else {
throw new ParsingException(st.lineno(),
LocalizedMessage.getMessage
LocalizedMessage.getNonlocalized
("expected.codeBase.or.SignedBy.or.Principal"));
}
}
@ -556,7 +556,7 @@ public class PolicyParser {
} else {
throw new
ParsingException(st.lineno(),
LocalizedMessage.getMessage
LocalizedMessage.getNonlocalized
("expected.permission.entry"));
}
}
@ -733,7 +733,7 @@ public class PolicyParser {
switch (lookahead) {
case StreamTokenizer.TT_NUMBER:
throw new ParsingException(st.lineno(), expect,
LocalizedMessage.getMessage("number.") +
LocalizedMessage.getNonlocalized("number.") +
String.valueOf(st.nval));
case StreamTokenizer.TT_EOF:
LocalizedMessage localizedMsg = new LocalizedMessage
@ -826,10 +826,10 @@ public class PolicyParser {
switch (lookahead) {
case StreamTokenizer.TT_NUMBER:
throw new ParsingException(st.lineno(), ";",
LocalizedMessage.getMessage("number.") +
LocalizedMessage.getNonlocalized("number.") +
String.valueOf(st.nval));
case StreamTokenizer.TT_EOF:
throw new ParsingException(LocalizedMessage.getMessage
throw new ParsingException(LocalizedMessage.getNonlocalized
("expected.read.end.of.file."));
default:
lookahead = st.nextToken();
@ -987,7 +987,7 @@ public class PolicyParser {
*/
public PrincipalEntry(String principalClass, String principalName) {
if (principalClass == null || principalName == null)
throw new NullPointerException(LocalizedMessage.getMessage
throw new NullPointerException(LocalizedMessage.getNonlocalized
("null.principalClass.or.principalName"));
this.principalClass = principalClass;
this.principalName = principalName;
@ -1339,8 +1339,6 @@ public class PolicyParser {
public ParsingException(int line, String msg) {
super("line " + line + ": " + msg);
// don't call form.format unless getLocalizedMessage is called
// to avoid unnecessary permission checks
localizedMsg = new LocalizedMessage("line.number.msg");
source = new Object[] {line, msg};
}
@ -1348,16 +1346,14 @@ public class PolicyParser {
public ParsingException(int line, String expect, String actual) {
super("line " + line + ": expected [" + expect +
"], found [" + actual + "]");
// don't call form.format unless getLocalizedMessage is called
// to avoid unnecessary permission checks
localizedMsg = new LocalizedMessage
("line.number.expected.expect.found.actual.");
source = new Object[] {line, expect, actual};
}
@Override
public String getLocalizedMessage() {
return i18nMessage != null ? i18nMessage : localizedMsg.format(source);
public String getNonlocalizedMessage() {
return i18nMessage != null ? i18nMessage :
localizedMsg.formatNonlocalized(source);
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2018, 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
@ -523,9 +523,11 @@ public final class Main {
if (c != null) {
command = c;
} else if (collator.compare(flags, "-help") == 0 ||
collator.compare(flags, "-h") == 0 ||
collator.compare(flags, "-?") == 0) {
} else if (collator.compare(flags, "--help") == 0 ||
collator.compare(flags, "-h") == 0 ||
collator.compare(flags, "-?") == 0 ||
// -help: legacy.
collator.compare(flags, "-help") == 0) {
help = true;
} else if (collator.compare(flags, "-conf") == 0) {
i++;
@ -4608,6 +4610,8 @@ public final class Main {
System.err.printf(" %-20s%s\n", c, rb.getString(c.description));
}
System.err.println();
System.err.println(rb.getString(
"Use.keytool.help.for.all.available.commands"));
System.err.println(rb.getString(
"Use.keytool.command.name.help.for.usage.of.command.name"));
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2018, 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
@ -45,12 +45,12 @@ public class Resources extends java.util.ListResourceBundle {
{"option.1.set.twice", "The %s option is specified multiple times. All except the last one will be ignored."},
{"multiple.commands.1.2", "Only one command is allowed: both %1$s and %2$s were specified."},
{"Use.keytool.help.for.all.available.commands",
"Use \"keytool -help\" for all available commands"},
"Use \"keytool -?, -h, or --help\" for this help message"},
{"Key.and.Certificate.Management.Tool",
"Key and Certificate Management Tool"},
{"Commands.", "Commands:"},
{"Use.keytool.command.name.help.for.usage.of.command.name",
"Use \"keytool -command_name -help\" for usage of command_name.\n" +
"Use \"keytool -command_name --help\" for usage of command_name.\n" +
"Use the -conf <url> option to specify a pre-configured options file."},
// keytool: help: commands
{"Generates.a.certificate.request",
@ -462,7 +462,7 @@ public class Resources extends java.util.ListResourceBundle {
{"with.weak", "%s (weak)"},
{"key.bit", "%1$d-bit %2$s key"},
{"key.bit.weak", "%1$d-bit %2$s key (weak)"},
{"unknown.size.1", "unknown size %s key"},
{"unknown.size.1", "%s key of unknown size"},
{".PATTERN.printX509Cert.with.weak",
"Owner: {0}\nIssuer: {1}\nSerial number: {2}\nValid from: {3} until: {4}\nCertificate fingerprints:\n\t SHA1: {5}\n\t SHA256: {6}\nSignature algorithm name: {7}\nSubject Public Key Algorithm: {8}\nVersion: {9}"},
{"PKCS.10.with.weak",

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2018, 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,7 +42,7 @@ package sun.security.util;
public class LocalizedMessage {
private static final Resources resources = new Resources();
private static final Resources RESOURCES = new Resources();
private final String key;
@ -59,16 +59,28 @@ public class LocalizedMessage {
/**
* Return a localized string corresponding to the key stored in this
* object, formatted with the provided arguments. When the VM is booted,
* this method will obtain the correct localized message and format it
* using java.text.MessageFormat. Otherwise, a non-localized string is
* returned, and the formatting is performed by simplified formatting code.
* object, formatted with the provided arguments. This method should only
* be called when the VM is booted and all resources needed to obtain
* and format the localized message are loaded (or can be loaded).
*
* @param arguments The arguments that should be placed in the message
* @return A formatted message string
*/
public String format(Object... arguments) {
return getMessage(key, arguments);
public String formatLocalized(Object... arguments) {
return getLocalized(key, arguments);
}
/**
* Return a non-localized string corresponding to the key stored in this
* object, formatted with the provided arguments. All strings are obtained
* from sun.security.util.Resources, and the formatting only supports
* simple positional argument replacement (e.g. {1}).
*
* @param arguments The arguments that should be placed in the message
* @return A formatted message string
*/
public String formatNonlocalized(Object... arguments) {
return getNonlocalized(key, arguments);
}
/**
@ -81,10 +93,10 @@ public class LocalizedMessage {
* @param arguments The arguments that should be placed in the message
* @return A formatted message string
*/
public static String getMessageUnbooted(String key,
Object... arguments) {
public static String getNonlocalized(String key,
Object... arguments) {
String value = resources.getString(key);
String value = RESOURCES.getString(key);
if (arguments == null || arguments.length == 0) {
return value;
}
@ -110,8 +122,7 @@ public class LocalizedMessage {
try {
int index = Integer.parseInt(indexStr);
sb.append(arguments[index]);
}
catch(NumberFormatException e) {
} catch (NumberFormatException e) {
// argument index is not an integer
throw new RuntimeException("not an integer: " + indexStr);
}
@ -123,29 +134,22 @@ public class LocalizedMessage {
/**
* Return a localized string corresponding to the provided key, and
* formatted with the provided arguments. When the VM is booted, this
* method will obtain the correct localized message and format it using
* java.text.MessageFormat. Otherwise, a non-localized string is returned,
* and the formatting is performed by simplified formatting code.
* formatted with the provided arguments. This method should only be
* called when the VM is booted and all resources needed to obtain
* and format the localized message are loaded (or can be loaded).
*
* @param key The key of the desired string in the security resource bundle
* @param arguments The arguments that should be placed in the message
* @return A formatted message string
*/
public static String getMessage(String key,
Object... arguments) {
public static String getLocalized(String key, Object... arguments) {
if (jdk.internal.misc.VM.isBooted()) {
// Localization and formatting resources are available
String value = ResourcesMgr.getString(key);
if (arguments == null) {
return value;
}
java.text.MessageFormat form = new java.text.MessageFormat(value);
return form.format(arguments);
} else {
return getMessageUnbooted(key, arguments);
String value = ResourcesMgr.getString(key);
if (arguments == null) {
return value;
}
java.text.MessageFormat form = new java.text.MessageFormat(value);
return form.format(arguments);
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2010, 2018, 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
@ -31,8 +31,8 @@
*/
package sun.util.locale;
import java.lang.ref.SoftReference;
import java.lang.ref.SoftReference;
import java.util.StringJoiner;
public final class BaseLocale {
@ -48,26 +48,28 @@ public final class BaseLocale {
private volatile int hash;
// This method must be called only when creating the Locale.* constants.
private BaseLocale(String language, String region) {
this.language = language;
this.script = "";
this.region = region;
this.variant = "";
}
private BaseLocale(String language, String script, String region, String variant) {
this.language = (language != null) ? LocaleUtils.toLowerString(language).intern() : "";
this.script = (script != null) ? LocaleUtils.toTitleString(script).intern() : "";
this.region = (region != null) ? LocaleUtils.toUpperString(region).intern() : "";
this.variant = (variant != null) ? variant.intern() : "";
// This method must be called with normalize = false only when creating the
// Locale.* constants and non-normalized BaseLocale$Keys used for lookup.
private BaseLocale(String language, String script, String region, String variant,
boolean normalize) {
if (normalize) {
this.language = LocaleUtils.toLowerString(language).intern();
this.script = LocaleUtils.toTitleString(script).intern();
this.region = LocaleUtils.toUpperString(region).intern();
this.variant = variant.intern();
} else {
this.language = language;
this.script = script;
this.region = region;
this.variant = variant;
}
}
// Called for creating the Locale.* constants. No argument
// validation is performed.
public static BaseLocale createInstance(String language, String region) {
BaseLocale base = new BaseLocale(language, region);
CACHE.put(new Key(language, region), base);
BaseLocale base = new BaseLocale(language, "", region, "", false);
CACHE.put(new Key(base), base);
return base;
}
@ -84,7 +86,7 @@ public final class BaseLocale {
}
}
Key key = new Key(language, script, region, variant);
Key key = new Key(language, script, region, variant, false);
BaseLocale baseLocale = CACHE.get(key);
return baseLocale;
}
@ -123,16 +125,16 @@ public final class BaseLocale {
@Override
public String toString() {
StringJoiner sj = new StringJoiner(", ");
if (language.length() > 0) {
if (!language.isEmpty()) {
sj.add("language=" + language);
}
if (script.length() > 0) {
if (!script.isEmpty()) {
sj.add("script=" + script);
}
if (region.length() > 0) {
if (!region.isEmpty()) {
sj.add("region=" + region);
}
if (variant.length() > 0) {
if (!variant.isEmpty()) {
sj.add("variant=" + variant);
}
return sj.toString();
@ -155,10 +157,17 @@ public final class BaseLocale {
}
private static final class Key {
private final SoftReference<String> lang;
private final SoftReference<String> scrt;
private final SoftReference<String> regn;
private final SoftReference<String> vart;
/**
* Keep a SoftReference to the Key data if normalized (actually used
* as a cache key) and not initialized via the constant creation path.
*
* This allows us to avoid creating SoftReferences on lookup Keys
* (which are short-lived) and for Locales created via
* Locale#createConstant.
*/
private final SoftReference<BaseLocale> holderRef;
private final BaseLocale holder;
private final boolean normalized;
private final int hash;
@ -166,15 +175,16 @@ public final class BaseLocale {
* Creates a Key. language and region must be normalized
* (intern'ed in the proper case).
*/
private Key(String language, String region) {
assert language.intern() == language
&& region.intern() == region;
lang = new SoftReference<>(language);
scrt = new SoftReference<>("");
regn = new SoftReference<>(region);
vart = new SoftReference<>("");
private Key(BaseLocale locale) {
this.holder = locale;
this.holderRef = null;
this.normalized = true;
String language = locale.getLanguage();
String region = locale.getRegion();
assert LocaleUtils.toLowerString(language).intern() == language
&& LocaleUtils.toUpperString(region).intern() == region
&& locale.getVariant() == ""
&& locale.getScript() == "";
int h = language.hashCode();
if (region != "") {
@ -186,51 +196,64 @@ public final class BaseLocale {
hash = h;
}
public Key(String language, String script, String region, String variant) {
this(language, script, region, variant, false);
private Key(String language, String script, String region,
String variant, boolean normalize) {
if (language == null) {
language = "";
}
if (script == null) {
script = "";
}
if (region == null) {
region = "";
}
if (variant == null) {
variant = "";
}
BaseLocale locale = new BaseLocale(language, script, region, variant, normalize);
this.normalized = normalize;
if (normalized) {
this.holderRef = new SoftReference<>(locale);
this.holder = null;
} else {
this.holderRef = null;
this.holder = locale;
}
this.hash = hashCode(locale);
}
private Key(String language, String script, String region,
String variant, boolean normalized) {
public int hashCode() {
return hash;
}
private int hashCode(BaseLocale locale) {
int h = 0;
if (language != null) {
lang = new SoftReference<>(language);
int len = language.length();
for (int i = 0; i < len; i++) {
h = 31*h + LocaleUtils.toLower(language.charAt(i));
}
} else {
lang = new SoftReference<>("");
String lang = locale.getLanguage();
int len = lang.length();
for (int i = 0; i < len; i++) {
h = 31*h + LocaleUtils.toLower(lang.charAt(i));
}
if (script != null) {
scrt = new SoftReference<>(script);
int len = script.length();
for (int i = 0; i < len; i++) {
h = 31*h + LocaleUtils.toLower(script.charAt(i));
}
} else {
scrt = new SoftReference<>("");
String scrt = locale.getScript();
len = scrt.length();
for (int i = 0; i < len; i++) {
h = 31*h + LocaleUtils.toLower(scrt.charAt(i));
}
if (region != null) {
regn = new SoftReference<>(region);
int len = region.length();
for (int i = 0; i < len; i++) {
h = 31*h + LocaleUtils.toLower(region.charAt(i));
}
} else {
regn = new SoftReference<>("");
String regn = locale.getRegion();
len = regn.length();
for (int i = 0; i < len; i++) {
h = 31*h + LocaleUtils.toLower(regn.charAt(i));
}
if (variant != null) {
vart = new SoftReference<>(variant);
int len = variant.length();
for (int i = 0; i < len; i++) {
h = 31*h + variant.charAt(i);
}
} else {
vart = new SoftReference<>("");
String vart = locale.getVariant();
len = vart.length();
for (int i = 0; i < len; i++) {
h = 31*h + vart.charAt(i);
}
hash = h;
this.normalized = normalized;
return h;
}
private BaseLocale getBaseLocale() {
return (holder == null) ? holderRef.get() : holder;
}
@Override
@ -238,46 +261,31 @@ public final class BaseLocale {
if (this == obj) {
return true;
}
if (obj instanceof Key && this.hash == ((Key)obj).hash) {
String tl = this.lang.get();
String ol = ((Key)obj).lang.get();
if (tl != null && ol != null &&
LocaleUtils.caseIgnoreMatch(ol, tl)) {
String ts = this.scrt.get();
String os = ((Key)obj).scrt.get();
if (ts != null && os != null &&
LocaleUtils.caseIgnoreMatch(os, ts)) {
String tr = this.regn.get();
String or = ((Key)obj).regn.get();
if (tr != null && or != null &&
LocaleUtils.caseIgnoreMatch(or, tr)) {
String tv = this.vart.get();
String ov = ((Key)obj).vart.get();
return (ov != null && ov.equals(tv));
}
}
BaseLocale other = ((Key) obj).getBaseLocale();
BaseLocale locale = this.getBaseLocale();
if (other != null && locale != null
&& LocaleUtils.caseIgnoreMatch(other.getLanguage(), locale.getLanguage())
&& LocaleUtils.caseIgnoreMatch(other.getScript(), locale.getScript())
&& LocaleUtils.caseIgnoreMatch(other.getRegion(), locale.getRegion())
// variant is case sensitive in JDK!
&& other.getVariant().equals(locale.getVariant())) {
return true;
}
}
return false;
}
@Override
public int hashCode() {
return hash;
}
public static Key normalize(Key key) {
if (key.normalized) {
return key;
}
String lang = LocaleUtils.toLowerString(key.lang.get()).intern();
String scrt = LocaleUtils.toTitleString(key.scrt.get()).intern();
String regn = LocaleUtils.toUpperString(key.regn.get()).intern();
String vart = key.vart.get().intern(); // preserve upper/lower cases
return new Key(lang, scrt, regn, vart, true);
// Only normalized keys may be softly referencing the data holder
assert (key.holder != null && key.holderRef == null);
BaseLocale locale = key.holder;
return new Key(locale.getLanguage(), locale.getScript(),
locale.getRegion(), locale.getVariant(), true);
}
}
@ -288,18 +296,12 @@ public final class BaseLocale {
@Override
protected Key normalizeKey(Key key) {
assert key.lang.get() != null &&
key.scrt.get() != null &&
key.regn.get() != null &&
key.vart.get() != null;
return Key.normalize(key);
}
@Override
protected BaseLocale createObject(Key key) {
return new BaseLocale(key.lang.get(), key.scrt.get(),
key.regn.get(), key.vart.get());
return Key.normalize(key).getBaseLocale();
}
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2010, 2018, 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
@ -37,8 +37,8 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
public abstract class LocaleObjectCache<K, V> {
private ConcurrentMap<K, CacheEntry<K, V>> map;
private ReferenceQueue<V> queue = new ReferenceQueue<>();
private final ConcurrentMap<K, CacheEntry<K, V>> map;
private final ReferenceQueue<V> queue = new ReferenceQueue<>();
public LocaleObjectCache() {
this(16, 0.75f, 16);
@ -57,17 +57,14 @@ public abstract class LocaleObjectCache<K, V> {
value = entry.get();
}
if (value == null) {
V newVal = createObject(key);
// make sure key is normalized *after* the object creation
// so that newVal is assured to be created from a valid key.
key = normalizeKey(key);
V newVal = createObject(key);
if (key == null || newVal == null) {
// subclass must return non-null key/value object
return null;
}
CacheEntry<K, V> newEntry = new CacheEntry<>(key, newVal, queue);
entry = map.putIfAbsent(key, newEntry);
if (entry == null) {
value = newVal;
@ -92,7 +89,7 @@ public abstract class LocaleObjectCache<K, V> {
private void cleanStaleEntries() {
CacheEntry<K, V> entry;
while ((entry = (CacheEntry<K, V>)queue.poll()) != null) {
map.remove(entry.getKey());
map.remove(entry.getKey(), entry);
}
}

View file

@ -812,14 +812,14 @@ jdk.tls.legacyAlgorithms= \
# limited: These policy files contain more restricted cryptographic
# strengths
#
# The default setting is determined by the value of the “crypto.policy”
# The default setting is determined by the value of the "crypto.policy"
# Security property below. If your country or usage requires the
# traditional restrictive policy, the “limited” Java cryptographic
# traditional restrictive policy, the "limited" Java cryptographic
# policy is still available and may be appropriate for your environment.
#
# If you have restrictions that do not fit either use case mentioned
# above, Java provides the capability to customize these policy files.
# The “crypto.policy” security property points to a subdirectory
# The "crypto.policy" security property points to a subdirectory
# within <java-home>/conf/security/policy/ which can be customized.
# Please see the <java-home>/conf/security/policy/README.txt file or consult
# the Java Security Guide/JCA documentation for more information.

View file

@ -8,7 +8,7 @@
Import and export control rules on cryptographic software vary from
country to country. The Java Cryptography Extension (JCE) architecture
allows flexible cryptographic key strength to be configured via the
jurisdiction policy files which are referenced by the “crypto.policy”
jurisdiction policy files which are referenced by the "crypto.policy"
security property in the <java-home>/conf/security/java.security file.
By default, Java provides two different sets of cryptographic policy
@ -20,8 +20,8 @@ files:
limited: These policy files contain more restricted cryptographic
strengths
These files reside in <java-home>/conf/security/policy in the “unlimited”
or “limited” subdirectories respectively.
These files reside in <java-home>/conf/security/policy in the "unlimited"
or "limited" subdirectories respectively.
Each subdirectory contains a complete policy configuration,
and subdirectories can be added/edited/removed to reflect your

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2004, 2017, 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
@ -31,8 +31,8 @@ extern "C" {
#endif
/* Classfile version number for this information */
#define JVM_CLASSFILE_MAJOR_VERSION 54
#define JVM_CLASSFILE_MINOR_VERSION 0
#define JVM_CLASSFILE_MAJOR_VERSION @@VERSION_CLASSFILE_MAJOR@@
#define JVM_CLASSFILE_MINOR_VERSION @@VERSION_CLASSFILE_MINOR@@
/* Flags */

View file

@ -30,13 +30,7 @@
JNIEXPORT jclass JNICALL
Java_jdk_internal_reflect_Reflection_getCallerClass__(JNIEnv *env, jclass unused)
{
return JVM_GetCallerClass(env, JVM_CALLER_DEPTH);
}
JNIEXPORT jclass JNICALL
Java_jdk_internal_reflect_Reflection_getCallerClass__I(JNIEnv *env, jclass unused, jint depth)
{
return JVM_GetCallerClass(env, depth);
return JVM_GetCallerClass(env);
}
JNIEXPORT jint JNICALL

View file

@ -119,9 +119,6 @@ Java_java_lang_System_identityHashCode(JNIEnv *env, jobject this, jobject x)
#define VENDOR_URL_BUG "http://bugreport.java.com/bugreport/"
#endif
#define JAVA_MAX_SUPPORTED_VERSION 54
#define JAVA_MAX_SUPPORTED_MINOR_VERSION 0
#ifdef JAVA_SPECIFICATION_VENDOR /* Third party may NOT overwrite this. */
#error "ERROR: No override of JAVA_SPECIFICATION_VENDOR is allowed"
#else
@ -227,8 +224,8 @@ Java_java_lang_System_initProperties(JNIEnv *env, jclass cla, jobject props)
PUTPROP(props, "java.vendor.url", VENDOR_URL);
PUTPROP(props, "java.vendor.url.bug", VENDOR_URL_BUG);
jio_snprintf(buf, sizeof(buf), "%d.%d", JAVA_MAX_SUPPORTED_VERSION,
JAVA_MAX_SUPPORTED_MINOR_VERSION);
jio_snprintf(buf, sizeof(buf), "%d.%d", JVM_CLASSFILE_MAJOR_VERSION,
JVM_CLASSFILE_MINOR_VERSION);
PUTPROP(props, "java.class.version", buf);
if (sprops->awt_toolkit) {

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1995, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1995, 2018, 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
@ -91,6 +91,14 @@ public final class FileDescriptor {
fdo.registerCleanup();
}
public void registerCleanup(FileDescriptor fdo, PhantomCleanable<Object> cleanup) {
fdo.registerCleanup(cleanup);
}
public void unregisterCleanup(FileDescriptor fdo) {
fdo.unregisterCleanup();
}
public void setHandle(FileDescriptor fdo, long handle) {
throw new UnsupportedOperationException();
}
@ -105,7 +113,7 @@ public final class FileDescriptor {
/**
* Cleanup in case FileDescriptor is not explicitly closed.
*/
private FDCleanup cleanup;
private PhantomCleanable<Object> cleanup;
/**
* Constructs an (invalid) FileDescriptor
@ -206,16 +214,44 @@ public final class FileDescriptor {
}
/**
* Register a cleanup for the current raw fd.
* Register a cleanup for the current handle.
* Used directly in java.io and indirectly via fdAccess.
* The cleanup should be registered after the fd is set in the FileDescriptor.
* The cleanup should be registered after the handle is set in the FileDescriptor.
*/
@SuppressWarnings("unchecked")
synchronized void registerCleanup() {
void registerCleanup() {
registerCleanup(null);
}
/**
* Register a cleanup for the current handle.
* Used directly in java.io and indirectly via fdAccess.
* The cleanup should be registered after the handle is set in the FileDescriptor.
* @param newCleanable a PhantomCleanable to register
*/
@SuppressWarnings("unchecked")
synchronized void registerCleanup(PhantomCleanable<Object> newCleanable) {
if (cleanup != null) {
cleanup.clear();
}
cleanup = FDCleanup.create(this);
cleanup = (newCleanable == null) ? FDCleanup.create(this) : newCleanable;
}
/**
* Unregister a cleanup for the current raw fd.
* Used directly in java.io and indirectly via fdAccess.
* Normally {@link #close()} should be used except in cases where
* it is certain the caller will close the raw fd and the cleanup
* must not close the raw fd. {@link #unregisterCleanup()} must be
* called before the raw fd is closed to prevent a race that makes
* it possible for the fd to be reallocated to another use and later
* the cleanup might be invoked.
*/
synchronized void unregisterCleanup() {
if (cleanup != null) {
cleanup.clear();
}
cleanup = null;
}
/**

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2018, 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
@ -25,10 +25,14 @@
package sun.nio.ch;
import java.io.*;
import java.io.FileDescriptor;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.nio.channels.spi.*;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.Pipe;
import java.nio.channels.SelectionKey;
import java.nio.channels.spi.SelectorProvider;
import java.util.concurrent.locks.ReentrantLock;
class SinkChannelImpl
@ -40,17 +44,17 @@ class SinkChannelImpl
private static final NativeDispatcher nd = new FileDispatcherImpl();
// The file descriptor associated with this channel
FileDescriptor fd;
private final FileDescriptor fd;
// fd value needed for dev/poll. This value will remain valid
// even after the value in the file descriptor object has been set to -1
int fdVal;
private final int fdVal;
// ID of native thread doing write, for signalling
private volatile long thread;
// Lock held by current reading thread
private final Object lock = new Object();
// Lock held by current writing thread
private final ReentrantLock writeLock = new ReentrantLock();
// Lock held by any thread that modifies the state fields declared below
// DO NOT invoke a blocking I/O operation while holding this lock!
@ -155,8 +159,9 @@ class SinkChannelImpl
}
public int write(ByteBuffer src) throws IOException {
ensureOpen();
synchronized (lock) {
writeLock.lock();
try {
ensureOpen();
int n = 0;
try {
begin();
@ -172,14 +177,18 @@ class SinkChannelImpl
end((n > 0) || (n == IOStatus.UNAVAILABLE));
assert IOStatus.check(n);
}
} finally {
writeLock.unlock();
}
}
public long write(ByteBuffer[] srcs) throws IOException {
if (srcs == null)
throw new NullPointerException();
ensureOpen();
synchronized (lock) {
writeLock.lock();
try {
ensureOpen();
long n = 0;
try {
begin();
@ -195,6 +204,8 @@ class SinkChannelImpl
end((n > 0) || (n == IOStatus.UNAVAILABLE));
assert IOStatus.check(n);
}
} finally {
writeLock.unlock();
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2018, 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
@ -25,10 +25,14 @@
package sun.nio.ch;
import java.io.*;
import java.io.FileDescriptor;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.nio.channels.spi.*;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.Pipe;
import java.nio.channels.SelectionKey;
import java.nio.channels.spi.SelectorProvider;
import java.util.concurrent.locks.ReentrantLock;
class SourceChannelImpl
@ -40,17 +44,17 @@ class SourceChannelImpl
private static final NativeDispatcher nd = new FileDispatcherImpl();
// The file descriptor associated with this channel
FileDescriptor fd;
private final FileDescriptor fd;
// fd value needed for dev/poll. This value will remain valid
// even after the value in the file descriptor object has been set to -1
int fdVal;
private final int fdVal;
// ID of native thread doing read, for signalling
private volatile long thread;
// Lock held by current reading thread
private final Object lock = new Object();
private final ReentrantLock readLock = new ReentrantLock();
// Lock held by any thread that modifies the state fields declared below
// DO NOT invoke a blocking I/O operation while holding this lock!
@ -155,8 +159,10 @@ class SourceChannelImpl
}
public int read(ByteBuffer dst) throws IOException {
ensureOpen();
synchronized (lock) {
readLock.lock();
try {
ensureOpen();
int n = 0;
try {
begin();
@ -172,6 +178,8 @@ class SourceChannelImpl
end((n > 0) || (n == IOStatus.UNAVAILABLE));
assert IOStatus.check(n);
}
} finally {
readLock.unlock();
}
}
@ -186,8 +194,10 @@ class SourceChannelImpl
public long read(ByteBuffer[] dsts) throws IOException {
if (dsts == null)
throw new NullPointerException();
ensureOpen();
synchronized (lock) {
readLock.lock();
try {
ensureOpen();
long n = 0;
try {
begin();
@ -203,6 +213,8 @@ class SourceChannelImpl
end((n > 0) || (n == IOStatus.UNAVAILABLE));
assert IOStatus.check(n);
}
} finally {
readLock.unlock();
}
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2018, 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
@ -27,6 +27,7 @@
#include <string.h>
#include "net_util.h"
#include "java_net_SocketCleanable.h"
JNIEXPORT jboolean JNICALL
Java_java_net_AbstractPlainSocketImpl_isReusePortAvailable0(JNIEnv* env, jclass c1)
@ -45,3 +46,15 @@ Java_jdk_net_Sockets_isReusePortAvailable0(JNIEnv* env, jclass c1)
{
return (reuseport_available()) ? JNI_TRUE : JNI_FALSE;
}
/*
* Class: java_net_SocketCleanable
* Method: cleanupClose0
* Signature: (I)V
*/
JNIEXPORT void JNICALL
Java_java_net_SocketCleanable_cleanupClose0(JNIEnv *env, jclass c1, jint fd)
{
NET_SocketClose(fd);
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2018, 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
@ -47,8 +47,7 @@
JNIEXPORT jint JNICALL
Java_sun_nio_ch_SocketChannelImpl_checkConnect(JNIEnv *env, jobject this,
jobject fdo, jboolean block,
jboolean ready)
jobject fdo, jboolean block)
{
int error = 0;
socklen_t n = sizeof(int);
@ -56,19 +55,16 @@ Java_sun_nio_ch_SocketChannelImpl_checkConnect(JNIEnv *env, jobject this,
int result = 0;
struct pollfd poller;
poller.revents = 1;
if (!ready) {
poller.fd = fd;
poller.events = POLLOUT;
poller.revents = 0;
result = poll(&poller, 1, block ? -1 : 0);
if (result < 0) {
JNU_ThrowIOExceptionWithLastError(env, "Poll failed");
return IOS_THROWN;
}
if (!block && (result == 0))
return IOS_UNAVAILABLE;
poller.fd = fd;
poller.events = POLLOUT;
poller.revents = 0;
result = poll(&poller, 1, block ? -1 : 0);
if (result < 0) {
JNU_ThrowIOExceptionWithLastError(env, "Poll failed");
return IOS_THROWN;
}
if (!block && (result == 0))
return IOS_UNAVAILABLE;
if (poller.revents) {
errno = 0;

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2018, 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
@ -90,7 +90,15 @@ public final class FileDescriptor {
}
public void registerCleanup(FileDescriptor fdo) {
fdo.registerCleanup();
fdo.registerCleanup(null);
}
public void registerCleanup(FileDescriptor fdo, PhantomCleanable<Object> cleanup) {
fdo.registerCleanup(cleanup);
}
public void unregisterCleanup(FileDescriptor fdo) {
fdo.unregisterCleanup();
}
public void setHandle(FileDescriptor fdo, long handle) {
@ -107,7 +115,7 @@ public final class FileDescriptor {
/**
* Cleanup in case FileDescriptor is not explicitly closed.
*/
private FDCleanup cleanup;
private PhantomCleanable<Object> cleanup;
/**
* Constructs an (invalid) FileDescriptor
@ -217,11 +225,39 @@ public final class FileDescriptor {
* The cleanup should be registered after the handle is set in the FileDescriptor.
*/
@SuppressWarnings("unchecked")
synchronized void registerCleanup() {
void registerCleanup() {
registerCleanup(null);
}
/**
* Register a cleanup for the current handle.
* Used directly in java.io and indirectly via fdAccess.
* The cleanup should be registered after the handle is set in the FileDescriptor.
* @param newCleanable a PhantomCleanable to register
*/
@SuppressWarnings("unchecked")
synchronized void registerCleanup(PhantomCleanable<Object> newCleanable) {
if (cleanup != null) {
cleanup.clear();
}
cleanup = FDCleanup.create(this);
cleanup = (newCleanable == null) ? FDCleanup.create(this) : newCleanable;
}
/**
* Unregister a cleanup for the current raw fd.
* Used directly in java.io and indirectly via fdAccess.
* Normally {@link #close()} should be used except in cases where
* it is certain the caller will close the raw fd and the cleanup
* must not close the raw fd. {@link #unregisterCleanup()} must be
* called before the raw fd is closed to prevent a race that makes
* it possible for the fd to be reallocated to another use and later
* the cleanup might be invoked.
*/
synchronized void unregisterCleanup() {
if (cleanup != null) {
cleanup.clear();
}
cleanup = null;
}
/**
@ -319,16 +355,21 @@ public final class FileDescriptor {
/**
* Cleanup for a FileDescriptor when it becomes phantom reachable.
* Create a cleanup if handle != -1.
* Windows closes files using handles and sockets via the fd.
* Network FileDescriptors using socket fd must provide their
* own PhantomCleanable to {@link #registerCleanup}.
* This implementation only clears thehandles.
* <p>
* Subclassed from {@code PhantomCleanable} so that {@code clear} can be
* called to disable the cleanup when the fd is closed by any means other
* called to disable the cleanup when the handle is closed by any means other
* than calling {@link FileDescriptor#close}.
* Otherwise, it may close the handle after it has been reused.
* Otherwise, it may incorrectly close the handle after it has been reused.
*/
static final class FDCleanup extends PhantomCleanable<Object> {
private final long handle;
static FDCleanup create(FileDescriptor fdo) {
return fdo.handle == -1
return fdo.handle == -1L
? null
: new FDCleanup(fdo, CleanerFactory.cleaner(), fdo.handle);
}

View file

@ -86,6 +86,7 @@ class TwoStacksPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl
fd1 = new FileDescriptor();
try {
super.create();
SocketCleanable.register(fd1);
} catch (SocketException e) {
fd1 = null;
throw e;
@ -160,6 +161,8 @@ class TwoStacksPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl
protected void close() {
if (fd != null || fd1 != null) {
SocketCleanable.unregister(fd);
SocketCleanable.unregister(fd1);
datagramSocketClose();
ResourceManager.afterUdpClose();
fd = null;

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002, 2006, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2018, 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
@ -44,7 +44,7 @@ class SinkChannelImpl
implements SelChImpl
{
// The SocketChannel assoicated with this pipe
SocketChannel sc;
final SocketChannel sc;
public FileDescriptor getFD() {
return ((SocketChannelImpl)sc).getFD();

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002, 2006, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2018, 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
@ -43,7 +43,7 @@ class SourceChannelImpl
implements SelChImpl
{
// The SocketChannel assoicated with this pipe
SocketChannel sc;
private final SocketChannel sc;
public FileDescriptor getFD() {
return ((SocketChannelImpl) sc).getFD();

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2018, 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
@ -24,6 +24,8 @@
*/
#include <jni.h>
#include "net_util.h"
#include "java_net_SocketCleanable.h"
JNIEXPORT jboolean JNICALL
Java_java_net_AbstractPlainSocketImpl_isReusePortAvailable0(JNIEnv* env, jclass c1)
@ -45,3 +47,15 @@ Java_jdk_net_Sockets_isReusePortAvailable0(JNIEnv* env, jclass c1)
// SO_REUSEPORT is not supported on Windows
return JNI_FALSE;
}
/*
* Class: java_net_SocketCleanable
* Method: cleanupClose0
* Signature: (I)V
*/
JNIEXPORT void JNICALL
Java_java_net_SocketCleanable_cleanupClose0(JNIEnv *env, jclass c1, jint fd)
{
NET_SocketClose(fd);
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2018, 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
@ -525,7 +525,7 @@ NET_SocketClose(int fd) {
int len = sizeof (l);
if (getsockopt(fd, SOL_SOCKET, SO_LINGER, (char *)&l, &len) == 0) {
if (l.l_onoff == 0) {
WSASendDisconnect(fd, NULL);
shutdown(fd, SD_SEND);
}
}
ret = closesocket (fd);

Some files were not shown because too many files have changed in this diff Show more