Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/windows/classes/java/net/TwoStacksPlainSocketImpl.java
32287 views
/*1* Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/24package java.net;2526import java.io.IOException;27import java.io.FileDescriptor;28import sun.net.ResourceManager;2930/*31* This class defines the plain SocketImpl that is used for all32* Windows version lower than Vista. It adds support for IPv6 on33* these platforms where available.34*35* For backward compatibility Windows platforms that do not have IPv636* support also use this implementation, and fd1 gets set to null37* during socket creation.38*39* @author Chris Hegarty40*/4142class TwoStacksPlainSocketImpl extends AbstractPlainSocketImpl43{44/* second fd, used for ipv6 on windows only.45* fd1 is used for listeners and for client sockets at initialization46* until the socket is connected. Up to this point fd always refers47* to the ipv4 socket and fd1 to the ipv6 socket. After the socket48* becomes connected, fd always refers to the connected socket49* (either v4 or v6) and fd1 is closed.50*51* For ServerSockets, fd always refers to the v4 listener and52* fd1 the v6 listener.53*/54private FileDescriptor fd1;5556/*57* Needed for ipv6 on windows because we need to know58* if the socket is bound to ::0 or 0.0.0.0, when a caller59* asks for it. Otherwise we don't know which socket to ask.60*/61private InetAddress anyLocalBoundAddr = null;6263/* to prevent starvation when listening on two sockets, this is64* is used to hold the id of the last socket we accepted on.65*/66private int lastfd = -1;6768// true if this socket is exclusively bound69private final boolean exclusiveBind;7071// emulates SO_REUSEADDR when exclusiveBind is true72private boolean isReuseAddress;7374static {75initProto();76}7778public TwoStacksPlainSocketImpl(boolean exclBind) {79exclusiveBind = exclBind;80}8182public TwoStacksPlainSocketImpl(FileDescriptor fd, boolean exclBind) {83this.fd = fd;84exclusiveBind = exclBind;85}8687/**88* Creates a socket with a boolean that specifies whether this89* is a stream socket (true) or an unconnected UDP socket (false).90*/91protected synchronized void create(boolean stream) throws IOException {92fd1 = new FileDescriptor();93try {94super.create(stream);95} catch (IOException e) {96fd1 = null;97throw e;98}99}100101/**102* Binds the socket to the specified address of the specified local port.103* @param address the address104* @param port the port105*/106protected synchronized void bind(InetAddress address, int lport)107throws IOException108{109super.bind(address, lport);110if (address.isAnyLocalAddress()) {111anyLocalBoundAddr = address;112}113}114115public Object getOption(int opt) throws SocketException {116if (isClosedOrPending()) {117throw new SocketException("Socket Closed");118}119if (opt == SO_BINDADDR) {120if (fd != null && fd1 != null ) {121/* must be unbound or else bound to anyLocal */122return anyLocalBoundAddr;123}124InetAddressContainer in = new InetAddressContainer();125socketGetOption(opt, in);126return in.addr;127} else if (opt == SO_REUSEADDR && exclusiveBind) {128// SO_REUSEADDR emulated when using exclusive bind129return isReuseAddress;130} else131return super.getOption(opt);132}133134@Override135void socketBind(InetAddress address, int port) throws IOException {136socketBind(address, port, exclusiveBind);137}138139@Override140void socketSetOption(int opt, boolean on, Object value)141throws SocketException142{143// SO_REUSEADDR emulated when using exclusive bind144if (opt == SO_REUSEADDR && exclusiveBind)145isReuseAddress = on;146else147socketNativeSetOption(opt, on, value);148}149150/**151* Closes the socket.152*/153@Override154protected void close() throws IOException {155synchronized(fdLock) {156if (fd != null || fd1 != null) {157if (!stream) {158ResourceManager.afterUdpClose();159}160if (fdUseCount == 0) {161if (closePending) {162return;163}164closePending = true;165socketClose();166fd = null;167fd1 = null;168return;169} else {170/*171* If a thread has acquired the fd and a close172* isn't pending then use a deferred close.173* Also decrement fdUseCount to signal the last174* thread that releases the fd to close it.175*/176if (!closePending) {177closePending = true;178fdUseCount--;179socketClose();180}181}182}183}184}185186@Override187void reset() throws IOException {188if (fd != null || fd1 != null) {189socketClose();190}191fd = null;192fd1 = null;193super.reset();194}195196/*197* Return true if already closed or close is pending198*/199@Override200public boolean isClosedOrPending() {201/*202* Lock on fdLock to ensure that we wait if a203* close is in progress.204*/205synchronized (fdLock) {206if (closePending || (fd == null && fd1 == null)) {207return true;208} else {209return false;210}211}212}213214/* Native methods */215216static native void initProto();217218native void socketCreate(boolean isServer) throws IOException;219220native void socketConnect(InetAddress address, int port, int timeout)221throws IOException;222223native void socketBind(InetAddress address, int port, boolean exclBind)224throws IOException;225226native void socketListen(int count) throws IOException;227228native void socketAccept(SocketImpl s) throws IOException;229230native int socketAvailable() throws IOException;231232native void socketClose0(boolean useDeferredClose) throws IOException;233234native void socketShutdown(int howto) throws IOException;235236native void socketNativeSetOption(int cmd, boolean on, Object value)237throws SocketException;238239native int socketGetOption(int opt, Object iaContainerObj) throws SocketException;240241native void socketSendUrgentData(int data) throws IOException;242}243244245