151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/*
22c87ad3a45cecf9e344487cad1abfdebe79f2c7cNarayan Kamath * Copyright (C) 2014 The Android Open Source Project
3519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it
751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as
851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation.  Oracle designates this
951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided
1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code.
1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT
1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that
1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code).
1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version
1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation,
2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any
2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions.
2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */
2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage sun.nio.ch;
2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.FileDescriptor;
3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.IOException;
315ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.net.InetAddress;
325ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.net.InetSocketAddress;
335ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.net.ProtocolFamily;
345ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.net.Socket;
355ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.net.SocketAddress;
365ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.net.SocketOption;
375ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.net.StandardProtocolFamily;
385ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.net.StandardSocketOptions;
3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.nio.ByteBuffer;
405ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.nio.channels.AlreadyBoundException;
415ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.nio.channels.AlreadyConnectedException;
425ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.nio.channels.AsynchronousCloseException;
435ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.nio.channels.ClosedChannelException;
445ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.nio.channels.ConnectionPendingException;
455ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.nio.channels.NoConnectionPendingException;
465ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.nio.channels.NotYetConnectedException;
475ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.nio.channels.SelectionKey;
485ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.nio.channels.SocketChannel;
495ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.nio.channels.spi.SelectorProvider;
505ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.util.Collections;
515ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.util.HashSet;
525ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.util.Set;
531d568d5e72820f7e487a49e3c57dee4f1e7f14bcNarayan Kamath
54e31b37859051d3902e06e4ba384995df7188917fHans Boehmimport dalvik.annotation.optimization.ReachabilitySensitive;
551d568d5e72820f7e487a49e3c57dee4f1e7f14bcNarayan Kamathimport dalvik.system.BlockGuard;
565ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport dalvik.system.CloseGuard;
57e573e88e89daf5efb323719c54117c5a423eb245Yi Kongimport sun.net.ExtendedOptionsImpl;
585ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport sun.net.NetHooks;
5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
60519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera
6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/**
6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * An implementation of SocketChannels
6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */
6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiclass SocketChannelImpl
6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    extends SocketChannel
6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    implements SelChImpl
6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski{
6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // Used to make native read and write calls
7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static NativeDispatcher nd;
7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // Our file descriptor object
7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private final FileDescriptor fd;
7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // fd value needed for dev/poll. This value will remain valid
7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // even after the value in the file descriptor object has been set to -1
7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private final int fdVal;
7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // IDs of native threads doing reads and writes, for signalling
8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private volatile long readerThread = 0;
8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private volatile long writerThread = 0;
8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // Lock held by current reading or connecting thread
8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private final Object readLock = new Object();
8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // Lock held by current writing or connecting thread
8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private final Object writeLock = new Object();
8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // Lock held by any thread that modifies the state fields declared below
9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // DO NOT invoke a blocking I/O operation while holding this lock!
9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private final Object stateLock = new Object();
9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // -- The following fields are protected by stateLock
9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // set true when exclusive binding is on and SO_REUSEADDR is emulated
9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private boolean isReuseAddress;
9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // State, increases monotonically
10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static final int ST_UNINITIALIZED = -1;
10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static final int ST_UNCONNECTED = 0;
10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static final int ST_PENDING = 1;
10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static final int ST_CONNECTED = 2;
10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static final int ST_KILLPENDING = 3;
10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static final int ST_KILLED = 4;
10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private int state = ST_UNINITIALIZED;
10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // Binding
10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private InetSocketAddress localAddress;
11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private InetSocketAddress remoteAddress;
11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // Input/Output open
11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private boolean isInputOpen = true;
11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private boolean isOutputOpen = true;
11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private boolean readyToConnect = false;
11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // Socket adaptor, created on demand
11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private Socket socket;
11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // -- End of fields protected by stateLock
12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
122dd2c67a47dc742e19c6710ddd6e1b85f95dd1d1fNeil Fuller    // Android-added: CloseGuard support.
123e31b37859051d3902e06e4ba384995df7188917fHans Boehm    @ReachabilitySensitive
1245ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera    private final CloseGuard guard = CloseGuard.get();
12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // Constructor for normal connecting sockets
12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    //
12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    SocketChannelImpl(SelectorProvider sp) throws IOException {
12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        super(sp);
13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.fd = Net.socket(true);
13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.fdVal = IOUtil.fdVal(fd);
13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.state = ST_UNCONNECTED;
1335ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera
134dd2c67a47dc742e19c6710ddd6e1b85f95dd1d1fNeil Fuller        // Android-added: CloseGuard support.
1355ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera        // Net#socket will set |fd| if it succeeds.
1365ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera        if (fd != null && fd.valid()) {
1375ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera            guard.open("close");
1385ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera        }
13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    SocketChannelImpl(SelectorProvider sp,
14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                      FileDescriptor fd,
14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                      boolean bound)
14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        throws IOException
14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    {
14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        super(sp);
14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.fd = fd;
14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.fdVal = IOUtil.fdVal(fd);
14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.state = ST_UNCONNECTED;
1505ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera
151dd2c67a47dc742e19c6710ddd6e1b85f95dd1d1fNeil Fuller        // Android-added: CloseGuard support.
1525ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera        if (fd != null && fd.valid()) {
1535ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera            guard.open("close");
1545ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera        }
1555ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera
15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (bound)
15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            this.localAddress = Net.localAddress(fd);
15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // Constructor for sockets obtained from server sockets
16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    //
16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    SocketChannelImpl(SelectorProvider sp,
16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                      FileDescriptor fd, InetSocketAddress remote)
16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        throws IOException
16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    {
16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        super(sp);
16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.fd = fd;
16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.fdVal = IOUtil.fdVal(fd);
16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.state = ST_CONNECTED;
17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.localAddress = Net.localAddress(fd);
17151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.remoteAddress = remote;
172dd2c67a47dc742e19c6710ddd6e1b85f95dd1d1fNeil Fuller        // Android-added: CloseGuard support.
1735ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera        if (fd != null && fd.valid()) {
1745ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera            guard.open("close");
1755ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera        }
17651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
17751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
17851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public Socket socket() {
17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (stateLock) {
18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (socket == null)
18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                socket = SocketAdaptor.create(this);
18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return socket;
18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    @Override
18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public SocketAddress getLocalAddress() throws IOException {
18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (stateLock) {
18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (!isOpen())
19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                throw new ClosedChannelException();
19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return  Net.getRevealedLocalAddress(localAddress);
19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    @Override
19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public SocketAddress getRemoteAddress() throws IOException {
19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (stateLock) {
19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (!isOpen())
19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                throw new ClosedChannelException();
20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return remoteAddress;
20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
20351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    @Override
20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public <T> SocketChannel setOption(SocketOption<T> name, T value)
20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        throws IOException
20751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    {
20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (name == null)
20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new NullPointerException();
21051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (!supportedOptions().contains(name))
21151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new UnsupportedOperationException("'" + name + "' not supported");
21251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (stateLock) {
21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (!isOpen())
21551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                throw new ClosedChannelException();
21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
21751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (name == StandardSocketOptions.IP_TOS) {
218519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera                ProtocolFamily family = Net.isIPv6Available() ?
219519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera                    StandardProtocolFamily.INET6 : StandardProtocolFamily.INET;
220519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera                Net.setSocketOption(fd, family, name, value);
22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return this;
222519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera            }
223519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera
224519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera            if (name == StandardSocketOptions.SO_REUSEADDR && Net.useExclusiveBind()) {
22551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // SO_REUSEADDR emulated when using exclusive bind
22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                isReuseAddress = (Boolean)value;
22751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return this;
22851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
22951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
23051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // no options that require special handling
23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            Net.setSocketOption(fd, Net.UNSPEC, name, value);
23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return this;
23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
23451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
23551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
23651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    @Override
23751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    @SuppressWarnings("unchecked")
23851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public <T> T getOption(SocketOption<T> name)
23951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        throws IOException
24051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    {
24151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (name == null)
24251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new NullPointerException();
24351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (!supportedOptions().contains(name))
24451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new UnsupportedOperationException("'" + name + "' not supported");
24551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
24651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (stateLock) {
24751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (!isOpen())
24851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                throw new ClosedChannelException();
24951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
25051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (name == StandardSocketOptions.SO_REUSEADDR &&
25151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    Net.useExclusiveBind())
25251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            {
25351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // SO_REUSEADDR emulated when using exclusive bind
25451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return (T)Boolean.valueOf(isReuseAddress);
25551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
25651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
25751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // special handling for IP_TOS: always return 0 when IPv6
25851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (name == StandardSocketOptions.IP_TOS) {
259519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera                ProtocolFamily family = Net.isIPv6Available() ?
260519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera                    StandardProtocolFamily.INET6 : StandardProtocolFamily.INET;
261519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera                return (T) Net.getSocketOption(fd, family, name);
26251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
26351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
26451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // no options that require special handling
26551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return (T) Net.getSocketOption(fd, Net.UNSPEC, name);
26651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
26751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
26851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
26951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static class DefaultOptionsHolder {
27051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        static final Set<SocketOption<?>> defaultOptions = defaultOptions();
27151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
27251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        private static Set<SocketOption<?>> defaultOptions() {
27351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            HashSet<SocketOption<?>> set = new HashSet<SocketOption<?>>(8);
27451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            set.add(StandardSocketOptions.SO_SNDBUF);
27551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            set.add(StandardSocketOptions.SO_RCVBUF);
27651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            set.add(StandardSocketOptions.SO_KEEPALIVE);
27751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            set.add(StandardSocketOptions.SO_REUSEADDR);
27851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            set.add(StandardSocketOptions.SO_LINGER);
27951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            set.add(StandardSocketOptions.TCP_NODELAY);
28051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // additional options required by socket adaptor
28151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            set.add(StandardSocketOptions.IP_TOS);
28251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            set.add(ExtendedSocketOption.SO_OOBINLINE);
283e573e88e89daf5efb323719c54117c5a423eb245Yi Kong            if (ExtendedOptionsImpl.flowSupported()) {
284e573e88e89daf5efb323719c54117c5a423eb245Yi Kong                set.add(jdk.net.ExtendedSocketOptions.SO_FLOW_SLA);
285e573e88e89daf5efb323719c54117c5a423eb245Yi Kong            }
28651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return Collections.unmodifiableSet(set);
28751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
28851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
28951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
29051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    @Override
29151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public final Set<SocketOption<?>> supportedOptions() {
29251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return DefaultOptionsHolder.defaultOptions;
29351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
29451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
29551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private boolean ensureReadOpen() throws ClosedChannelException {
29651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (stateLock) {
29751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (!isOpen())
29851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                throw new ClosedChannelException();
29951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (!isConnected())
30051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                throw new NotYetConnectedException();
30151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (!isInputOpen)
30251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return false;
30351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            else
30451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return true;
30551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
30651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
30751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
30851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private void ensureWriteOpen() throws ClosedChannelException {
30951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (stateLock) {
31051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (!isOpen())
31151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                throw new ClosedChannelException();
31251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (!isOutputOpen)
31351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                throw new ClosedChannelException();
31451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (!isConnected())
31551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                throw new NotYetConnectedException();
31651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
31751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
31851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
31951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private void readerCleanup() throws IOException {
32051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (stateLock) {
32151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            readerThread = 0;
32251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (state == ST_KILLPENDING)
32351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                kill();
32451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
32551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
32651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
32751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private void writerCleanup() throws IOException {
32851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (stateLock) {
32951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            writerThread = 0;
33051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (state == ST_KILLPENDING)
33151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                kill();
33251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
33351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
33451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
33551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public int read(ByteBuffer buf) throws IOException {
33651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
33751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (buf == null)
33851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new NullPointerException();
33951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
34051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (readLock) {
34151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (!ensureReadOpen())
34251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return -1;
34351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            int n = 0;
34451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            try {
34551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
34651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // Set up the interruption machinery; see
34751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // AbstractInterruptibleChannel for details
34851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                //
34951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                begin();
35051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
35151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                synchronized (stateLock) {
35251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (!isOpen()) {
35351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // Either the current thread is already interrupted, so
35451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // begin() closed the channel, or another thread closed the
35551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // channel since we checked it a few bytecodes ago.  In
35651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // either case the value returned here is irrelevant since
35751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // the invocation of end() in the finally block will throw
35851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // an appropriate exception.
35951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    //
36051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        return 0;
36151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
36251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
36351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
36451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // Save this thread so that it can be signalled on those
36551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // platforms that require it
36651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    //
36751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    readerThread = NativeThread.current();
36851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
36951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
37051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // Between the previous test of isOpen() and the return of the
37151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // IOUtil.read invocation below, this channel might be closed
37251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // or this thread might be interrupted.  We rely upon the
37351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // implicit synchronization point in the kernel read() call to
37451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // make sure that the right thing happens.  In either case the
37551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // implCloseSelectableChannel method is ultimately invoked in
37651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // some other thread, so there are three possibilities:
37751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                //
37851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                //   - implCloseSelectableChannel() invokes nd.preClose()
37951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                //     before this thread invokes read(), in which case the
38051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                //     read returns immediately with either EOF or an error,
38151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                //     the latter of which will cause an IOException to be
38251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                //     thrown.
38351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                //
38451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                //   - implCloseSelectableChannel() invokes nd.preClose() after
38551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                //     this thread is blocked in read().  On some operating
38651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                //     systems (e.g., Solaris and Windows) this causes the read
38751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                //     to return immediately with either EOF or an error
38851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                //     indication.
38951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                //
39051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                //   - implCloseSelectableChannel() invokes nd.preClose() after
39151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                //     this thread is blocked in read() but the operating
39251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                //     system (e.g., Linux) doesn't support preemptive close,
39351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                //     so implCloseSelectableChannel() proceeds to signal this
39451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                //     thread, thereby causing the read to return immediately
39551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                //     with IOStatus.INTERRUPTED.
39651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                //
39751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // In all three cases the invocation of end() in the finally
39851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // clause will notice that the channel has been closed and
39951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // throw an appropriate exception (AsynchronousCloseException
40051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // or ClosedByInterruptException) if necessary.
40151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                //
40251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // *There is A fourth possibility. implCloseSelectableChannel()
40351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // invokes nd.preClose(), signals reader/writer thred and quickly
40451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // moves on to nd.close() in kill(), which does a real close.
40551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // Then a third thread accepts a new connection, opens file or
40651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // whatever that causes the released "fd" to be recycled. All
40751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // above happens just between our last isOpen() check and the
40851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // next kernel read reached, with the recycled "fd". The solution
40951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // is to postpone the real kill() if there is a reader or/and
41051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // writer thread(s) over there "waiting", leave the cleanup/kill
41151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // to the reader or writer thread. (the preClose() still happens
41251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // so the connection gets cut off as usual).
41351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                //
41451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // For socket channels there is the additional wrinkle that
41551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // asynchronous shutdown works much like asynchronous close,
41651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // except that the channel is shutdown rather than completely
41751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // closed.  This is analogous to the first two cases above,
41851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // except that the shutdown operation plays the role of
41951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // nd.preClose().
42051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                for (;;) {
42151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    n = IOUtil.read(fd, buf, -1, nd);
42251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ((n == IOStatus.INTERRUPTED) && isOpen()) {
42351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // The system call was interrupted but the channel
42451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // is still open, so retry
42551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        continue;
42651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
42751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    return IOStatus.normalize(n);
42851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
42951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
43051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } finally {
43151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                readerCleanup();        // Clear reader thread
43251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // The end method, which is defined in our superclass
43351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // AbstractInterruptibleChannel, resets the interruption
43451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // machinery.  If its argument is true then it returns
43551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // normally; otherwise it checks the interrupt and open state
43651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // of this channel and throws an appropriate exception if
43751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // necessary.
43851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                //
43951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // So, if we actually managed to do any I/O in the above try
44051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // block then we pass true to the end method.  We also pass
44151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // true if the channel was in non-blocking mode when the I/O
44251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // operation was initiated but no data could be transferred;
44351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // this prevents spurious exceptions from being thrown in the
44451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // rare event that a channel is closed or a thread is
44551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // interrupted at the exact moment that a non-blocking I/O
44651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // request is made.
44751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                //
44851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                end(n > 0 || (n == IOStatus.UNAVAILABLE));
44951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
45051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // Extra case for socket channels: Asynchronous shutdown
45151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                //
45251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                synchronized (stateLock) {
45351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ((n <= 0) && (!isInputOpen))
45451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        return IOStatus.EOF;
45551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
45651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
45751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                assert IOStatus.check(n);
45851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
45951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
46051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
46151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
46251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
46351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public long read(ByteBuffer[] dsts, int offset, int length)
46451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        throws IOException
46551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    {
46651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ((offset < 0) || (length < 0) || (offset > dsts.length - length))
46751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new IndexOutOfBoundsException();
46851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (readLock) {
46951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (!ensureReadOpen())
47051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return -1;
47151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            long n = 0;
47251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            try {
47351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                begin();
47451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                synchronized (stateLock) {
47551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (!isOpen())
47651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        return 0;
47751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    readerThread = NativeThread.current();
47851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
47951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
48051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                for (;;) {
48151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    n = IOUtil.read(fd, dsts, offset, length, nd);
48251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ((n == IOStatus.INTERRUPTED) && isOpen())
48351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        continue;
48451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    return IOStatus.normalize(n);
48551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
48651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } finally {
48751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                readerCleanup();
48851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                end(n > 0 || (n == IOStatus.UNAVAILABLE));
48951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                synchronized (stateLock) {
49051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ((n <= 0) && (!isInputOpen))
49151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        return IOStatus.EOF;
49251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
49351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                assert IOStatus.check(n);
49451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
49551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
49651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
49751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
49851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public int write(ByteBuffer buf) throws IOException {
49951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (buf == null)
50051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new NullPointerException();
50151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (writeLock) {
50251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            ensureWriteOpen();
50351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            int n = 0;
50451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            try {
50551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                begin();
50651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                synchronized (stateLock) {
50751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (!isOpen())
50851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        return 0;
50951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    writerThread = NativeThread.current();
51051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
51151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                for (;;) {
51251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    n = IOUtil.write(fd, buf, -1, nd);
51351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ((n == IOStatus.INTERRUPTED) && isOpen())
51451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        continue;
51551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    return IOStatus.normalize(n);
51651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
51751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } finally {
51851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                writerCleanup();
51951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                end(n > 0 || (n == IOStatus.UNAVAILABLE));
52051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                synchronized (stateLock) {
52151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ((n <= 0) && (!isOutputOpen))
52251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        throw new AsynchronousCloseException();
52351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
52451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                assert IOStatus.check(n);
52551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
52651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
52751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
52851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
52951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public long write(ByteBuffer[] srcs, int offset, int length)
53051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        throws IOException
53151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    {
53251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ((offset < 0) || (length < 0) || (offset > srcs.length - length))
53351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new IndexOutOfBoundsException();
53451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (writeLock) {
53551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            ensureWriteOpen();
53651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            long n = 0;
53751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            try {
53851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                begin();
53951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                synchronized (stateLock) {
54051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (!isOpen())
54151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        return 0;
54251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    writerThread = NativeThread.current();
54351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
54451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                for (;;) {
54551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    n = IOUtil.write(fd, srcs, offset, length, nd);
54651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ((n == IOStatus.INTERRUPTED) && isOpen())
54751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        continue;
54851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    return IOStatus.normalize(n);
54951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
55051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } finally {
55151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                writerCleanup();
55251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                end((n > 0) || (n == IOStatus.UNAVAILABLE));
55351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                synchronized (stateLock) {
55451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ((n <= 0) && (!isOutputOpen))
55551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        throw new AsynchronousCloseException();
55651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
55751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                assert IOStatus.check(n);
55851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
55951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
56051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
56151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
56251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // package-private
56351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    int sendOutOfBandData(byte b) throws IOException {
56451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (writeLock) {
56551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            ensureWriteOpen();
56651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            int n = 0;
56751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            try {
56851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                begin();
56951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                synchronized (stateLock) {
57051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (!isOpen())
57151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        return 0;
57251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    writerThread = NativeThread.current();
57351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
57451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                for (;;) {
57551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    n = sendOutOfBandData(fd, b);
57651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ((n == IOStatus.INTERRUPTED) && isOpen())
57751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        continue;
57851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    return IOStatus.normalize(n);
57951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
58051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } finally {
58151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                writerCleanup();
58251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                end((n > 0) || (n == IOStatus.UNAVAILABLE));
58351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                synchronized (stateLock) {
58451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ((n <= 0) && (!isOutputOpen))
58551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        throw new AsynchronousCloseException();
58651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
58751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                assert IOStatus.check(n);
58851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
58951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
59051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
59151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
59251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    protected void implConfigureBlocking(boolean block) throws IOException {
59351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        IOUtil.configureBlocking(fd, block);
59451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
59551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
59651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public InetSocketAddress localAddress() {
59751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (stateLock) {
59851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return localAddress;
59951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
60051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
60151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
60251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public SocketAddress remoteAddress() {
60351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (stateLock) {
60451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return remoteAddress;
60551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
60651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
60751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
60851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    @Override
60951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public SocketChannel bind(SocketAddress local) throws IOException {
61051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (readLock) {
61151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            synchronized (writeLock) {
61251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                synchronized (stateLock) {
61351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (!isOpen())
61451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        throw new ClosedChannelException();
61551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (state == ST_PENDING)
61651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        throw new ConnectionPendingException();
61751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (localAddress != null)
61851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        throw new AlreadyBoundException();
61951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    InetSocketAddress isa = (local == null) ?
62051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        new InetSocketAddress(0) : Net.checkAddress(local);
621519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera                    SecurityManager sm = System.getSecurityManager();
622519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera                    if (sm != null) {
623519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera                        sm.checkListen(isa.getPort());
624519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera                    }
62551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    NetHooks.beforeTcpBind(fd, isa.getAddress(), isa.getPort());
62651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    Net.bind(fd, isa.getAddress(), isa.getPort());
62751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    localAddress = Net.localAddress(fd);
62851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
62951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
63051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
63151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return this;
63251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
63351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
63451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public boolean isConnected() {
63551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (stateLock) {
63651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return (state == ST_CONNECTED);
63751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
63851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
63951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
64051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public boolean isConnectionPending() {
64151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (stateLock) {
64251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return (state == ST_PENDING);
64351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
64451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
64551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
64651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    void ensureOpenAndUnconnected() throws IOException { // package-private
64751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (stateLock) {
64851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (!isOpen())
64951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                throw new ClosedChannelException();
65051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (state == ST_CONNECTED)
65151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                throw new AlreadyConnectedException();
65251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (state == ST_PENDING)
65351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                throw new ConnectionPendingException();
65451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
65551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
65651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
65751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public boolean connect(SocketAddress sa) throws IOException {
65851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int localPort = 0;
65951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
66051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (readLock) {
66151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            synchronized (writeLock) {
66251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                ensureOpenAndUnconnected();
66351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                InetSocketAddress isa = Net.checkAddress(sa);
66451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                SecurityManager sm = System.getSecurityManager();
66551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (sm != null)
66651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    sm.checkConnect(isa.getAddress().getHostAddress(),
66751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                    isa.getPort());
66851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                synchronized (blockingLock()) {
66951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    int n = 0;
67051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    try {
67151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        try {
67251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            begin();
67351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            synchronized (stateLock) {
67451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                if (!isOpen()) {
67551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                    return false;
67651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                }
67751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                // notify hook only if unbound
67851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                if (localAddress == null) {
67951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                    NetHooks.beforeTcpConnect(fd,
68051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                                           isa.getAddress(),
68151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                                           isa.getPort());
68251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                }
68351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                readerThread = NativeThread.current();
68451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            }
68551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            for (;;) {
68651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                InetAddress ia = isa.getAddress();
68751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                if (ia.isAnyLocalAddress())
68851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                    ia = InetAddress.getLocalHost();
68951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                n = Net.connect(fd,
69051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                                ia,
69151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                                isa.getPort());
69251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                if (  (n == IOStatus.INTERRUPTED)
69351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                      && isOpen())
69451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                    continue;
69551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                break;
69651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            }
69751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
69851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        } finally {
69951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            readerCleanup();
70051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            end((n > 0) || (n == IOStatus.UNAVAILABLE));
70151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            assert IOStatus.check(n);
70251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
70351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    } catch (IOException x) {
70451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // If an exception was thrown, close the channel after
70551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // invoking end() so as to avoid bogus
70651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // AsynchronousCloseExceptions
70751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        close();
70851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        throw x;
70951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
71051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    synchronized (stateLock) {
71151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        remoteAddress = isa;
71251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        if (n > 0) {
71351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
71451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            // Connection succeeded; disallow further
71551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            // invocation
71651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            state = ST_CONNECTED;
71751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            if (isOpen())
71851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                localAddress = Net.localAddress(fd);
71951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            return true;
72051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
72151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // If nonblocking and no exception then connection
72251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // pending; disallow another invocation
7232e1995a729cb8d836159444d61427d4d0ef0b45fNarayan Kamath                        if (!isBlocking()) {
72451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            state = ST_PENDING;
7252e1995a729cb8d836159444d61427d4d0ef0b45fNarayan Kamath                            if (isOpen()) {
7262e1995a729cb8d836159444d61427d4d0ef0b45fNarayan Kamath                                localAddress = Net.localAddress(fd);
7272e1995a729cb8d836159444d61427d4d0ef0b45fNarayan Kamath                            }
7282e1995a729cb8d836159444d61427d4d0ef0b45fNarayan Kamath                        }
72951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
73051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
73151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return false;
73251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
73351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
73451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
73551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
73651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public boolean finishConnect() throws IOException {
73751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (readLock) {
73851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            synchronized (writeLock) {
73951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                synchronized (stateLock) {
74051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (!isOpen())
74151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        throw new ClosedChannelException();
74251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (state == ST_CONNECTED)
74351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        return true;
74451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (state != ST_PENDING)
74551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        throw new NoConnectionPendingException();
74651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
74751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                int n = 0;
74851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                try {
74951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    try {
75051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        begin();
75151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        synchronized (blockingLock()) {
75251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            synchronized (stateLock) {
75351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                if (!isOpen()) {
75451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                    return false;
75551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                }
75651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                readerThread = NativeThread.current();
75751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            }
7581d568d5e72820f7e487a49e3c57dee4f1e7f14bcNarayan Kamath
7591d568d5e72820f7e487a49e3c57dee4f1e7f14bcNarayan Kamath                            BlockGuard.getThreadPolicy().onNetwork();
76051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            if (!isBlocking()) {
76151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                for (;;) {
76251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                    n = checkConnect(fd, false,
76351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                                     readyToConnect);
76451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                    if (  (n == IOStatus.INTERRUPTED)
76551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                          && isOpen())
76651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                        continue;
76751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                    break;
76851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                }
76951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            } else {
77051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                for (;;) {
77151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                    n = checkConnect(fd, true,
77251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                                     readyToConnect);
77351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                    if (n == 0) {
77451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                        // Loop in case of
77551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                        // spurious notifications
77651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                        continue;
77751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                    }
77851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                    if (  (n == IOStatus.INTERRUPTED)
77951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                          && isOpen())
78051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                        continue;
78151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                    break;
78251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                }
78351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            }
78451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
78551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    } finally {
78651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        synchronized (stateLock) {
78751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            readerThread = 0;
78851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            if (state == ST_KILLPENDING) {
78951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                kill();
79051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                // poll()/getsockopt() does not report
79151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                // error (throws exception, with n = 0)
79251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                // on Linux platform after dup2 and
79351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                // signal-wakeup. Force n to 0 so the
79451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                // end() can throw appropriate exception
79551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                n = 0;
79651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            }
79751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
79851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        end((n > 0) || (n == IOStatus.UNAVAILABLE));
79951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        assert IOStatus.check(n);
80051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
80151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } catch (IOException x) {
80251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // If an exception was thrown, close the channel after
80351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // invoking end() so as to avoid bogus
80451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // AsynchronousCloseExceptions
80551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    close();
80651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    throw x;
80751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
80851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (n > 0) {
80951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    synchronized (stateLock) {
81051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        state = ST_CONNECTED;
81151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        if (isOpen())
81251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            localAddress = Net.localAddress(fd);
81351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
81451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    return true;
81551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
81651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return false;
81751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
81851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
81951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
82051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
82151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    @Override
82251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public SocketChannel shutdownInput() throws IOException {
82351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (stateLock) {
82451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (!isOpen())
82551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                throw new ClosedChannelException();
82651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (!isConnected())
82751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                throw new NotYetConnectedException();
82851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (isInputOpen) {
82951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                Net.shutdown(fd, Net.SHUT_RD);
83051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (readerThread != 0)
83151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    NativeThread.signal(readerThread);
83251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                isInputOpen = false;
83351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
83451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return this;
83551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
83651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
83751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
83851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    @Override
83951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public SocketChannel shutdownOutput() throws IOException {
84051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (stateLock) {
84151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (!isOpen())
84251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                throw new ClosedChannelException();
84351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (!isConnected())
84451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                throw new NotYetConnectedException();
84551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (isOutputOpen) {
84651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                Net.shutdown(fd, Net.SHUT_WR);
84751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (writerThread != 0)
84851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    NativeThread.signal(writerThread);
84951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                isOutputOpen = false;
85051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
85151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return this;
85251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
85351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
85451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
85551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public boolean isInputOpen() {
85651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (stateLock) {
85751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return isInputOpen;
85851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
85951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
86051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
86151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public boolean isOutputOpen() {
86251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (stateLock) {
86351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return isOutputOpen;
86451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
86551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
86651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
86751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // AbstractInterruptibleChannel synchronizes invocations of this method
86851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // using AbstractInterruptibleChannel.closeLock, and also ensures that this
86951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // method is only ever invoked once.  Before we get to this method, isOpen
87051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // (which is volatile) will have been set to false.
87151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    //
87251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    protected void implCloseSelectableChannel() throws IOException {
87351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (stateLock) {
87451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            isInputOpen = false;
87551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            isOutputOpen = false;
87651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
87751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // Close the underlying file descriptor and dup it to a known fd
87851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // that's already closed.  This prevents other operations on this
87951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // channel from using the old fd, which might be recycled in the
88051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // meantime and allocated to an entirely different channel.
88151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            //
8825ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera            if (state != ST_KILLED) {
883dd2c67a47dc742e19c6710ddd6e1b85f95dd1d1fNeil Fuller                // Android-added: CloseGuard support.
8845ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera                guard.close();
88551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                nd.preClose(fd);
8865ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera            }
88751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
88851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // Signal native threads, if needed.  If a target thread is not
88951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // currently blocked in an I/O operation then no harm is done since
89051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // the signal handler doesn't actually do anything.
89151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            //
89251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (readerThread != 0)
89351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                NativeThread.signal(readerThread);
89451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
89551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (writerThread != 0)
89651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                NativeThread.signal(writerThread);
89751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
89851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // If this channel is not registered then it's safe to close the fd
89951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // immediately since we know at this point that no thread is
90051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // blocked in an I/O operation upon the channel and, since the
90151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // channel is marked closed, no thread will start another such
90251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // operation.  If this channel is registered then we don't close
90351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // the fd since it might be in use by a selector.  In that case
90451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // closing this channel caused its keys to be cancelled, so the
90551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // last selector to deregister a key for this channel will invoke
90651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // kill() to close the fd.
90751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            //
90851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (!isRegistered())
90951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                kill();
91051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
91151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
91251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
91351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void kill() throws IOException {
91451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (stateLock) {
91551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (state == ST_KILLED)
91651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return;
91751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (state == ST_UNINITIALIZED) {
91851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                state = ST_KILLED;
91951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return;
92051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
92151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            assert !isOpen() && !isRegistered();
92251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
92351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // Postpone the kill if there is a waiting reader
92451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // or writer thread. See the comments in read() for
92551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // more detailed explanation.
92651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (readerThread == 0 && writerThread == 0) {
92751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                nd.close(fd);
92851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                state = ST_KILLED;
92951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else {
93051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                state = ST_KILLPENDING;
93151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
93251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
93351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
93451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
9355ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera    protected void finalize() throws IOException {
9365ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera        if (guard != null) {
9375ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera            guard.warnIfOpen();
9385ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera        }
9395ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera        close();
9405ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera    }
9415ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera
94251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
94351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Translates native poll revent ops into a ready operation ops
94451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
94551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public boolean translateReadyOps(int ops, int initialOps,
94651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                     SelectionKeyImpl sk) {
94751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int intOps = sk.nioInterestOps(); // Do this just once, it synchronizes
94851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int oldOps = sk.nioReadyOps();
94951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int newOps = initialOps;
95051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
951519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera        if ((ops & Net.POLLNVAL) != 0) {
95251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // This should only happen if this channel is pre-closed while a
95351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // selection operation is in progress
95451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // ## Throw an error if this channel has not been pre-closed
95551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return false;
95651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
95751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
958519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera        if ((ops & (Net.POLLERR | Net.POLLHUP)) != 0) {
95951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            newOps = intOps;
96051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            sk.nioReadyOps(newOps);
96151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // No need to poll again in checkConnect,
96251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // the error will be detected there
96351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            readyToConnect = true;
96451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return (newOps & ~oldOps) != 0;
96551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
96651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
967519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera        if (((ops & Net.POLLIN) != 0) &&
96851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            ((intOps & SelectionKey.OP_READ) != 0) &&
96951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            (state == ST_CONNECTED))
97051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            newOps |= SelectionKey.OP_READ;
97151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
972519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera        if (((ops & Net.POLLCONN) != 0) &&
97351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            ((intOps & SelectionKey.OP_CONNECT) != 0) &&
97451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            ((state == ST_UNCONNECTED) || (state == ST_PENDING))) {
97551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            newOps |= SelectionKey.OP_CONNECT;
97651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            readyToConnect = true;
97751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
97851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
979519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera        if (((ops & Net.POLLOUT) != 0) &&
98051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            ((intOps & SelectionKey.OP_WRITE) != 0) &&
98151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            (state == ST_CONNECTED))
98251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            newOps |= SelectionKey.OP_WRITE;
98351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
98451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        sk.nioReadyOps(newOps);
98551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return (newOps & ~oldOps) != 0;
98651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
98751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
98851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public boolean translateAndUpdateReadyOps(int ops, SelectionKeyImpl sk) {
98951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return translateReadyOps(ops, sk.nioReadyOps(), sk);
99051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
99151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
99251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public boolean translateAndSetReadyOps(int ops, SelectionKeyImpl sk) {
99351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return translateReadyOps(ops, 0, sk);
99451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
99551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
996519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera    // package-private
997519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera    int poll(int events, long timeout) throws IOException {
998519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera        assert Thread.holdsLock(blockingLock()) && !isBlocking();
999519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera
1000519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera        synchronized (readLock) {
1001519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera            int n = 0;
1002519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera            try {
1003519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera                begin();
1004519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera                synchronized (stateLock) {
1005519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera                    if (!isOpen())
1006519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera                        return 0;
1007519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera                    readerThread = NativeThread.current();
1008519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera                }
1009519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera                n = Net.poll(fd, events, timeout);
1010519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera            } finally {
1011519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera                readerCleanup();
1012519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera                end(n > 0);
1013519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera            }
1014519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera            return n;
1015519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera        }
1016519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera    }
1017519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera
101851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
101951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Translates an interest operation set into a native poll event set
102051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
102151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void translateAndSetInterestOps(int ops, SelectionKeyImpl sk) {
102251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int newOps = 0;
102351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ((ops & SelectionKey.OP_READ) != 0)
1024519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera            newOps |= Net.POLLIN;
102551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ((ops & SelectionKey.OP_WRITE) != 0)
1026519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera            newOps |= Net.POLLOUT;
102751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ((ops & SelectionKey.OP_CONNECT) != 0)
1028519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera            newOps |= Net.POLLCONN;
102951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        sk.selector.putEventOps(sk, newOps);
103051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
103151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
103251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public FileDescriptor getFD() {
103351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return fd;
103451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
103551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
103651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public int getFDVal() {
103751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return fdVal;
103851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
103951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
104051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    @Override
104151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public String toString() {
104251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        StringBuffer sb = new StringBuffer();
104351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        sb.append(this.getClass().getSuperclass().getName());
104451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        sb.append('[');
104551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (!isOpen())
104651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            sb.append("closed");
104751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        else {
104851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            synchronized (stateLock) {
104951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                switch (state) {
105051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                case ST_UNCONNECTED:
105151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    sb.append("unconnected");
105251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    break;
105351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                case ST_PENDING:
105451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    sb.append("connection-pending");
105551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    break;
105651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                case ST_CONNECTED:
105751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    sb.append("connected");
105851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (!isInputOpen)
105951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        sb.append(" ishut");
106051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (!isOutputOpen)
106151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        sb.append(" oshut");
106251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    break;
106351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
106451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                InetSocketAddress addr = localAddress();
106551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (addr != null) {
106651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    sb.append(" local=");
106751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    sb.append(Net.getRevealedLocalAddressAsString(addr));
106851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
106951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (remoteAddress() != null) {
107051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    sb.append(" remote=");
107151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    sb.append(remoteAddress().toString());
107251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
107351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
107451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
107551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        sb.append(']');
107651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return sb.toString();
107751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
107851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
107951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
108051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // -- Native methods --
108151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
108251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static native int checkConnect(FileDescriptor fd,
108351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                           boolean block, boolean ready)
108451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        throws IOException;
108551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
108651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static native int sendOutOfBandData(FileDescriptor fd, byte data)
108751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        throws IOException;
108851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
108951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static {
109051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        nd = new SocketDispatcher();
109151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
109251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
109351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski}
1094