Mercurial > hg > release > icedtea7-2.1
changeset 1569:3f4c11b93ded
More NIO build fixes.
2009-01-13 Andrew John Hughes <gnu_andrew@member.fsf.org>
* overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/net/StandardProtocolFamily.java,
* overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/net/StandardSocketOption.java:
Added missing files.
* overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/channels/AsynchronousFileChannel.java,
* overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/channels/AsynchronousServerSocketChannel.java,
* overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/channels/AsynchronousSocketChannel.java,
* overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/channels/FileChannel.java,
* overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/channels/FileLock.java,
* overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/channels/MulticastChannel.java,
* overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/FileTreeWalker.java,
* overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/FileVisitor.java,
* overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/Files.java,
* overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/Path.java,
* overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/Paths.java,
* overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/SecureDirectoryStream.java,
* overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/SimpleFileVisitor.java,
* overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/attribute/AclFileAttributeView.java,
* overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/attribute/Attributes.java,
* overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/attribute/FileStoreSpaceAttributeView.java,
* overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/attribute/PosixFileAttributeView.java,
* overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/attribute/PosixFilePermissions.java,
* overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/spi/AbstractPath.java,
* overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/spi/FileSystemProvider.java,
* overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/spi/FileTypeDetector.java:
Fixed imports.
* overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/util/concurrent/ScheduledThreadPoolExecutor.java:
Added.
* overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/misc/JavaUtilConcurrentThreadPoolExecutorAccess.java:
Added to allow access to private members of java.util.concurrent.ThreadPoolExecutor.
* overlays/nio2/openjdk/jdk/src/share/classes/sun/nio/ch/AbstractFuture.java,
* overlays/nio2/openjdk/jdk/src/solaris/classes/sun/nio/ch/DefaultAsynchronousChannelProvider.java,
* overlays/nio2/openjdk/jdk/src/solaris/classes/sun/nio/fs/DefaultFileSystemProvider.java,
* overlays/nio2/openjdk/jdk/src/solaris/classes/sun/nio/fs/DefaultFileTypeDetector.java,
* overlays/nio2/openjdk/jdk/src/solaris/classes/sun/nio/fs/UnixFileSystem.java:
Fix imports.
* patches/icedtea-nio2.patch:
Patch ThreadPoolExecutor to allow access to private variables, add missing files to
nio/FILES_java.gmk
line wrap: on
line diff
--- a/ChangeLog Tue Jan 13 16:38:40 2009 +0000 +++ b/ChangeLog Wed Jan 14 05:27:57 2009 +0000 @@ -1,3 +1,44 @@ +2009-01-13 Andrew John Hughes <gnu_andrew@member.fsf.org> + + * overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/net/StandardProtocolFamily.java, + * overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/net/StandardSocketOption.java: + Added missing files. + * overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/channels/AsynchronousFileChannel.java, + * overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/channels/AsynchronousServerSocketChannel.java, + * overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/channels/AsynchronousSocketChannel.java, + * overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/channels/FileChannel.java, + * overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/channels/FileLock.java, + * overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/channels/MulticastChannel.java, + * overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/FileTreeWalker.java, + * overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/FileVisitor.java, + * overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/Files.java, + * overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/Path.java, + * overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/Paths.java, + * overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/SecureDirectoryStream.java, + * overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/SimpleFileVisitor.java, + * overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/attribute/AclFileAttributeView.java, + * overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/attribute/Attributes.java, + * overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/attribute/FileStoreSpaceAttributeView.java, + * overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/attribute/PosixFileAttributeView.java, + * overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/attribute/PosixFilePermissions.java, + * overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/spi/AbstractPath.java, + * overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/spi/FileSystemProvider.java, + * overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/spi/FileTypeDetector.java: + Fixed imports. + * overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/util/concurrent/ScheduledThreadPoolExecutor.java: + Added. + * overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/misc/JavaUtilConcurrentThreadPoolExecutorAccess.java: + Added to allow access to private members of java.util.concurrent.ThreadPoolExecutor. + * overlays/nio2/openjdk/jdk/src/share/classes/sun/nio/ch/AbstractFuture.java, + * overlays/nio2/openjdk/jdk/src/solaris/classes/sun/nio/ch/DefaultAsynchronousChannelProvider.java, + * overlays/nio2/openjdk/jdk/src/solaris/classes/sun/nio/fs/DefaultFileSystemProvider.java, + * overlays/nio2/openjdk/jdk/src/solaris/classes/sun/nio/fs/DefaultFileTypeDetector.java, + * overlays/nio2/openjdk/jdk/src/solaris/classes/sun/nio/fs/UnixFileSystem.java: + Fix imports. + * patches/icedtea-nio2.patch: + Patch ThreadPoolExecutor to allow access to private variables, add missing files to + nio/FILES_java.gmk + 2009-01-12 Andrew John Hughes <gnu_andrew@member.fsf.org> * overlays/nio2/openjdk/jdk/src/share/classes/com/sun/nio/file/ExtendedCopyOption.java,
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/net/StandardProtocolFamily.java Wed Jan 14 05:27:57 2009 +0000 @@ -0,0 +1,46 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 Red Hat, Inc. + * 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package org.classpath.icedtea.java.net; + +/** + * Defines the standard families of communication protocols. + * + * @since 1.7 + */ + +public enum StandardProtocolFamily implements ProtocolFamily { + + /** + * Internet Protocol Version 4 (IPv4) + */ + INET, + + /** + * Internet Protocol Version 6 (IPv6) + */ + INET6 +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/net/StandardSocketOption.java Wed Jan 14 05:27:57 2009 +0000 @@ -0,0 +1,370 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 Red Hat, Inc. + * 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package org.classpath.icedtea.java.net; + +import java.net.NetworkInterface; + +/** + * Defines the <em>standard</em> socket options. + * + * <p> The {@link SocketOption#name name} of each socket option defined by this + * class is its field name. + * + * <p> In this release, the socket options defined here are used by {@link + * java.nio.channels.NetworkChannel network} channels in the {@link + * java.nio.channels channels} package. + * + * @since 1.7 + */ + +public final class StandardSocketOption { + private StandardSocketOption() { } + + // -- SOL_SOCKET -- + + /** + * Allow transmission of broadcast datagrams. + * + * <p> The value of this socket option is a {@code Boolean} that represents + * whether the option is enabled or disabled. The option is specific to + * datagram-oriented sockets sending to {@link java.net.Inet4Address IPv4} + * broadcast addresses. When the socket option is enabled then the socket + * can be used to send <em>broadcast datagrams</em>. + * + * <p> The initial value of this socket option is {@code FALSE}. The socket + * option may be enabled or disabled at any time. Some operating systems may + * require that the Java virtual machine be started with implementation + * specific privileges to enable this option or send broadcast datagrams. + * + * @see <a href="http://www.ietf.org/rfc/rfc919.txt">RFC 929: + * Broadcasting Internet Datagrams</a> + * @see DatagramSocket#setBroadcast + */ + public static final SocketOption<Boolean> SO_BROADCAST = + new StdSocketOption<Boolean>("SO_BROADCAST", Boolean.class); + + /** + * Keep connection alive. + * + * <p> The value of this socket option is a {@code Boolean} that represents + * whether the option is enabled or disabled. When the {@code SO_KEEPALIVE} + * option is enabled the operating system may use a <em>keep-alive</em> + * mechanism to periodically probe the other end of a connection when the + * connection is otherwise idle. The exact semantics of the keep alive + * mechanism is system dependent and therefore unspecified. + * + * <p> The initial value of this socket option is {@code FALSE}. The socket + * option may be enabled or disabled at any time. + * + * @see <a href="http://www.ietf.org/rfc/rfc1122.txt">RFC 1122 + * Requirements for Internet Hosts -- Communication Layers</a> + * @see Socket#setKeepAlive + */ + public static final SocketOption<Boolean> SO_KEEPALIVE = + new StdSocketOption<Boolean>("SO_KEEPALIVE", Boolean.class); + + /** + * The size of the socket send buffer. + * + * <p> The value of this socket option is an {@code Integer} that is the + * size of the socket send buffer in bytes. The socket send buffer is an + * output buffer used by the networking implementation. It may need to be + * increased for high-volume connections. The value of the socket option is + * a <em>hint</em> to the implementation to size the buffer and the actual + * size may differ. The socket option can be queried to retrieve the actual + * size. + * + * <p> For datagram-oriented sockets, the size of the send buffer may limit + * the size of the datagrams that may be sent by the socket. Whether + * datagrams larger than the buffer size are sent or discarded is system + * dependent. + * + * <p> The initial/default size of the socket send buffer and the range of + * allowable values is system dependent although a negative size is not + * allowed. An attempt to set the socket send buffer to larger than its + * maximum size causes it to be set to its maximum size. + * + * <p> An implementation allows this socket option to be set before the + * socket is bound or connected. Whether an implementation allows the + * socket send buffer to be changed after the socket is bound is system + * dependent. + * + * @see Socket#setSendBufferSize + */ + public static final SocketOption<Integer> SO_SNDBUF = + new StdSocketOption<Integer>("SO_SNDBUF", Integer.class); + + + /** + * The size of the socket receive buffer. + * + * <p> The value of this socket option is an {@code Integer} that is the + * size of the socket receive buffer in bytes. The socket receive buffer is + * an input buffer used by the networking implementation. It may need to be + * increased for high-volume connections or decreased to limit the possible + * backlog of incoming data. The value of the socket option is a + * <em>hint</em> to the implementation to size the buffer and the actual + * size may differ. + * + * <p> For datagram-oriented sockets, the size of the receive buffer may + * limit the size of the datagrams that can be received. Whether datagrams + * larger than the buffer size can be received is system dependent. + * Increasing the socket receive buffer may be important for cases where + * datagrams arrive in bursts faster than they can be processed. + * + * <p> In the case of stream-oriented sockets and the TCP/IP protocol, the + * size of the socket receive buffer may be used when advertising the size + * of the TCP receive window to the remote peer. + * + * <p> The initial/default size of the socket receive buffer and the range + * of allowable values is system dependent although a negative size is not + * allowed. An attempt to set the socket receive buffer to larger than its + * maximum size causes it to be set to its maximum size. + * + * <p> An implementation allows this socket option to be set before the + * socket is bound or connected. Whether an implementation allows the + * socket receive buffer to be changed after the socket is bound is system + * dependent. + * + * @see <a href="http://www.ietf.org/rfc/rfc1323.txt">RFC 1323: TCP + * Extensions for High Performance</a> + * @see Socket#setReceiveBufferSize + * @see ServerSocket#setReceiveBufferSize + */ + public static final SocketOption<Integer> SO_RCVBUF = + new StdSocketOption<Integer>("SO_RCVBUF", Integer.class); + + /** + * Re-use address. + * + * <p> The value of this socket option is a {@code Boolean} that represents + * whether the option is enabled or disabled. The exact semantics of this + * socket option are socket type and system dependent. + * + * <p> In the case of stream-oriented sockets, this socket option will + * usually determine whether the socket can be bound to a socket address + * when a previous connection involving that socket address is in the + * <em>TIME_WAIT</em> state. On implementations where the semantics differ, + * and the socket option is not required to be enabled in order to bind the + * socket when a previous connection is in this state, then the + * implementation may choose to ignore this option. + * + * <p> For datagram-oriented sockets the socket option is used to allow + * multiple programs bind to the same address. This option should be enabled + * when the socket is to be used for Internet Protocol (IP) multicasting. + * + * <p> An implementation allows this socket option to be set before the + * socket is bound or connected. Changing the value of this socket option + * after the socket is bound has no effect. The default value of this + * socket option is system dependent. + * + * @see <a href="http://www.ietf.org/rfc/rfc793.txt">RFC 793: Transmission + * Control Protocol</a> + * @see ServerSocket#setReuseAddress + */ + public static final SocketOption<Boolean> SO_REUSEADDR = + new StdSocketOption<Boolean>("SO_REUSEADDR", Boolean.class); + + /** + * Linger on close if data is present. + * + * <p> The value of this socket option is an {@code Integer} that controls + * the action taken when unsent data is queued on the socket and a method + * to close the socket is invoked. If the value of the socket option is zero + * or greater, then it represents a timeout value, in seconds, known as the + * <em>linger interval</em>. The linger interval is the timeout for the + * {@code close} method to block while the operating system attempts to + * transmit the unsent data or it decides that it is unable to transmit the + * data. If the value of the socket option is less than zero then the option + * is disabled. In that case the {@code close} method does not wait until + * unsent data is transmitted; if possible the operating system will transmit + * any unsent data before the connection is closed. + * + * <p> This socket option is intended for use with sockets that are configured + * in {@link java.nio.channels.SelectableChannel#isBlocking() blocking} mode + * only. The behavior of the {@code close} method when this option is + * enabled on a non-blocking socket is not defined. + * + * <p> The initial value of this socket option is a negative value, meaning + * that the option is disabled. The option may be enabled, or the linger + * interval changed, at any time. The maximum value of the linger interval + * is system dependent. Setting the linger interval to a value that is + * greater than its maximum value causes the linger interval to be set to + * its maximum value. + * + * @see Socket#setSoLinger + */ + public static final SocketOption<Integer> SO_LINGER = + new StdSocketOption<Integer>("SO_LINGER", Integer.class); + + + // -- IPPROTO_IP -- + + /** + * The Type of Service (ToS) octet in the Internet Protocol (IP) header. + * + * <p> The value of this socket option is an {@code Integer} representing + * the value of the ToS octet in IP packets sent by sockets to an {@link + * StandardProtocolFamily#INET IPv4} socket. The interpretation of the ToS + * octet is network specific and is not defined by this class. Further + * information on the ToS octet can be found in <a + * href="http://www.ietf.org/rfc/rfc1349.txt">RFC 1349</a> and <a + * href="http://www.ietf.org/rfc/rfc2474.txt">RFC 2474</a>. The value + * of the socket option is a <em>hint</em>. An implementation may ignore the + * value, or ignore specific values. + * + * <p> The initial/default value of the TOS field in the ToS octet is + * implementation specific but will typically be {@code 0}. For + * datagram-oriented sockets the option may be configured at any time after + * the socket has been bound. The new value of the octet is used when sending + * subsequent datagrams. It is system dependent whether this option can be + * queried or changed prior to binding the socket. + * + * <p> The behavior of this socket option on a stream-oriented socket, or an + * {@link StandardProtocolFamily#INET6 IPv6} socket, is not defined in this + * release. + * + * @see DatagramSocket#setTrafficClass + */ + public static final SocketOption<Integer> IP_TOS = + new StdSocketOption<Integer>("IP_TOS", Integer.class); + + /** + * The network interface for Internet Protocol (IP) multicast datagrams. + * + * <p> The value of this socket option is a {@link NetworkInterface} that + * represents the outgoing interface for multicast datagrams sent by the + * datagram-oriented socket. For {@link StandardProtocolFamily#INET6 IPv6} + * sockets then it is system dependent whether setting this option also + * sets the outgoing interface for multlicast datagrams sent to IPv4 + * addresses. + * + * <p> The initial/default value of this socket option may be {@code null} + * to indicate that outgoing interface will be selected by the operating + * system, typically based on the network routing tables. An implementation + * allows this socket option to be set after the socket is bound. Whether + * the socket option can be queried or changed prior to binding the socket + * is system dependent. + * + * @see java.nio.channels.MulticastChannel + * @see MulticastSocket#setInterface + */ + public static final SocketOption<NetworkInterface> IP_MULTICAST_IF = + new StdSocketOption<NetworkInterface>("IP_MULTICAST_IF", NetworkInterface.class); + + /** + * The <em>time-to-live</em> for Internet Protocol (IP) multicast datagrams. + * + * <p> The value of this socket option is an {@code Integer} in the range + * <tt>0 <= value <= 255</tt>. It is used to control + * the scope of multicast datagrams sent by the datagram-oriented socket. + * In the case of an {@link StandardProtocolFamily#INET IPv4} socket + * the option is the time-to-live (TTL) on multicast datagrams sent by the + * socket. Datagrams with a TTL of zero are not transmitted on the network + * but may be delivered locally. In the case of an {@link + * StandardProtocolFamily#INET6 IPv6} socket the option is the + * <em>hop limit</em> which is number of <em>hops</em> that the datagram can + * pass through before expiring on the network. For IPv6 sockets it is + * system dependent whether the option also sets the <em>time-to-live</em> + * on multicast datagrams sent to IPv4 addresses. + * + * <p> The initial/default value of the time-to-live setting is typically + * {@code 1}. An implementation allows this socket option to be set after + * the socket is bound. Whether the socket option can be queried or changed + * prior to binding the socket is system dependent. + * + * @see java.nio.channels.MulticastChannel + * @see MulticastSocket#setTimeToLive + */ + public static final SocketOption<Integer> IP_MULTICAST_TTL = + new StdSocketOption<Integer>("IP_MULTICAST_TTL", Integer.class); + + /** + * Loopback for Internet Protocol (IP) multicast datagrams. + * + * <p> The value of this socket option is a {@code Boolean} that controls + * the <em>loopback</em> of multicast datagrams. The value of the socket + * option represents if the option is enabled or disabled. + * + * <p> The exact semantics of this socket options are system dependent. + * In particular, it is system dependent whether the loopback applies to + * multicast datagrams sent from the socket or received by the socket. + * For {@link StandardProtocolFamily#INET6 IPv6} sockets then it is + * system dependent whether the option also applies to multicast datagrams + * sent to IPv4 addresses. + * + * <p> The initial/default value of this socket option is {@code TRUE}. An + * implementation allows this socket option to be set after the socket is + * bound. Whether the socket option can be queried or changed prior to + * binding the socket is system dependent. + * + * @see java.nio.channels.MulticastChannel + * @see MulticastSocket#setLoopbackMode + */ + public static final SocketOption<Boolean> IP_MULTICAST_LOOP = + new StdSocketOption<Boolean>("IP_MULTICAST_LOOP", Boolean.class); + + + // -- IPPROTO_TCP -- + + /** + * Disable the Nagle algorithm. + * + * <p> The value of this socket option is a {@code Boolean} that represents + * whether the option is enabled or disabled. The socket option is specific to + * stream-oriented sockets using the TCP/IP protocol. TCP/IP uses an algorithm + * known as <em>The Nagle Algorithm</em> to coalesce short segments and + * improve network efficiency. + * + * <p> The default value of this socket option is {@code FALSE}. The + * socket option should only be enabled in cases where it is known that the + * coalescing impacts performance. The socket option may be enabled at any + * time. In other words, the Nagle Algorithm can be disabled. Once the option + * is enabled, it is system dependent whether it can be subsequently + * disabled. If it cannot, then invoking the {@code setOption} method to + * disable the option has no effect. + * + * @see <a href="http://www.ietf.org/rfc/rfc1122.txt">RFC 1122: + * Requirements for Internet Hosts -- Communication Layers</a> + * @see Socket#setTcpNoDelay + */ + public static final SocketOption<Boolean> TCP_NODELAY = + new StdSocketOption<Boolean>("TCP_NODELAY", Boolean.class); + + + private static class StdSocketOption<T> implements SocketOption<T> { + private final String name; + private final Class<T> type; + StdSocketOption(String name, Class<T> type) { + this.name = name; + this.type = type; + } + public String name() { return name; } + public Class<T> type() { return type; } + public String toString() { return name; } + } +}
--- a/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/channels/AsynchronousFileChannel.java Tue Jan 13 16:38:40 2009 +0000 +++ b/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/channels/AsynchronousFileChannel.java Wed Jan 14 05:27:57 2009 +0000 @@ -34,10 +34,10 @@ import java.util.HashSet; import java.util.Collections; -import org.classpath.icedtea.java.nio.file.FileSystemProvider; import org.classpath.icedtea.java.nio.file.OpenOption; import org.classpath.icedtea.java.nio.file.Path; import org.classpath.icedtea.java.nio.file.attribute.FileAttribute; +import org.classpath.icedtea.java.nio.file.spi.FileSystemProvider; /** * An asynchronous channel for reading, writing, and manipulating a file.
--- a/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/channels/AsynchronousServerSocketChannel.java Tue Jan 13 16:38:40 2009 +0000 +++ b/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/channels/AsynchronousServerSocketChannel.java Wed Jan 14 05:27:57 2009 +0000 @@ -26,11 +26,11 @@ package org.classpath.icedtea.java.nio.channels; -import java.net.SocketOption; import java.net.SocketAddress; import java.util.concurrent.Future; import java.io.IOException; +import org.classpath.icedtea.java.net.SocketOption; import org.classpath.icedtea.java.nio.channels.spi.AsynchronousChannelProvider; /**
--- a/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/channels/AsynchronousSocketChannel.java Tue Jan 13 16:38:40 2009 +0000 +++ b/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/channels/AsynchronousSocketChannel.java Wed Jan 14 05:27:57 2009 +0000 @@ -26,14 +26,15 @@ package org.classpath.icedtea.java.nio.channels; -import java.nio.channels.spi.*; import java.util.concurrent.TimeUnit; import java.util.concurrent.Future; import java.io.IOException; -import java.net.SocketOption; import java.net.SocketAddress; import java.nio.ByteBuffer; +import org.classpath.icedtea.java.net.SocketOption; +import org.classpath.icedtea.java.nio.channels.spi.AsynchronousChannelProvider; + /** * An asynchronous channel for stream-oriented connecting sockets. *
--- a/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/channels/FileChannel.java Tue Jan 13 16:38:40 2009 +0000 +++ b/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/channels/FileChannel.java Wed Jan 14 05:27:57 2009 +0000 @@ -29,14 +29,20 @@ import java.io.*; import java.nio.ByteBuffer; import java.nio.MappedByteBuffer; +import java.nio.channels.GatheringByteChannel; +import java.nio.channels.ReadableByteChannel; +import java.nio.channels.ScatteringByteChannel; +import java.nio.channels.WritableByteChannel; import java.nio.channels.spi.AbstractInterruptibleChannel; -import java.nio.file.*; -import java.nio.file.attribute.FileAttribute; -import java.nio.file.spi.*; import java.util.Set; import java.util.HashSet; import java.util.Collections; +import org.classpath.icedtea.java.nio.file.OpenOption; +import org.classpath.icedtea.java.nio.file.Path; +import org.classpath.icedtea.java.nio.file.attribute.FileAttribute; +import org.classpath.icedtea.java.nio.file.spi.FileSystemProvider; + /** * A channel for reading, writing, mapping, and manipulating a file. *
--- a/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/channels/FileLock.java Tue Jan 13 16:38:40 2009 +0000 +++ b/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/channels/FileLock.java Wed Jan 14 05:27:57 2009 +0000 @@ -28,6 +28,8 @@ import java.io.IOException; +import java.nio.channels.Channel; + /** * A token representing a lock on a region of a file. *
--- a/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/channels/MulticastChannel.java Tue Jan 13 16:38:40 2009 +0000 +++ b/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/channels/MulticastChannel.java Wed Jan 14 05:27:57 2009 +0000 @@ -29,10 +29,10 @@ import java.net.InetAddress; import java.net.NetworkInterface; import java.io.IOException; -import java.net.StandardProtocolFamily; // javadoc -import java.net.StandardSocketOption; // javadoc import org.classpath.icedtea.java.net.ProtocolFamily; // javadoc +import org.classpath.icedtea.java.net.StandardProtocolFamily; // javadoc +import org.classpath.icedtea.java.net.StandardSocketOption; // javadoc /** * A network channel that supports Internet Protocol (IP) multicasting.
--- a/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/FileTreeWalker.java Tue Jan 13 16:38:40 2009 +0000 +++ b/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/FileTreeWalker.java Wed Jan 14 05:27:57 2009 +0000 @@ -26,10 +26,12 @@ package org.classpath.icedtea.java.nio.file; -import java.nio.file.attribute.*; import java.io.IOException; import java.util.*; +import org.classpath.icedtea.java.nio.file.attribute.Attributes; +import org.classpath.icedtea.java.nio.file.attribute.BasicFileAttributes; + /** * Simple file tree walker that works in a similar manner to nftw(3C). *
--- a/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/FileVisitor.java Tue Jan 13 16:38:40 2009 +0000 +++ b/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/FileVisitor.java Wed Jan 14 05:27:57 2009 +0000 @@ -26,9 +26,10 @@ package org.classpath.icedtea.java.nio.file; -import java.nio.file.attribute.BasicFileAttributes; import java.io.IOException; +import org.classpath.icedtea.java.nio.file.attribute.BasicFileAttributes; + /** * A visitor of files. An implementation of this interface is provided to the * {@link Files#walkFileTree walkFileTree} utility method to visit each file
--- a/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/Files.java Tue Jan 13 16:38:40 2009 +0000 +++ b/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/Files.java Wed Jan 14 05:27:57 2009 +0000 @@ -26,12 +26,13 @@ package org.classpath.icedtea.java.nio.file; -import java.nio.file.spi.FileTypeDetector; import java.io.IOException; import java.util.*; import java.security.AccessController; import java.security.PrivilegedAction; +import org.classpath.icedtea.java.nio.file.spi.FileTypeDetector; + /** * Utility methods for files and directories. *
--- a/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/Path.java Tue Jan 13 16:38:40 2009 +0000 +++ b/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/Path.java Wed Jan 14 05:27:57 2009 +0000 @@ -31,6 +31,8 @@ import java.net.URI; import java.util.*; +import org.classpath.icedtea.java.nio.channels.SeekableByteChannel; + import org.classpath.icedtea.java.nio.file.attribute.FileAttribute; /**
--- a/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/Paths.java Tue Jan 13 16:38:40 2009 +0000 +++ b/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/Paths.java Wed Jan 14 05:27:57 2009 +0000 @@ -26,10 +26,11 @@ package org.classpath.icedtea.java.nio.file; -import java.nio.file.spi.FileSystemProvider; import java.net.URI; import java.util.Iterator; +import org.classpath.icedtea.java.nio.file.spi.FileSystemProvider; + /** * This class consists exclusively of static methods that return a {@link Path} * by converting a path string or {@link URI}.
--- a/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/SecureDirectoryStream.java Tue Jan 13 16:38:40 2009 +0000 +++ b/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/SecureDirectoryStream.java Wed Jan 14 05:27:57 2009 +0000 @@ -25,11 +25,13 @@ */ package org.classpath.icedtea.java.nio.file; -import java.nio.file.attribute.*; -import java.nio.channels.SeekableByteChannel; import java.util.Set; import java.io.IOException; +import org.classpath.icedtea.java.nio.channels.SeekableByteChannel; +import org.classpath.icedtea.java.nio.file.attribute.FileAttribute; +import org.classpath.icedtea.java.nio.file.attribute.FileAttributeView; + /** * A {@code DirectoryStream} that defines operations on files that are located * relative to an open directory. A {@code SecureDirectoryStream} is intended
--- a/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/SimpleFileVisitor.java Tue Jan 13 16:38:40 2009 +0000 +++ b/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/SimpleFileVisitor.java Wed Jan 14 05:27:57 2009 +0000 @@ -26,10 +26,11 @@ package org.classpath.icedtea.java.nio.file; -import java.nio.file.attribute.BasicFileAttributes; import java.io.IOException; import java.io.IOError; +import org.classpath.icedtea.java.nio.file.attribute.BasicFileAttributes; + /** * A simple visitor of files with default behavior to visit all files and to * re-throw I/O errors.
--- a/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/attribute/AclFileAttributeView.java Tue Jan 13 16:38:40 2009 +0000 +++ b/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/attribute/AclFileAttributeView.java Wed Jan 14 05:27:57 2009 +0000 @@ -26,7 +26,6 @@ package org.classpath.icedtea.java.nio.file.attribute; -import java.nio.file.*; import java.util.List; import java.io.IOException;
--- a/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/attribute/Attributes.java Tue Jan 13 16:38:40 2009 +0000 +++ b/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/attribute/Attributes.java Wed Jan 14 05:27:57 2009 +0000 @@ -31,6 +31,7 @@ import java.util.concurrent.TimeUnit; import org.classpath.icedtea.java.nio.file.FileRef; +import org.classpath.icedtea.java.nio.file.FileStore; import org.classpath.icedtea.java.nio.file.LinkOption; /**
--- a/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/attribute/FileStoreSpaceAttributeView.java Tue Jan 13 16:38:40 2009 +0000 +++ b/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/attribute/FileStoreSpaceAttributeView.java Wed Jan 14 05:27:57 2009 +0000 @@ -26,7 +26,6 @@ package org.classpath.icedtea.java.nio.file.attribute; -import java.nio.file.*; import java.util.Map; import java.io.IOException;
--- a/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/attribute/PosixFileAttributeView.java Tue Jan 13 16:38:40 2009 +0000 +++ b/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/attribute/PosixFileAttributeView.java Wed Jan 14 05:27:57 2009 +0000 @@ -26,7 +26,6 @@ package org.classpath.icedtea.java.nio.file.attribute; -import java.nio.file.*; import java.util.Set; import java.io.IOException;
--- a/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/attribute/PosixFilePermissions.java Tue Jan 13 16:38:40 2009 +0000 +++ b/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/attribute/PosixFilePermissions.java Wed Jan 14 05:27:57 2009 +0000 @@ -26,9 +26,18 @@ package org.classpath.icedtea.java.nio.file.attribute; -import static java.nio.file.attribute.PosixFilePermission.*; import java.util.*; +import static org.classpath.icedtea.java.nio.file.attribute.PosixFilePermission.OWNER_READ; +import static org.classpath.icedtea.java.nio.file.attribute.PosixFilePermission.OWNER_WRITE; +import static org.classpath.icedtea.java.nio.file.attribute.PosixFilePermission.OWNER_EXECUTE; +import static org.classpath.icedtea.java.nio.file.attribute.PosixFilePermission.GROUP_READ; +import static org.classpath.icedtea.java.nio.file.attribute.PosixFilePermission.GROUP_WRITE; +import static org.classpath.icedtea.java.nio.file.attribute.PosixFilePermission.GROUP_EXECUTE; +import static org.classpath.icedtea.java.nio.file.attribute.PosixFilePermission.OTHERS_READ; +import static org.classpath.icedtea.java.nio.file.attribute.PosixFilePermission.OTHERS_WRITE; +import static org.classpath.icedtea.java.nio.file.attribute.PosixFilePermission.OTHERS_EXECUTE; + /** * This class consists exclusively of static methods that operate on sets of * {@link PosixFilePermission} objects.
--- a/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/spi/AbstractPath.java Tue Jan 13 16:38:40 2009 +0000 +++ b/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/spi/AbstractPath.java Wed Jan 14 05:27:57 2009 +0000 @@ -31,10 +31,26 @@ import java.io.*; import java.util.*; +import org.classpath.icedtea.java.nio.channels.SeekableByteChannel; + +import org.classpath.icedtea.java.nio.file.AtomicMoveNotSupportedException; import org.classpath.icedtea.java.nio.file.CopyOption; +import org.classpath.icedtea.java.nio.file.DirectoryStream; +import org.classpath.icedtea.java.nio.file.FileRef; +import org.classpath.icedtea.java.nio.file.LinkOption; +import org.classpath.icedtea.java.nio.file.NoSuchFileException; +import org.classpath.icedtea.java.nio.file.OpenOption; import org.classpath.icedtea.java.nio.file.Path; +import org.classpath.icedtea.java.nio.file.PathMatcher; import org.classpath.icedtea.java.nio.file.StandardOpenOption; +import org.classpath.icedtea.java.nio.file.StandardCopyOption; +import org.classpath.icedtea.java.nio.file.WatchEvent; +import org.classpath.icedtea.java.nio.file.WatchKey; +import org.classpath.icedtea.java.nio.file.WatchService; +import org.classpath.icedtea.java.nio.file.attribute.Attributes; +import org.classpath.icedtea.java.nio.file.attribute.BasicFileAttributes; +import org.classpath.icedtea.java.nio.file.attribute.BasicFileAttributeView; import org.classpath.icedtea.java.nio.file.attribute.FileAttribute; /**
--- a/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/spi/FileSystemProvider.java Tue Jan 13 16:38:40 2009 +0000 +++ b/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/spi/FileSystemProvider.java Wed Jan 14 05:27:57 2009 +0000 @@ -26,8 +26,6 @@ package org.classpath.icedtea.java.nio.file.spi; -import java.nio.file.*; -import java.nio.file.attribute.FileAttribute; import java.nio.channels.*; import java.net.URI; import java.util.*; @@ -36,6 +34,14 @@ import java.security.PrivilegedAction; import java.io.IOException; +import org.classpath.icedtea.java.nio.channels.AsynchronousFileChannel; +import org.classpath.icedtea.java.nio.file.FileRef; +import org.classpath.icedtea.java.nio.file.FileSystem; +import org.classpath.icedtea.java.nio.file.FileSystems; +import org.classpath.icedtea.java.nio.file.OpenOption; +import org.classpath.icedtea.java.nio.file.Path; +import org.classpath.icedtea.java.nio.file.attribute.FileAttribute; + /** * Service-provider class for file systems. *
--- a/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/spi/FileTypeDetector.java Tue Jan 13 16:38:40 2009 +0000 +++ b/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/nio/file/spi/FileTypeDetector.java Wed Jan 14 05:27:57 2009 +0000 @@ -26,9 +26,10 @@ package org.classpath.icedtea.java.nio.file.spi; -import java.nio.file.FileRef; import java.io.IOException; +import org.classpath.icedtea.java.nio.file.FileRef; + /** * A file type detector for probing a file to guess its file type. *
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/java/util/concurrent/ScheduledThreadPoolExecutor.java Wed Jan 14 05:27:57 2009 +0000 @@ -0,0 +1,1364 @@ +/* + * 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +package org.classpath.icedtea.java.util.concurrent; + +import java.util.*; + +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.Callable; +import java.util.concurrent.Delayed; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.FutureTask; +import java.util.concurrent.RejectedExecutionHandler; +import java.util.concurrent.RunnableScheduledFuture; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; + +import java.util.concurrent.atomic.*; +import java.util.concurrent.locks.*; + +import org.classpath.icedtea.misc.SharedSecrets; + +/** + * A {@link ThreadPoolExecutor} that can additionally schedule + * commands to run after a given delay, or to execute + * periodically. This class is preferable to {@link java.util.Timer} + * when multiple worker threads are needed, or when the additional + * flexibility or capabilities of {@link ThreadPoolExecutor} (which + * this class extends) are required. + * + * <p>Delayed tasks execute no sooner than they are enabled, but + * without any real-time guarantees about when, after they are + * enabled, they will commence. Tasks scheduled for exactly the same + * execution time are enabled in first-in-first-out (FIFO) order of + * submission. + * + * <p>When a submitted task is cancelled before it is run, execution + * is suppressed. By default, such a cancelled task is not + * automatically removed from the work queue until its delay + * elapses. While this enables further inspection and monitoring, it + * may also cause unbounded retention of cancelled tasks. To avoid + * this, set {@link #setRemoveOnCancelPolicy} to {@code true}, which + * causes tasks to be immediately removed from the work queue at + * time of cancellation. + * + * <p>While this class inherits from {@link ThreadPoolExecutor}, a few + * of the inherited tuning methods are not useful for it. In + * particular, because it acts as a fixed-sized pool using + * {@code corePoolSize} threads and an unbounded queue, adjustments + * to {@code maximumPoolSize} have no useful effect. Additionally, it + * is almost never a good idea to set {@code corePoolSize} to zero or + * use {@code allowCoreThreadTimeOut} because this may leave the pool + * without threads to handle tasks once they become eligible to run. + * + * <p><b>Extension notes:</b> This class overrides the + * {@link ThreadPoolExecutor#execute execute} and + * {@link AbstractExecutorService#submit(Runnable) submit} + * methods to generate internal {@link ScheduledFuture} objects to + * control per-task delays and scheduling. To preserve + * functionality, any further overrides of these methods in + * subclasses must invoke superclass versions, which effectively + * disables additional task customization. However, this class + * provides alternative protected extension method + * {@code decorateTask} (one version each for {@code Runnable} and + * {@code Callable}) that can be used to customize the concrete task + * types used to execute commands entered via {@code execute}, + * {@code submit}, {@code schedule}, {@code scheduleAtFixedRate}, + * and {@code scheduleWithFixedDelay}. By default, a + * {@code ScheduledThreadPoolExecutor} uses a task type extending + * {@link FutureTask}. However, this may be modified or replaced using + * subclasses of the form: + * + * <pre> {@code + * public class CustomScheduledExecutor extends ScheduledThreadPoolExecutor { + * + * static class CustomTask<V> implements RunnableScheduledFuture<V> { ... } + * + * protected <V> RunnableScheduledFuture<V> decorateTask( + * Runnable r, RunnableScheduledFuture<V> task) { + * return new CustomTask<V>(r, task); + * } + * + * protected <V> RunnableScheduledFuture<V> decorateTask( + * Callable<V> c, RunnableScheduledFuture<V> task) { + * return new CustomTask<V>(c, task); + * } + * // ... add constructors, etc. + * }}</pre> + * + * @since 1.5 + * @author Doug Lea + */ +public class ScheduledThreadPoolExecutor + extends ThreadPoolExecutor + implements ScheduledExecutorService { + + /* + * This class specializes ThreadPoolExecutor implementation by + * + * 1. Using a custom task type, ScheduledFutureTask for + * tasks, even those that don't require scheduling (i.e., + * those submitted using ExecutorService execute, not + * ScheduledExecutorService methods) which are treated as + * delayed tasks with a delay of zero. + * + * 2. Using a custom queue (DelayedWorkQueue), a variant of + * unbounded DelayQueue. The lack of capacity constraint and + * the fact that corePoolSize and maximumPoolSize are + * effectively identical simplifies some execution mechanics + * (see delayedExecute) compared to ThreadPoolExecutor. + * + * 3. Supporting optional run-after-shutdown parameters, which + * leads to overrides of shutdown methods to remove and cancel + * tasks that should NOT be run after shutdown, as well as + * different recheck logic when task (re)submission overlaps + * with a shutdown. + * + * 4. Task decoration methods to allow interception and + * instrumentation, which are needed because subclasses cannot + * otherwise override submit methods to get this effect. These + * don't have any impact on pool control logic though. + */ + + /** + * False if should cancel/suppress periodic tasks on shutdown. + */ + private volatile boolean continueExistingPeriodicTasksAfterShutdown; + + /** + * False if should cancel non-periodic tasks on shutdown. + */ + private volatile boolean executeExistingDelayedTasksAfterShutdown = true; + + /** + * True if ScheduledFutureTask.cancel should remove from queue + */ + private volatile boolean removeOnCancel = false; + + /** + * Sequence number to break scheduling ties, and in turn to + * guarantee FIFO order among tied entries. + */ + private static final AtomicLong sequencer = new AtomicLong(0); + + /** + * Returns current nanosecond time. + */ + final long now() { + return System.nanoTime(); + } + + private class ScheduledFutureTask<V> + extends FutureTask<V> implements RunnableScheduledFuture<V> { + + /** Sequence number to break ties FIFO */ + private final long sequenceNumber; + + /** The time the task is enabled to execute in nanoTime units */ + private long time; + + /** + * Period in nanoseconds for repeating tasks. A positive + * value indicates fixed-rate execution. A negative value + * indicates fixed-delay execution. A value of 0 indicates a + * non-repeating task. + */ + private final long period; + + /** The actual task to be re-enqueued by reExecutePeriodic */ + RunnableScheduledFuture<V> outerTask = this; + + /** + * Index into delay queue, to support faster cancellation. + */ + int heapIndex; + + /** + * Creates a one-shot action with given nanoTime-based trigger time. + */ + ScheduledFutureTask(Runnable r, V result, long ns) { + super(r, result); + this.time = ns; + this.period = 0; + this.sequenceNumber = sequencer.getAndIncrement(); + } + + /** + * Creates a periodic action with given nano time and period. + */ + ScheduledFutureTask(Runnable r, V result, long ns, long period) { + super(r, result); + this.time = ns; + this.period = period; + this.sequenceNumber = sequencer.getAndIncrement(); + } + + /** + * Creates a one-shot action with given nanoTime-based trigger. + */ + ScheduledFutureTask(Callable<V> callable, long ns) { + super(callable); + this.time = ns; + this.period = 0; + this.sequenceNumber = sequencer.getAndIncrement(); + } + + public long getDelay(TimeUnit unit) { + return unit.convert(time - now(), TimeUnit.NANOSECONDS); + } + + public int compareTo(Delayed other) { + if (other == this) // compare zero ONLY if same object + return 0; + if (other instanceof ScheduledFutureTask) { + ScheduledFutureTask<?> x = (ScheduledFutureTask<?>)other; + long diff = time - x.time; + if (diff < 0) + return -1; + else if (diff > 0) + return 1; + else if (sequenceNumber < x.sequenceNumber) + return -1; + else + return 1; + } + long d = (getDelay(TimeUnit.NANOSECONDS) - + other.getDelay(TimeUnit.NANOSECONDS)); + return (d == 0) ? 0 : ((d < 0) ? -1 : 1); + } + + /** + * Returns true if this is a periodic (not a one-shot) action. + * + * @return true if periodic + */ + public boolean isPeriodic() { + return period != 0; + } + + /** + * Sets the next time to run for a periodic task. + */ + private void setNextRunTime() { + long p = period; + if (p > 0) + time += p; + else + time = triggerTime(-p); + } + + public boolean cancel(boolean mayInterruptIfRunning) { + boolean cancelled = super.cancel(mayInterruptIfRunning); + if (cancelled && removeOnCancel && heapIndex >= 0) + remove(this); + return cancelled; + } + + /** + * Overrides FutureTask version so as to reset/requeue if periodic. + */ + public void run() { + boolean periodic = isPeriodic(); + if (!canRunInCurrentRunState(periodic)) + cancel(false); + else if (!periodic) + ScheduledFutureTask.super.run(); + else if (ScheduledFutureTask.super.runAndReset()) { + setNextRunTime(); + reExecutePeriodic(outerTask); + } + } + } + + /** + * Returns true if can run a task given current run state + * and run-after-shutdown parameters. + * + * @param periodic true if this task periodic, false if delayed + */ + boolean canRunInCurrentRunState(boolean periodic) { + return isRunningOrShutdownSTPE(periodic ? + continueExistingPeriodicTasksAfterShutdown : + executeExistingDelayedTasksAfterShutdown); + } + + /** + * Main execution method for delayed or periodic tasks. If pool + * is shut down, rejects the task. Otherwise adds task to queue + * and starts a thread, if necessary, to run it. (We cannot + * prestart the thread to run the task because the task (probably) + * shouldn't be run yet,) If the pool is shut down while the task + * is being added, cancel and remove it if required by state and + * run-after-shutdown parameters. + * + * @param task the task + */ + private void delayedExecute(RunnableScheduledFuture<?> task) { + if (isShutdown()) + rejectSTPE(task); + else { + super.getQueue().add(task); + if (isShutdown() && + !canRunInCurrentRunState(task.isPeriodic()) && + remove(task)) + task.cancel(false); + else + prestartCoreThread(); + } + } + + /** + * Requeues a periodic task unless current run state precludes it. + * Same idea as delayedExecute except drops task rather than rejecting. + * + * @param task the task + */ + void reExecutePeriodic(RunnableScheduledFuture<?> task) { + if (canRunInCurrentRunState(true)) { + super.getQueue().add(task); + if (!canRunInCurrentRunState(true) && remove(task)) + task.cancel(false); + else + prestartCoreThread(); + } + } + + /** + * Cancels and clears the queue of all tasks that should not be run + * due to shutdown policy. Invoked within super.shutdown. + */ + void onShutdown() { + BlockingQueue<Runnable> q = super.getQueue(); + boolean keepDelayed = + getExecuteExistingDelayedTasksAfterShutdownPolicy(); + boolean keepPeriodic = + getContinueExistingPeriodicTasksAfterShutdownPolicy(); + if (!keepDelayed && !keepPeriodic) + q.clear(); + else { + // Traverse snapshot to avoid iterator exceptions + for (Object e : q.toArray()) { + if (e instanceof RunnableScheduledFuture) { + RunnableScheduledFuture<?> t = + (RunnableScheduledFuture<?>)e; + if ((t.isPeriodic() ? !keepPeriodic : !keepDelayed) || + t.isCancelled()) { // also remove if already cancelled + if (q.remove(t)) + t.cancel(false); + } + } + } + } + tryTerminateSTPE(); + } + + /** + * Modifies or replaces the task used to execute a runnable. + * This method can be used to override the concrete + * class used for managing internal tasks. + * The default implementation simply returns the given task. + * + * @param runnable the submitted Runnable + * @param task the task created to execute the runnable + * @return a task that can execute the runnable + * @since 1.6 + */ + protected <V> RunnableScheduledFuture<V> decorateTask( + Runnable runnable, RunnableScheduledFuture<V> task) { + return task; + } + + /** + * Modifies or replaces the task used to execute a callable. + * This method can be used to override the concrete + * class used for managing internal tasks. + * The default implementation simply returns the given task. + * + * @param callable the submitted Callable + * @param task the task created to execute the callable + * @return a task that can execute the callable + * @since 1.6 + */ + protected <V> RunnableScheduledFuture<V> decorateTask( + Callable<V> callable, RunnableScheduledFuture<V> task) { + return task; + } + + /** + * Creates a new {@code ScheduledThreadPoolExecutor} with the + * given core pool size. + * + * @param corePoolSize the number of threads to keep in the pool, even + * if they are idle, unless {@code allowCoreThreadTimeOut} is set + * @throws IllegalArgumentException if {@code corePoolSize < 0} + */ + public ScheduledThreadPoolExecutor(int corePoolSize) { + super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS, + new DelayedWorkQueue()); + } + + /** + * Creates a new {@code ScheduledThreadPoolExecutor} with the + * given initial parameters. + * + * @param corePoolSize the number of threads to keep in the pool, even + * if they are idle, unless {@code allowCoreThreadTimeOut} is set + * @param threadFactory the factory to use when the executor + * creates a new thread + * @throws IllegalArgumentException if {@code corePoolSize < 0} + * @throws NullPointerException if {@code threadFactory} is null + */ + public ScheduledThreadPoolExecutor(int corePoolSize, + ThreadFactory threadFactory) { + super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS, + new DelayedWorkQueue(), threadFactory); + } + + /** + * Creates a new ScheduledThreadPoolExecutor with the given + * initial parameters. + * + * @param corePoolSize the number of threads to keep in the pool, even + * if they are idle, unless {@code allowCoreThreadTimeOut} is set + * @param handler the handler to use when execution is blocked + * because the thread bounds and queue capacities are reached + * @throws IllegalArgumentException if {@code corePoolSize < 0} + * @throws NullPointerException if {@code handler} is null + */ + public ScheduledThreadPoolExecutor(int corePoolSize, + RejectedExecutionHandler handler) { + super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS, + new DelayedWorkQueue(), handler); + } + + /** + * Creates a new ScheduledThreadPoolExecutor with the given + * initial parameters. + * + * @param corePoolSize the number of threads to keep in the pool, even + * if they are idle, unless {@code allowCoreThreadTimeOut} is set + * @param threadFactory the factory to use when the executor + * creates a new thread + * @param handler the handler to use when execution is blocked + * because the thread bounds and queue capacities are reached + * @throws IllegalArgumentException if {@code corePoolSize < 0} + * @throws NullPointerException if {@code threadFactory} or + * {@code handler} is null + */ + public ScheduledThreadPoolExecutor(int corePoolSize, + ThreadFactory threadFactory, + RejectedExecutionHandler handler) { + super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS, + new DelayedWorkQueue(), threadFactory, handler); + } + + /** + * Returns the trigger time of a delayed action. + */ + private long triggerTime(long delay, TimeUnit unit) { + return triggerTime(unit.toNanos((delay < 0) ? 0 : delay)); + } + + /** + * Returns the trigger time of a delayed action. + */ + long triggerTime(long delay) { + return now() + + ((delay < (Long.MAX_VALUE >> 1)) ? delay : overflowFree(delay)); + } + + /** + * Constrains the values of all delays in the queue to be within + * Long.MAX_VALUE of each other, to avoid overflow in compareTo. + * This may occur if a task is eligible to be dequeued, but has + * not yet been, while some other task is added with a delay of + * Long.MAX_VALUE. + */ + private long overflowFree(long delay) { + Delayed head = (Delayed) super.getQueue().peek(); + if (head != null) { + long headDelay = head.getDelay(TimeUnit.NANOSECONDS); + if (headDelay < 0 && (delay - headDelay < 0)) + delay = Long.MAX_VALUE + headDelay; + } + return delay; + } + + /** + * @throws RejectedExecutionException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + */ + public ScheduledFuture<?> schedule(Runnable command, + long delay, + TimeUnit unit) { + if (command == null || unit == null) + throw new NullPointerException(); + RunnableScheduledFuture<?> t = decorateTask(command, + new ScheduledFutureTask<Void>(command, null, + triggerTime(delay, unit))); + delayedExecute(t); + return t; + } + + /** + * @throws RejectedExecutionException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + */ + public <V> ScheduledFuture<V> schedule(Callable<V> callable, + long delay, + TimeUnit unit) { + if (callable == null || unit == null) + throw new NullPointerException(); + RunnableScheduledFuture<V> t = decorateTask(callable, + new ScheduledFutureTask<V>(callable, + triggerTime(delay, unit))); + delayedExecute(t); + return t; + } + + /** + * @throws RejectedExecutionException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + * @throws IllegalArgumentException {@inheritDoc} + */ + public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, + long initialDelay, + long period, + TimeUnit unit) { + if (command == null || unit == null) + throw new NullPointerException(); + if (period <= 0) + throw new IllegalArgumentException(); + ScheduledFutureTask<Void> sft = + new ScheduledFutureTask<Void>(command, + null, + triggerTime(initialDelay, unit), + unit.toNanos(period)); + RunnableScheduledFuture<Void> t = decorateTask(command, sft); + sft.outerTask = t; + delayedExecute(t); + return t; + } + + /** + * @throws RejectedExecutionException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + * @throws IllegalArgumentException {@inheritDoc} + */ + public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, + long initialDelay, + long delay, + TimeUnit unit) { + if (command == null || unit == null) + throw new NullPointerException(); + if (delay <= 0) + throw new IllegalArgumentException(); + ScheduledFutureTask<Void> sft = + new ScheduledFutureTask<Void>(command, + null, + triggerTime(initialDelay, unit), + unit.toNanos(-delay)); + RunnableScheduledFuture<Void> t = decorateTask(command, sft); + sft.outerTask = t; + delayedExecute(t); + return t; + } + + /** + * Executes {@code command} with zero required delay. + * This has effect equivalent to + * {@link #schedule(Runnable,long,TimeUnit) schedule(command, 0, anyUnit)}. + * Note that inspections of the queue and of the list returned by + * {@code shutdownNow} will access the zero-delayed + * {@link ScheduledFuture}, not the {@code command} itself. + * + * <p>A consequence of the use of {@code ScheduledFuture} objects is + * that {@link ThreadPoolExecutor#afterExecute afterExecute} is always + * called with a null second {@code Throwable} argument, even if the + * {@code command} terminated abruptly. Instead, the {@code Throwable} + * thrown by such a task can be obtained via {@link Future#get}. + * + * @throws RejectedExecutionException at discretion of + * {@code RejectedExecutionHandler}, if the task + * cannot be accepted for execution because the + * executor has been shut down + * @throws NullPointerException {@inheritDoc} + */ + public void execute(Runnable command) { + schedule(command, 0, TimeUnit.NANOSECONDS); + } + + // Override AbstractExecutorService methods + + /** + * @throws RejectedExecutionException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + */ + public Future<?> submit(Runnable task) { + return schedule(task, 0, TimeUnit.NANOSECONDS); + } + + /** + * @throws RejectedExecutionException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + */ + public <T> Future<T> submit(Runnable task, T result) { + return schedule(Executors.callable(task, result), + 0, TimeUnit.NANOSECONDS); + } + + /** + * @throws RejectedExecutionException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + */ + public <T> Future<T> submit(Callable<T> task) { + return schedule(task, 0, TimeUnit.NANOSECONDS); + } + + /** + * Sets the policy on whether to continue executing existing + * periodic tasks even when this executor has been {@code shutdown}. + * In this case, these tasks will only terminate upon + * {@code shutdownNow} or after setting the policy to + * {@code false} when already shutdown. + * This value is by default {@code false}. + * + * @param value if {@code true}, continue after shutdown, else don't. + * @see #getContinueExistingPeriodicTasksAfterShutdownPolicy + */ + public void setContinueExistingPeriodicTasksAfterShutdownPolicy(boolean value) { + continueExistingPeriodicTasksAfterShutdown = value; + if (!value && isShutdown()) + onShutdown(); + } + + /** + * Gets the policy on whether to continue executing existing + * periodic tasks even when this executor has been {@code shutdown}. + * In this case, these tasks will only terminate upon + * {@code shutdownNow} or after setting the policy to + * {@code false} when already shutdown. + * This value is by default {@code false}. + * + * @return {@code true} if will continue after shutdown + * @see #setContinueExistingPeriodicTasksAfterShutdownPolicy + */ + public boolean getContinueExistingPeriodicTasksAfterShutdownPolicy() { + return continueExistingPeriodicTasksAfterShutdown; + } + + /** + * Sets the policy on whether to execute existing delayed + * tasks even when this executor has been {@code shutdown}. + * In this case, these tasks will only terminate upon + * {@code shutdownNow}, or after setting the policy to + * {@code false} when already shutdown. + * This value is by default {@code true}. + * + * @param value if {@code true}, execute after shutdown, else don't. + * @see #getExecuteExistingDelayedTasksAfterShutdownPolicy + */ + public void setExecuteExistingDelayedTasksAfterShutdownPolicy(boolean value) { + executeExistingDelayedTasksAfterShutdown = value; + if (!value && isShutdown()) + onShutdown(); + } + + /** + * Gets the policy on whether to execute existing delayed + * tasks even when this executor has been {@code shutdown}. + * In this case, these tasks will only terminate upon + * {@code shutdownNow}, or after setting the policy to + * {@code false} when already shutdown. + * This value is by default {@code true}. + * + * @return {@code true} if will execute after shutdown + * @see #setExecuteExistingDelayedTasksAfterShutdownPolicy + */ + public boolean getExecuteExistingDelayedTasksAfterShutdownPolicy() { + return executeExistingDelayedTasksAfterShutdown; + } + + /** + * Sets the policy on whether cancelled tasks should be immediately + * removed from the work queue at time of cancellation. This value is + * by default {@code false}. + * + * @param value if {@code true}, remove on cancellation, else don't + * @see #getRemoveOnCancelPolicy + * @since 1.7 + */ + public void setRemoveOnCancelPolicy(boolean value) { + removeOnCancel = value; + } + + /** + * Gets the policy on whether cancelled tasks should be immediately + * removed from the work queue at time of cancellation. This value is + * by default {@code false}. + * + * @return {@code true} if cancelled tasks are immediately removed + * from the queue + * @see #setRemoveOnCancelPolicy + * @since 1.7 + */ + public boolean getRemoveOnCancelPolicy() { + return removeOnCancel; + } + + /** + * Initiates an orderly shutdown in which previously submitted + * tasks are executed, but no new tasks will be accepted. + * Invocation has no additional effect if already shut down. + * + * <p>This method does not wait for previously submitted tasks to + * complete execution. Use {@link #awaitTermination awaitTermination} + * to do that. + * + * <p>If the {@code ExecuteExistingDelayedTasksAfterShutdownPolicy} + * has been set {@code false}, existing delayed tasks whose delays + * have not yet elapsed are cancelled. And unless the {@code + * ContinueExistingPeriodicTasksAfterShutdownPolicy} has been set + * {@code true}, future executions of existing periodic tasks will + * be cancelled. + * + * @throws SecurityException {@inheritDoc} + */ + public void shutdown() { + super.shutdown(); + } + + /** + * Attempts to stop all actively executing tasks, halts the + * processing of waiting tasks, and returns a list of the tasks + * that were awaiting execution. + * + * <p>This method does not wait for actively executing tasks to + * terminate. Use {@link #awaitTermination awaitTermination} to + * do that. + * + * <p>There are no guarantees beyond best-effort attempts to stop + * processing actively executing tasks. This implementation + * cancels tasks via {@link Thread#interrupt}, so any task that + * fails to respond to interrupts may never terminate. + * + * @return list of tasks that never commenced execution. + * Each element of this list is a {@link ScheduledFuture}, + * including those tasks submitted using {@code execute}, + * which are for scheduling purposes used as the basis of a + * zero-delay {@code ScheduledFuture}. + * @throws SecurityException {@inheritDoc} + */ + public List<Runnable> shutdownNow() { + return super.shutdownNow(); + } + + /** + * Returns the task queue used by this executor. Each element of + * this queue is a {@link ScheduledFuture}, including those + * tasks submitted using {@code execute} which are for scheduling + * purposes used as the basis of a zero-delay + * {@code ScheduledFuture}. Iteration over this queue is + * <em>not</em> guaranteed to traverse tasks in the order in + * which they will execute. + * + * @return the task queue + */ + public BlockingQueue<Runnable> getQueue() { + return super.getQueue(); + } + + /** + * Specialized delay queue. To mesh with TPE declarations, this + * class must be declared as a BlockingQueue<Runnable> even though + * it can only hold RunnableScheduledFutures. + */ + static class DelayedWorkQueue extends AbstractQueue<Runnable> + implements BlockingQueue<Runnable> { + + /* + * A DelayedWorkQueue is based on a heap-based data structure + * like those in DelayQueue and PriorityQueue, except that + * every ScheduledFutureTask also records its index into the + * heap array. This eliminates the need to find a task upon + * cancellation, greatly speeding up removal (down from O(n) + * to O(log n)), and reducing garbage retention that would + * otherwise occur by waiting for the element to rise to top + * before clearing. But because the queue may also hold + * RunnableScheduledFutures that are not ScheduledFutureTasks, + * we are not guaranteed to have such indices available, in + * which case we fall back to linear search. (We expect that + * most tasks will not be decorated, and that the faster cases + * will be much more common.) + * + * All heap operations must record index changes -- mainly + * within siftUp and siftDown. Upon removal, a task's + * heapIndex is set to -1. Note that ScheduledFutureTasks can + * appear at most once in the queue (this need not be true for + * other kinds of tasks or work queues), so are uniquely + * identified by heapIndex. + */ + + private static final int INITIAL_CAPACITY = 16; + private RunnableScheduledFuture[] queue = + new RunnableScheduledFuture[INITIAL_CAPACITY]; + private final ReentrantLock lock = new ReentrantLock(); + private int size = 0; + + /** + * Thread designated to wait for the task at the head of the + * queue. This variant of the Leader-Follower pattern + * (http://www.cs.wustl.edu/~schmidt/POSA/POSA2/) serves to + * minimize unnecessary timed waiting. When a thread becomes + * the leader, it waits only for the next delay to elapse, but + * other threads await indefinitely. The leader thread must + * signal some other thread before returning from take() or + * poll(...), unless some other thread becomes leader in the + * interim. Whenever the head of the queue is replaced with a + * task with an earlier expiration time, the leader field is + * invalidated by being reset to null, and some waiting + * thread, but not necessarily the current leader, is + * signalled. So waiting threads must be prepared to acquire + * and lose leadership while waiting. + */ + private Thread leader = null; + + /** + * Condition signalled when a newer task becomes available at the + * head of the queue or a new thread may need to become leader. + */ + private final Condition available = lock.newCondition(); + + /** + * Set f's heapIndex if it is a ScheduledFutureTask. + */ + private void setIndex(RunnableScheduledFuture f, int idx) { + if (f instanceof ScheduledFutureTask) + ((ScheduledFutureTask)f).heapIndex = idx; + } + + /** + * Sift element added at bottom up to its heap-ordered spot. + * Call only when holding lock. + */ + private void siftUp(int k, RunnableScheduledFuture key) { + while (k > 0) { + int parent = (k - 1) >>> 1; + RunnableScheduledFuture e = queue[parent]; + if (key.compareTo(e) >= 0) + break; + queue[k] = e; + setIndex(e, k); + k = parent; + } + queue[k] = key; + setIndex(key, k); + } + + /** + * Sift element added at top down to its heap-ordered spot. + * Call only when holding lock. + */ + private void siftDown(int k, RunnableScheduledFuture key) { + int half = size >>> 1; + while (k < half) { + int child = (k << 1) + 1; + RunnableScheduledFuture c = queue[child]; + int right = child + 1; + if (right < size && c.compareTo(queue[right]) > 0) + c = queue[child = right]; + if (key.compareTo(c) <= 0) + break; + queue[k] = c; + setIndex(c, k); + k = child; + } + queue[k] = key; + setIndex(key, k); + } + + /** + * Resize the heap array. Call only when holding lock. + */ + private void grow() { + int oldCapacity = queue.length; + int newCapacity = oldCapacity + (oldCapacity >> 1); // grow 50% + if (newCapacity < 0) // overflow + newCapacity = Integer.MAX_VALUE; + queue = Arrays.copyOf(queue, newCapacity); + } + + /** + * Find index of given object, or -1 if absent + */ + private int indexOf(Object x) { + if (x != null) { + if (x instanceof ScheduledFutureTask) { + int i = ((ScheduledFutureTask) x).heapIndex; + // Sanity check; x could conceivably be a + // ScheduledFutureTask from some other pool. + if (i >= 0 && i < size && queue[i] == x) + return i; + } else { + for (int i = 0; i < size; i++) + if (x.equals(queue[i])) + return i; + } + } + return -1; + } + + public boolean contains(Object x) { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + return indexOf(x) != -1; + } finally { + lock.unlock(); + } + } + + public boolean remove(Object x) { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + int i = indexOf(x); + if (i < 0) + return false; + + setIndex(queue[i], -1); + int s = --size; + RunnableScheduledFuture replacement = queue[s]; + queue[s] = null; + if (s != i) { + siftDown(i, replacement); + if (queue[i] == replacement) + siftUp(i, replacement); + } + return true; + } finally { + lock.unlock(); + } + } + + public int size() { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + return size; + } finally { + lock.unlock(); + } + } + + public boolean isEmpty() { + return size() == 0; + } + + public int remainingCapacity() { + return Integer.MAX_VALUE; + } + + public RunnableScheduledFuture peek() { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + return queue[0]; + } finally { + lock.unlock(); + } + } + + public boolean offer(Runnable x) { + if (x == null) + throw new NullPointerException(); + RunnableScheduledFuture e = (RunnableScheduledFuture)x; + final ReentrantLock lock = this.lock; + lock.lock(); + try { + int i = size; + if (i >= queue.length) + grow(); + size = i + 1; + if (i == 0) { + queue[0] = e; + setIndex(e, 0); + } else { + siftUp(i, e); + } + if (queue[0] == e) { + leader = null; + available.signal(); + } + } finally { + lock.unlock(); + } + return true; + } + + public void put(Runnable e) { + offer(e); + } + + public boolean add(Runnable e) { + return offer(e); + } + + public boolean offer(Runnable e, long timeout, TimeUnit unit) { + return offer(e); + } + + /** + * Performs common bookkeeping for poll and take: Replaces + * first element with last and sifts it down. Call only when + * holding lock. + * @param f the task to remove and return + */ + private RunnableScheduledFuture finishPoll(RunnableScheduledFuture f) { + int s = --size; + RunnableScheduledFuture x = queue[s]; + queue[s] = null; + if (s != 0) + siftDown(0, x); + setIndex(f, -1); + return f; + } + + public RunnableScheduledFuture poll() { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + RunnableScheduledFuture first = queue[0]; + if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0) + return null; + else + return finishPoll(first); + } finally { + lock.unlock(); + } + } + + public RunnableScheduledFuture take() throws InterruptedException { + final ReentrantLock lock = this.lock; + lock.lockInterruptibly(); + try { + for (;;) { + RunnableScheduledFuture first = queue[0]; + if (first == null) + available.await(); + else { + long delay = first.getDelay(TimeUnit.NANOSECONDS); + if (delay <= 0) + return finishPoll(first); + else if (leader != null) + available.await(); + else { + Thread thisThread = Thread.currentThread(); + leader = thisThread; + try { + available.awaitNanos(delay); + } finally { + if (leader == thisThread) + leader = null; + } + } + } + } + } finally { + if (leader == null && queue[0] != null) + available.signal(); + lock.unlock(); + } + } + + public RunnableScheduledFuture poll(long timeout, TimeUnit unit) + throws InterruptedException { + long nanos = unit.toNanos(timeout); + final ReentrantLock lock = this.lock; + lock.lockInterruptibly(); + try { + for (;;) { + RunnableScheduledFuture first = queue[0]; + if (first == null) { + if (nanos <= 0) + return null; + else + nanos = available.awaitNanos(nanos); + } else { + long delay = first.getDelay(TimeUnit.NANOSECONDS); + if (delay <= 0) + return finishPoll(first); + if (nanos <= 0) + return null; + if (nanos < delay || leader != null) + nanos = available.awaitNanos(nanos); + else { + Thread thisThread = Thread.currentThread(); + leader = thisThread; + try { + long timeLeft = available.awaitNanos(delay); + nanos -= delay - timeLeft; + } finally { + if (leader == thisThread) + leader = null; + } + } + } + } + } finally { + if (leader == null && queue[0] != null) + available.signal(); + lock.unlock(); + } + } + + public void clear() { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + for (int i = 0; i < size; i++) { + RunnableScheduledFuture t = queue[i]; + if (t != null) { + queue[i] = null; + setIndex(t, -1); + } + } + size = 0; + } finally { + lock.unlock(); + } + } + + /** + * Return and remove first element only if it is expired. + * Used only by drainTo. Call only when holding lock. + */ + private RunnableScheduledFuture pollExpired() { + RunnableScheduledFuture first = queue[0]; + if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0) + return null; + return finishPoll(first); + } + + public int drainTo(Collection<? super Runnable> c) { + if (c == null) + throw new NullPointerException(); + if (c == this) + throw new IllegalArgumentException(); + final ReentrantLock lock = this.lock; + lock.lock(); + try { + RunnableScheduledFuture first; + int n = 0; + while ((first = pollExpired()) != null) { + c.add(first); + ++n; + } + return n; + } finally { + lock.unlock(); + } + } + + public int drainTo(Collection<? super Runnable> c, int maxElements) { + if (c == null) + throw new NullPointerException(); + if (c == this) + throw new IllegalArgumentException(); + if (maxElements <= 0) + return 0; + final ReentrantLock lock = this.lock; + lock.lock(); + try { + RunnableScheduledFuture first; + int n = 0; + while (n < maxElements && (first = pollExpired()) != null) { + c.add(first); + ++n; + } + return n; + } finally { + lock.unlock(); + } + } + + public Object[] toArray() { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + return Arrays.copyOf(queue, size, Object[].class); + } finally { + lock.unlock(); + } + } + + @SuppressWarnings("unchecked") + public <T> T[] toArray(T[] a) { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + if (a.length < size) + return (T[]) Arrays.copyOf(queue, size, a.getClass()); + System.arraycopy(queue, 0, a, 0, size); + if (a.length > size) + a[size] = null; + return a; + } finally { + lock.unlock(); + } + } + + public Iterator<Runnable> iterator() { + return new Itr(Arrays.copyOf(queue, size)); + } + + /** + * Snapshot iterator that works off copy of underlying q array. + */ + private class Itr implements Iterator<Runnable> { + final RunnableScheduledFuture[] array; + int cursor = 0; // index of next element to return + int lastRet = -1; // index of last element, or -1 if no such + + Itr(RunnableScheduledFuture[] array) { + this.array = array; + } + + public boolean hasNext() { + return cursor < array.length; + } + + public Runnable next() { + if (cursor >= array.length) + throw new NoSuchElementException(); + lastRet = cursor; + return array[cursor++]; + } + + public void remove() { + if (lastRet < 0) + throw new IllegalStateException(); + DelayedWorkQueue.this.remove(array[lastRet]); + lastRet = -1; + } + } + } + + // Duplicated package-private methods from ThreadPoolExecutor + + private static final int COUNT_BITS = Integer.SIZE - 3; + private static final int CAPACITY = (1 << COUNT_BITS) - 1; + private static final int TIDYING = 2 << COUNT_BITS; + private static final int SHUTDOWN = 0 << COUNT_BITS; + + // Packing and unpacking ctl + private static int runStateOf(int c) { return c & ~CAPACITY; } + private static int workerCountOf(int c) { return c & CAPACITY; } + + private static final boolean ONLY_ONE = true; + + /** + * Transitions to TERMINATED state if either (SHUTDOWN and pool + * and queue empty) or (STOP and pool empty). If otherwise + * eligible to terminate but workerCount is nonzero, interrupts an + * idle worker to ensure that shutdown signals propagate. This + * method must be called following any action that might make + * termination possible -- reducing worker count or removing tasks + * from the queue during shutdown. The method is non-private to + * allow access from ScheduledThreadPoolExecutor. + */ + private final void tryTerminateSTPE() { + final JavaUtilConcurrentThreadPoolExecutorAccess juctpea = + SharedSecrets.getJavaUtilConcurrentThreadPoolExecutorAccess(); + final AtomicInteger ctl = juctpea.getCtl(this); + for (;;) { + int c = ctl.get(); + if (isRunning(c) || + runStateAtLeast(c, TIDYING) || + (runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty())) + return; + if (workerCountOf(c) != 0) { // Eligible to terminate + interruptIdleWorkers(ONLY_ONE); + return; + } + + final ReentrantLock mainLock = juctpea.getMainLock(this); + mainLock.lock(); + try { + if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) { + try { + terminated(); + } finally { + ctl.set(ctlOf(TERMINATED, 0)); + juctpea.getTermination(this).signalAll(); + } + return; + } + } finally { + mainLock.unlock(); + } + // else retry on failed CAS + } + } + + /** + * State check needed by ScheduledThreadPoolExecutor to + * enable running tasks during shutdown. + * + * @param shutdownOK true if should return true if SHUTDOWN + */ + private final boolean isRunningOrShutdownSTPE(boolean shutdownOK) { + int rs = runStateOf(ctl.get()); + return rs == RUNNING || (rs == SHUTDOWN && shutdownOK); + } + + /** + * Invokes the rejected execution handler for the given command. + * Package-protected for use by ScheduledThreadPoolExecutor. + */ + private final void rejectSTPE(Runnable command) { + SharedSecrets.getJavaUtilConcurrentThreadPoolExecutorAccess().getHandler(this).rejectedExecution(command, this); + } + + private static boolean isRunning(int c) { + return c < SHUTDOWN; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/overlays/nio2/openjdk/jdk/src/share/classes/org/classpath/icedtea/misc/JavaUtilConcurrentThreadPoolExecutorAccess.java Wed Jan 14 05:27:57 2009 +0000 @@ -0,0 +1,55 @@ +/* JavaUtilConcurrentThreadPoolExecutorAccess.java + Copyright (C) 2009 Red Hat, Inc. + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 2. + +IcedTea 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 for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. + */ + +package org.classpath.icedtea.misc; + +import java.util.concurrent.RejectedExecutionHandler; +import java.util.concurrent.ThreadPoolExecutor; + +import java.util.concurrent.atomic.AtomicInteger; + +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +public interface JavaUtilConcurrentThreadPoolExecutorAccess +{ + AtomicInteger getCtl(ThreadPoolExecutor e); + ReentrantLock getMainLock(ThreadPoolExecutor e); + Condition getTermination(ThreadPoolExecutor e); + RejectedExecutionHandler getHandler(ThreadPoolExecutor e); +} +
--- a/overlays/nio2/openjdk/jdk/src/share/classes/sun/nio/ch/AbstractFuture.java Tue Jan 13 16:38:40 2009 +0000 +++ b/overlays/nio2/openjdk/jdk/src/share/classes/sun/nio/ch/AbstractFuture.java Wed Jan 14 05:27:57 2009 +0000 @@ -25,9 +25,10 @@ package sun.nio.ch; -import java.nio.channels.AsynchronousChannel; import java.util.concurrent.Future; +import org.classpath.icedtea.java.nio.channels.AsynchronousChannel; + /** * Base implementation of Future used for asynchronous I/O */
--- a/overlays/nio2/openjdk/jdk/src/solaris/classes/sun/nio/ch/DefaultAsynchronousChannelProvider.java Tue Jan 13 16:38:40 2009 +0000 +++ b/overlays/nio2/openjdk/jdk/src/solaris/classes/sun/nio/ch/DefaultAsynchronousChannelProvider.java Wed Jan 14 05:27:57 2009 +0000 @@ -25,10 +25,11 @@ package sun.nio.ch; -import java.nio.channels.spi.AsynchronousChannelProvider; import java.security.AccessController; import sun.security.action.GetPropertyAction; +import org.classpath.icedtea.java.nio.channels.spi.AsynchronousChannelProvider; + /** * Creates this platform's default asynchronous channel provider */
--- a/overlays/nio2/openjdk/jdk/src/solaris/classes/sun/nio/fs/DefaultFileSystemProvider.java Tue Jan 13 16:38:40 2009 +0000 +++ b/overlays/nio2/openjdk/jdk/src/solaris/classes/sun/nio/fs/DefaultFileSystemProvider.java Wed Jan 14 05:27:57 2009 +0000 @@ -25,11 +25,12 @@ package sun.nio.fs; -import java.nio.file.spi.FileSystemProvider; import java.security.AccessController; import java.security.PrivilegedAction; import sun.security.action.GetPropertyAction; +import org.classpath.icedtea.java.nio.file.spi.FileSystemProvider; + /** * Creates this platform's default FileSystemProvider. */
--- a/overlays/nio2/openjdk/jdk/src/solaris/classes/sun/nio/fs/DefaultFileTypeDetector.java Tue Jan 13 16:38:40 2009 +0000 +++ b/overlays/nio2/openjdk/jdk/src/solaris/classes/sun/nio/fs/DefaultFileTypeDetector.java Wed Jan 14 05:27:57 2009 +0000 @@ -25,7 +25,7 @@ package sun.nio.fs; -import java.nio.file.spi.FileTypeDetector; +import org.classpath.icedtea.java.nio.file.spi.FileTypeDetector; public class DefaultFileTypeDetector { private DefaultFileTypeDetector() { }
--- a/overlays/nio2/openjdk/jdk/src/solaris/classes/sun/nio/fs/UnixFileSystem.java Tue Jan 13 16:38:40 2009 +0000 +++ b/overlays/nio2/openjdk/jdk/src/solaris/classes/sun/nio/fs/UnixFileSystem.java Wed Jan 14 05:27:57 2009 +0000 @@ -33,6 +33,7 @@ import sun.security.action.GetBooleanAction; import org.classpath.icedtea.java.nio.file.FileStore; +import org.classpath.icedtea.java.nio.file.FileSystem; import org.classpath.icedtea.java.nio.file.attribute.UserPrincipal; import org.classpath.icedtea.java.nio.file.spi.FileSystemProvider;
--- a/patches/icedtea-nio2.patch Tue Jan 13 16:38:40 2009 +0000 +++ b/patches/icedtea-nio2.patch Wed Jan 14 05:27:57 2009 +0000 @@ -52,7 +52,7 @@ FILES_java = $(JAVA_JAVA_java) diff -Nru openjdk.orig/jdk/make/java/nio/FILES_java.gmk openjdk/jdk/make/java/nio/FILES_java.gmk --- openjdk.orig/jdk/make/java/nio/FILES_java.gmk 2009-01-10 03:21:38.000000000 +0000 -+++ openjdk/jdk/make/java/nio/FILES_java.gmk 2009-01-13 12:44:37.000000000 +0000 ++++ openjdk/jdk/make/java/nio/FILES_java.gmk 2009-01-14 01:49:10.000000000 +0000 @@ -75,7 +75,6 @@ sun/nio/ch/DefaultSelectorProvider.java \ sun/nio/ch/DirectBuffer.java \ @@ -61,7 +61,7 @@ sun/nio/ch/FileKey.java \ sun/nio/ch/Interruptible.java \ sun/nio/ch/IOUtil.java \ -@@ -144,7 +143,138 @@ +@@ -144,7 +143,147 @@ java/lang/StringCoding.java \ \ sun/misc/Cleaner.java \ @@ -70,6 +70,8 @@ + \ + org/classpath/icedtea/java/net/ProtocolFamily.java \ + org/classpath/icedtea/java/net/SocketOption.java \ ++ org/classpath/icedtea/java/net/StandardProtocolFamily.java \ ++ org/classpath/icedtea/java/net/StandardSocketOption.java \ + org/classpath/icedtea/java/nio/channels/AsynchronousByteChannel.java \ + org/classpath/icedtea/java/nio/channels/AsynchronousChannel.java \ + org/classpath/icedtea/java/nio/channels/AsynchronousChannelGroup.java \ @@ -77,7 +79,10 @@ + org/classpath/icedtea/java/nio/channels/AsynchronousFileChannel.java \ + org/classpath/icedtea/java/nio/channels/AsynchronousServerSocketChannel.java \ + org/classpath/icedtea/java/nio/channels/AsynchronousSocketChannel.java \ ++ org/classpath/icedtea/java/nio/channels/Channels.java \ + org/classpath/icedtea/java/nio/channels/CompletionHandler.java \ ++ org/classpath/icedtea/java/nio/channels/FileChannel.java \ ++ org/classpath/icedtea/java/nio/channels/FileLock.java \ + org/classpath/icedtea/java/nio/channels/MembershipKey.java \ + org/classpath/icedtea/java/nio/channels/MulticastChannel.java \ + org/classpath/icedtea/java/nio/channels/NetworkChannel.java \ @@ -160,6 +165,10 @@ + org/classpath/icedtea/java/nio/file/spi/FileSystemProvider.java \ + org/classpath/icedtea/java/nio/file/spi/FileTypeDetector.java \ + \ ++ org/classpath/icedtea/java/util/concurrent/ScheduledThreadPoolExecutor.java \ ++ \ ++ org/classpath/icedtea/misc/JavaUtilConcurrentThreadPoolExecutorAccess.java \ ++ \ + com/sun/nio/file/ExtendedCopyOption.java \ + com/sun/nio/file/ExtendedOpenOption.java \ + com/sun/nio/file/ExtendedWatchEventModifier.java \ @@ -201,7 +210,7 @@ # Generated coder classes # -@@ -263,7 +393,14 @@ +@@ -263,7 +402,14 @@ \ java/nio/charset/CharacterCodingException.java \ java/nio/charset/IllegalCharsetNameException.java \ @@ -753,6 +762,26 @@ } +diff -Nru openjdk.orig/jdk/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java openjdk/jdk/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java +--- openjdk.orig/jdk/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java 2009-01-13 23:54:13.000000000 +0000 ++++ openjdk/jdk/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java 2009-01-14 01:30:11.000000000 +0000 +@@ -2004,4 +2004,16 @@ + } + } + } ++ ++ static { ++ org.classpath.icedtea.misc.SharedSecrets.setJavaUtilConcurrentThreadPoolExecutorAccess( ++ new org.classpath.icedtea.misc.JavaUtilConcurrentThreadPoolExecutorAccess() { ++ public AtomicInteger getCtl(ThreadPoolExecutor e) { return e.ctl; } ++ public ReentrantLock getMainLock(ThreadPoolExecutor e) { return e.mainLock; } ++ public Condition getTermination(ThreadPoolExecutor e) { return e.termination; } ++ public RejectedExecutionHandler getHandler(ThreadPoolExecutor e) { return e.handler; } ++ } ++ ); ++ } ++ + } diff -Nru openjdk.orig/jdk/src/share/classes/sun/security/util/SecurityConstants.java openjdk/jdk/src/share/classes/sun/security/util/SecurityConstants.java --- openjdk.orig/jdk/src/share/classes/sun/security/util/SecurityConstants.java 2009-01-12 17:45:26.000000000 +0000 +++ openjdk/jdk/src/share/classes/sun/security/util/SecurityConstants.java 2009-01-12 17:45:39.000000000 +0000