src/java.base/share/classes/sun/nio/ch/NioDatagramSocketImpl.java
author chegar
Fri, 18 Oct 2019 21:25:01 +0100
branchdatagramsocketimpl-branch
changeset 58697 e3ff12d14d43
parent 58688 2b1e684c3ce6
permissions -rw-r--r--
datagramsocketimpl-branch: minor refactoring
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
58680
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
     1
/*
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
     2
 * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
     4
 *
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    10
 *
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    15
 * accompanied this code).
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    16
 *
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    20
 *
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    23
 * questions.
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    24
 */
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    25
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    26
package sun.nio.ch;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    27
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    28
import java.io.FileDescriptor;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    29
import java.io.IOException;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    30
import java.io.UncheckedIOException;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    31
import java.lang.invoke.MethodHandles;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    32
import java.lang.invoke.VarHandle;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    33
import java.net.DatagramPacket;
58697
e3ff12d14d43 datagramsocketimpl-branch: minor refactoring
chegar
parents: 58688
diff changeset
    34
import java.net.DatagramSocketImpl;
58680
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    35
import java.net.InetAddress;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    36
import java.net.InetSocketAddress;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    37
import java.net.NetworkInterface;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    38
import java.net.ProtocolFamily;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    39
import java.net.SocketAddress;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    40
import java.net.SocketException;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    41
import java.net.SocketOption;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    42
import java.net.SocketOptions;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    43
import java.net.SocketTimeoutException;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    44
import java.net.StandardProtocolFamily;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    45
import java.net.StandardSocketOptions;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    46
import java.nio.ByteBuffer;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    47
import java.util.Collections;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    48
import java.util.HashSet;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    49
import java.util.Objects;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    50
import java.util.Set;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    51
import java.util.concurrent.locks.ReentrantLock;
58688
2b1e684c3ce6 datagramsocketimpl-branch: fix issue with receive packet buf size
chegar
parents: 58680
diff changeset
    52
import jdk.internal.access.JavaNetDatagramPacketAccess;
2b1e684c3ce6 datagramsocketimpl-branch: fix issue with receive packet buf size
chegar
parents: 58680
diff changeset
    53
import jdk.internal.access.SharedSecrets;
58680
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    54
import jdk.internal.ref.CleanerFactory;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    55
import sun.net.PlatformDatagramSocketImpl;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    56
import sun.net.ResourceManager;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    57
import sun.net.ext.ExtendedSocketOptions;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    58
import sun.net.util.IPAddressUtil;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    59
import sun.security.action.GetPropertyAction;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    60
import static java.net.StandardProtocolFamily.INET6;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    61
import static java.util.concurrent.TimeUnit.MILLISECONDS;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    62
import static java.util.concurrent.TimeUnit.NANOSECONDS;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    63
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    64
/**
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    65
 * A DatagramSocketImpl based on low-level NIO primitives.
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    66
 */
58697
e3ff12d14d43 datagramsocketimpl-branch: minor refactoring
chegar
parents: 58688
diff changeset
    67
public class NioDatagramSocketImpl
e3ff12d14d43 datagramsocketimpl-branch: minor refactoring
chegar
parents: 58688
diff changeset
    68
    extends DatagramSocketImpl
e3ff12d14d43 datagramsocketimpl-branch: minor refactoring
chegar
parents: 58688
diff changeset
    69
    implements PlatformDatagramSocketImpl
e3ff12d14d43 datagramsocketimpl-branch: minor refactoring
chegar
parents: 58688
diff changeset
    70
{
58680
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    71
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    72
    private static final NativeDispatcher nd = new SocketDispatcher();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    73
58688
2b1e684c3ce6 datagramsocketimpl-branch: fix issue with receive packet buf size
chegar
parents: 58680
diff changeset
    74
    private static final JavaNetDatagramPacketAccess DATAGRAM_PACKET_ACCESS =
2b1e684c3ce6 datagramsocketimpl-branch: fix issue with receive packet buf size
chegar
parents: 58680
diff changeset
    75
            SharedSecrets.getJavaNetDatagramPacketAccess();
2b1e684c3ce6 datagramsocketimpl-branch: fix issue with receive packet buf size
chegar
parents: 58680
diff changeset
    76
58680
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    77
    private static final int MAX_PACKET_LEN = 65536;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    78
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    79
    private static final ProtocolFamily family = family();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    80
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    81
    // Lock held by current reading or connecting thread
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    82
    private final ReentrantLock readLock = new ReentrantLock();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    83
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    84
    // Lock held by current writing or connecting thread
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    85
    private final ReentrantLock writeLock = new ReentrantLock();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    86
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    87
    // The stateLock for read/changing state
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    88
    private final Object stateLock = new Object();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    89
    private static final int ST_NEW = 0;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    90
    private static final int ST_UNCONNECTED = 1;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    91
    private static final int ST_CONNECTING = 2;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    92
    private static final int ST_CONNECTED = 3;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    93
    private static final int ST_CLOSING = 4;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    94
    private static final int ST_CLOSED = 5;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    95
    private volatile int state;  // need stateLock to change
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    96
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    97
    // set by create, protected by stateLock
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    98
    private FileDescriptorCloser closer;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
    99
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   100
    // set to true when the socket is in non-blocking mode
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   101
    private volatile boolean nonBlocking;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   102
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   103
    // used by connect/read/write/accept, protected by stateLock
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   104
    private long readerThread;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   105
    private long writerThread;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   106
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   107
    // Binding and remote address (when connected)
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   108
    private InetSocketAddress remoteAddress;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   109
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   110
    // receive timeout in millis
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   111
    private volatile int timeout;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   112
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   113
    /**  Returns true if the socket is open. */
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   114
    private boolean isOpen() {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   115
        return state < ST_CLOSING;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   116
    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   117
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   118
    /** Throws SocketException if the socket is not open. */
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   119
    private void ensureOpen() throws SocketException {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   120
        int state = this.state;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   121
        if (state == ST_NEW)
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   122
            throw new SocketException("Socket not created");
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   123
        if (state >= ST_CLOSING)
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   124
            throw new SocketException("Socket closed");
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   125
    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   126
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   127
    /**
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   128
     * Returns the socket protocol family.
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   129
     */
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   130
    private static ProtocolFamily family() {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   131
        if (Net.isIPv6Available()) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   132
            return StandardProtocolFamily.INET6;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   133
        } else {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   134
            return StandardProtocolFamily.INET;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   135
        }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   136
    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   137
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   138
    @Override
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   139
    protected void create() throws SocketException {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   140
        synchronized (stateLock) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   141
            if (state != ST_NEW)
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   142
                throw new SocketException("Already created");
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   143
            ResourceManager.beforeUdpCreate();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   144
            FileDescriptor fd;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   145
            try {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   146
                fd = Net.socket(false);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   147
            } catch (IOException ioe) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   148
                ResourceManager.afterUdpClose();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   149
                SocketException se = new SocketException(ioe.getMessage());
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   150
                se.initCause(ioe);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   151
                throw se;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   152
            }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   153
            this.fd = fd;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   154
            this.closer = FileDescriptorCloser.create(this);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   155
            this.state = ST_UNCONNECTED;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   156
        }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   157
    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   158
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   159
    @Override
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   160
    protected void bind(int port, InetAddress addr) throws SocketException {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   161
        synchronized (stateLock) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   162
            ensureOpen();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   163
            if (localPort != 0)
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   164
                throw new SocketException("Already bound");
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   165
            try {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   166
                Net.bind(fd, addr, port);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   167
                localPort = Net.localAddress(fd).getPort();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   168
            } catch (SocketException e) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   169
                throw e;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   170
            } catch (IOException ioe) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   171
                SocketException se = new SocketException(ioe.getMessage());
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   172
                se.initCause(ioe);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   173
                throw se;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   174
            }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   175
        }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   176
    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   177
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   178
    @SuppressWarnings("unchecked")
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   179
    private static <E extends Throwable> void sneakyThrow(Throwable e) throws E {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   180
        throw (E) e;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   181
    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   182
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   183
    @Override
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   184
    protected int peek(InetAddress i) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   185
        DatagramPacket packet = new DatagramPacket(new byte[1], 0, 1);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   186
        try {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   187
            receive(packet, true);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   188
            return packet.getPort();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   189
        } catch (IOException e) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   190
            sneakyThrow(e);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   191
            throw new InternalError("should not reach here");
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   192
        }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   193
    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   194
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   195
    @Override
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   196
    protected int peekData(DatagramPacket packet) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   197
        try {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   198
            receive(packet, true);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   199
            return packet.getPort();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   200
        } catch (IOException e) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   201
            sneakyThrow(e);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   202
            throw new InternalError("should not reach here");
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   203
        }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   204
    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   205
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   206
    /**
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   207
     * Disables the current thread for scheduling purposes until the socket is
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   208
     * ready for I/O, or is asynchronously closed, for up to the specified
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   209
     * waiting time.
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   210
     * @throws IOException if an I/O error occurs
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   211
     */
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   212
    private void park(int event, long nanos) throws IOException {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   213
        long millis;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   214
        if (nanos == 0) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   215
            millis = -1;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   216
        } else {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   217
            millis = NANOSECONDS.toMillis(nanos);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   218
        }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   219
        Net.poll(fd, event, millis);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   220
    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   221
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   222
    /**
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   223
     * Disables the current thread for scheduling purposes until the socket is
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   224
     * ready for I/O or is asynchronously closed.
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   225
     * @throws IOException if an I/O error occurs
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   226
     */
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   227
    private void park(int event) throws IOException {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   228
        park(event, 0);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   229
    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   230
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   231
    /**
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   232
     * Marks the beginning of a write operation that might block.
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   233
     * @throws SocketException if the socket is closed or not connected
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   234
     */
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   235
    private InetSocketAddress beginWrite() throws SocketException {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   236
        synchronized (stateLock) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   237
            ensureOpen();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   238
            writerThread = NativeThread.current();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   239
            return remoteAddress;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   240
        }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   241
    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   242
    /**
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   243
     * Marks the end of a write operation that may have blocked.
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   244
     */
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   245
    private void endWrite(boolean completed) throws SocketException {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   246
        synchronized (stateLock) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   247
            writerThread = 0;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   248
            int state = this.state;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   249
            if (state == ST_CLOSING)
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   250
                tryFinishClose();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   251
            if (!completed && state >= ST_CLOSING)
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   252
                throw new SocketException("Socket closed");
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   253
        }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   254
    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   255
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   256
    /**
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   257
     * Attempts to send bytes from the given byte array, to the given (optional)
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   258
     * address.
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   259
     */
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   260
    private int trySend(byte[] b, int off, int len, InetAddress address, int port)
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   261
        throws IOException
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   262
    {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   263
        ByteBuffer src = Util.getTemporaryDirectBuffer(len);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   264
        assert src.position() == 0 : "Expected source position of 0, in " + src;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   265
        assert src.remaining() == len : "Expected remaining " + len  + ", in " + src;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   266
        try {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   267
            src.put(b, off, len);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   268
            return send0(true, fd, ((DirectBuffer)src).address(), len, address, port);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   269
        } finally {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   270
            Util.offerFirstTemporaryDirectBuffer(src);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   271
        }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   272
    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   273
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   274
    @Override
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   275
    protected void send(DatagramPacket p) throws IOException {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   276
        Objects.requireNonNull(p);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   277
        InetSocketAddress target = Net.checkAddress(p.getSocketAddress());
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   278
        byte[] b = p.getData();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   279
        int off = p.getOffset();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   280
        int len = p.getLength();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   281
        if (len > MAX_PACKET_LEN)
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   282
            len = MAX_PACKET_LEN;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   283
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   284
        writeLock.lock();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   285
        try {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   286
            int n = 0;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   287
            InetAddress targetAddress = null;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   288
            int targetPort = 0;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   289
            try {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   290
                SocketAddress remote = beginWrite();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   291
                if (remote != null) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   292
                    // connected
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   293
                    if (!target.equals(remote)) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   294
                        String msg = "Connected address and packet address differ";
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   295
                        throw new IllegalArgumentException(msg);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   296
                    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   297
                } else {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   298
                    // not connected
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   299
                    if (target.getAddress().isLinkLocalAddress())
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   300
                        target = IPAddressUtil.toScopedAddress(target);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   301
                    targetAddress = target.getAddress();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   302
                    targetPort = target.getPort();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   303
                }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   304
                n = trySend(b, off, len, targetAddress, targetPort);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   305
                while (IOStatus.okayToRetry(n) && isOpen()) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   306
                    park(Net.POLLOUT);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   307
                    n = trySend(b, off, len, targetAddress, targetPort);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   308
                }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   309
            } finally {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   310
                endWrite(n > 0);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   311
                assert n >= 0;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   312
            }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   313
        } finally {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   314
            writeLock.unlock();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   315
        }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   316
    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   317
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   318
    /**
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   319
     * Configures the socket to blocking mode. This method is a no-op if the
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   320
     * socket is already in blocking mode.
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   321
     * @throws IOException if closed or there is an I/O error changing the mode
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   322
     */
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   323
    private void configureBlocking() throws IOException {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   324
        assert readLock.isHeldByCurrentThread();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   325
        if (nonBlocking) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   326
            synchronized (stateLock) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   327
                ensureOpen();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   328
                IOUtil.configureBlocking(fd, true);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   329
                nonBlocking = false;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   330
            }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   331
        }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   332
    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   333
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   334
    /**
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   335
     * Configures the socket to non-blocking mode. This method is a no-op if the
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   336
     * socket is already in non-blocking mode.
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   337
     * @throws IOException if closed or there is an I/O error changing the mode
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   338
     */
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   339
    private void configureNonBlocking() throws IOException {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   340
        assert readLock.isHeldByCurrentThread();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   341
        if (!nonBlocking) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   342
            synchronized (stateLock) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   343
                ensureOpen();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   344
                IOUtil.configureBlocking(fd, false);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   345
                nonBlocking = true;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   346
            }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   347
        }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   348
    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   349
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   350
    private InetSocketAddress beginRead() throws SocketException {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   351
        synchronized (stateLock) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   352
            ensureOpen();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   353
            readerThread = NativeThread.current();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   354
            return remoteAddress;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   355
        }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   356
    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   357
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   358
    private void endRead(boolean completed) throws SocketException {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   359
        synchronized (stateLock) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   360
            readerThread = 0;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   361
            int state = this.state;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   362
            if (state == ST_CLOSING)
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   363
                tryFinishClose();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   364
            if (!completed && state >= ST_CLOSING)
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   365
                throw new SocketException("Socket closed");
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   366
        }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   367
    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   368
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   369
    private InetSocketAddress sender = new InetSocketAddress(0);  // Set by receive0
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   370
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   371
    /**
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   372
     * Attempts to read bytes from the socket into the given byte array.
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   373
     */
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   374
    private int tryReceive(byte[] b, int off, int len, boolean isPeek)
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   375
        throws IOException
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   376
    {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   377
        ByteBuffer dst = Util.getTemporaryDirectBuffer(len);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   378
        assert dst.position() == 0;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   379
        assert dst.remaining() >= len;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   380
        try {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   381
            int n = receive0(fd, ((DirectBuffer)dst).address(), len, isPeek,
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   382
                             sender.getAddress(), sender.getPort());
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   383
            assert n <= len : "received:" + n + ", expected len:" + len;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   384
            if (n > 0) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   385
                dst.get(b, off, n);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   386
            }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   387
            return n;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   388
        } finally {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   389
            Util.offerFirstTemporaryDirectBuffer(dst);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   390
        }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   391
    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   392
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   393
    /**
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   394
     * Reads bytes from the socket into the given byte array with a timeout.
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   395
     * @throws SocketTimeoutException if the read timeout elapses
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   396
     */
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   397
    private int timedReceive(byte[] b, int off, int len, long nanos, boolean isPeek)
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   398
        throws IOException
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   399
    {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   400
        long startNanos = System.nanoTime();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   401
        int n = tryReceive(b, off, len, isPeek);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   402
        while (n == IOStatus.UNAVAILABLE && isOpen()) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   403
            long remainingNanos = nanos - (System.nanoTime() - startNanos);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   404
            if (remainingNanos <= 0) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   405
                throw new SocketTimeoutException("Receive timed out");
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   406
            }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   407
            park(Net.POLLIN, remainingNanos);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   408
            n = tryReceive(b, off, len, isPeek);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   409
        }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   410
        return n;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   411
    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   412
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   413
    @Override
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   414
    protected void receive(DatagramPacket p) throws IOException {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   415
        receive(p, false);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   416
    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   417
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   418
    private void receive(DatagramPacket p, boolean isPeek) throws IOException {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   419
        Objects.requireNonNull(p);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   420
        byte[] b = p.getData();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   421
        int off = p.getOffset();
58688
2b1e684c3ce6 datagramsocketimpl-branch: fix issue with receive packet buf size
chegar
parents: 58680
diff changeset
   422
        int len = DATAGRAM_PACKET_ACCESS.getBufLengthField(p);
58680
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   423
        assert len >= 0;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   424
        if (len > MAX_PACKET_LEN)
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   425
            len = MAX_PACKET_LEN;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   426
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   427
        readLock.lock();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   428
        try {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   429
            int n = 0;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   430
            try {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   431
                SocketAddress remote = beginRead();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   432
                boolean connected = (remote != null);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   433
                int timeout = this.timeout;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   434
                if (timeout > 0) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   435
                    // receive with timeout
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   436
                    configureNonBlocking();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   437
                    long nanos = MILLISECONDS.toNanos(timeout);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   438
                    n = timedReceive(b, off, len, nanos, isPeek);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   439
                } else {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   440
                    // receive, no timeout
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   441
                    n = tryReceive(b, off, len, isPeek);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   442
                    while (IOStatus.okayToRetry(n) && isOpen()) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   443
                        park(Net.POLLIN);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   444
                        n = tryReceive(b, off, len, isPeek);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   445
                    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   446
                }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   447
                assert n > 0;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   448
                assert sender != null;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   449
                if (p.getAddress() == null || !p.getAddress().equals(sender.getAddress()))
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   450
                    p.setAddress(sender.getAddress());
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   451
                if (p.getPort() != sender.getPort())
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   452
                    p.setPort(sender.getPort());
58688
2b1e684c3ce6 datagramsocketimpl-branch: fix issue with receive packet buf size
chegar
parents: 58680
diff changeset
   453
                DATAGRAM_PACKET_ACCESS.setLengthField(p, n);
58680
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   454
            } catch (IOException e) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   455
                // #### reset packet offset and length! ??
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   456
                throw e;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   457
            } finally {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   458
                endRead(n > 0);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   459
                assert IOStatus.check(n);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   460
            }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   461
        } finally {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   462
            readLock.unlock();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   463
        }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   464
    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   465
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   466
    @Override
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   467
    protected void connect(InetAddress address, int port) throws SocketException {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   468
        readLock.lock();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   469
        try {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   470
            writeLock.lock();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   471
            try {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   472
                synchronized (stateLock) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   473
                    ensureOpen();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   474
                    if (state == ST_CONNECTED) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   475
                        // #### already connected? throw? or connect to new remote
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   476
                    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   477
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   478
                    int n = Net.connect(family, fd, address, port);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   479
                    if (n <= 0)
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   480
                        throw new InternalError("should not reach here");
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   481
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   482
                    remoteAddress = new InetSocketAddress(address, port);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   483
                    state = ST_CONNECTED;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   484
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   485
                    // refresh local address
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   486
                    localPort = Net.localAddress(fd).getPort();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   487
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   488
                    // flush any packets already received.
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   489
                    try {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   490
                        byte[] ba = new byte[1];
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   491
                        configureNonBlocking();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   492
                        while (tryReceive(ba, 0, 1, false) > 0) { }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   493
                    } finally {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   494
                        configureBlocking();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   495
                    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   496
                }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   497
            } catch (SocketException e) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   498
                throw e;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   499
            } catch (IOException e) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   500
                throw new SocketException(e.getMessage());
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   501
            } finally {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   502
                writeLock.unlock();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   503
            }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   504
        } finally {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   505
            readLock.unlock();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   506
        }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   507
    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   508
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   509
    @Override
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   510
    protected void disconnect() {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   511
        readLock.lock();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   512
        try {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   513
            writeLock.lock();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   514
            try {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   515
                synchronized (stateLock) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   516
                    if (!isOpen() || (state != ST_CONNECTED))
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   517
                        return;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   518
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   519
                    try {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   520
                        disconnect0(fd, family == INET6);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   521
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   522
                        // no longer connected
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   523
                        remoteAddress = null;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   524
                        state = ST_UNCONNECTED;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   525
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   526
                        // check whether rebind is needed
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   527
                        InetSocketAddress isa = Net.localAddress(fd);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   528
                        if (isa.getPort() == 0) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   529
                            // On Linux, if bound to ephemeral port,
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   530
                            // disconnect does not preserve that port.
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   531
                            // In this case, try to rebind to the previous port.
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   532
                            int port = localPort;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   533
                            Net.bind(family, fd, isa.getAddress(), port);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   534
                            isa = Net.localAddress(fd); // refresh address
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   535
                            assert isa.getPort() == port;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   536
                        }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   537
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   538
                        // refresh local port
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   539
                        localPort = isa.getPort();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   540
                    } catch (IOException e) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   541
                        sneakyThrow(e);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   542
                        throw new InternalError("should not reach here");
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   543
                    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   544
                }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   545
            } finally {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   546
                writeLock.unlock();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   547
            }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   548
        } finally {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   549
            readLock.unlock();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   550
        }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   551
    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   552
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   553
    /**
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   554
     * Closes the socket if there are no I/O operations in progress.
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   555
     */
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   556
    private boolean tryClose() throws IOException {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   557
        assert Thread.holdsLock(stateLock) && state == ST_CLOSING;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   558
        if (readerThread == 0 && writerThread == 0) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   559
            try {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   560
                closer.run();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   561
            } catch (UncheckedIOException ioe) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   562
                throw ioe.getCause();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   563
            } finally {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   564
                state = ST_CLOSED;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   565
            }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   566
            return true;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   567
        } else {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   568
            return false;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   569
        }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   570
    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   571
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   572
    /**
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   573
     * Invokes tryClose to attempt to close the socket.
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   574
     *
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   575
     * This method is used for deferred closing by I/O operations.
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   576
     */
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   577
    private void tryFinishClose() {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   578
        try {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   579
            tryClose();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   580
        } catch (IOException ignore) { }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   581
    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   582
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   583
    /**
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   584
     * Closes the socket. If there are I/O operations in progress then the
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   585
     * socket is pre-closed and the threads are signalled. The socket will be
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   586
     * closed when the last I/O operation aborts.
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   587
     */
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   588
    @Override
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   589
    protected void close() {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   590
        synchronized (stateLock) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   591
            int state = this.state;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   592
            if (state >= ST_CLOSING)
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   593
                return;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   594
            if (state == ST_NEW) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   595
                this.state = ST_CLOSED;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   596
                return;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   597
            }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   598
            this.state = ST_CLOSING;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   599
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   600
            // Attempt to close the socket. If there are I/O operations in
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   601
            // progress then the socket is pre-closed and the thread(s)
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   602
            // signalled. The last thread will close the file descriptor.
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   603
            try {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   604
                if (!tryClose()) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   605
                    nd.preClose(fd);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   606
                    long reader = readerThread;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   607
                    if (reader != 0)
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   608
                        NativeThread.signal(reader);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   609
                    long writer = writerThread;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   610
                    if (writer != 0)
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   611
                        NativeThread.signal(writer);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   612
                }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   613
            } catch (IOException e) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   614
                throw new UncheckedIOException(e);  // Ugh!
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   615
            }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   616
        }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   617
    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   618
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   619
    private static final Set<SocketOption<?>> socketOptions = socketOptions();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   620
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   621
    private static Set<SocketOption<?>> socketOptions() {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   622
        HashSet<SocketOption<?>> options = new HashSet<>();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   623
        options.add(StandardSocketOptions.SO_SNDBUF);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   624
        options.add(StandardSocketOptions.SO_RCVBUF);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   625
        options.add(StandardSocketOptions.SO_REUSEADDR);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   626
        options.add(StandardSocketOptions.IP_TOS);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   627
        if (Net.isReusePortAvailable())
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   628
            options.add(StandardSocketOptions.SO_REUSEPORT);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   629
        options.addAll(ExtendedSocketOptions.datagramSocketOptions());
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   630
        return Collections.unmodifiableSet(options);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   631
    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   632
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   633
    @Override
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   634
    protected Set<SocketOption<?>> supportedOptions() {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   635
        return socketOptions;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   636
    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   637
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   638
    @Override
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   639
    protected <T> void setOption(SocketOption<T> opt, T value) throws IOException {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   640
        if (!supportedOptions().contains(opt))
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   641
            throw new UnsupportedOperationException("'" + opt + "' not supported");
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   642
        if (!opt.type().isInstance(value))
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   643
            throw new IllegalArgumentException("Invalid value '" + value + "'");
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   644
        synchronized (stateLock) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   645
            ensureOpen();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   646
            if (opt == StandardSocketOptions.IP_TOS) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   647
                // maps to IP_TOS or IPV6_TCLASS
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   648
                Net.setSocketOption(fd, family(), opt, value);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   649
            } else if (opt == StandardSocketOptions.SO_REUSEADDR) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   650
                setOption(SocketOptions.SO_REUSEADDR, value);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   651
            } else if (opt == StandardSocketOptions.SO_REUSEPORT) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   652
                setOption(SocketOptions.SO_REUSEPORT, value);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   653
            } else {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   654
                // option does not need special handling
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   655
                Net.setSocketOption(fd, opt, value);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   656
            }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   657
        }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   658
    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   659
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   660
    @SuppressWarnings("unchecked")
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   661
    @Override
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   662
    protected <T> T getOption(SocketOption<T> opt) throws IOException {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   663
        if (!supportedOptions().contains(opt))
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   664
            throw new UnsupportedOperationException("'" + opt + "' not supported");
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   665
        synchronized (stateLock) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   666
            ensureOpen();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   667
            if (opt == StandardSocketOptions.IP_TOS) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   668
                return (T) Net.getSocketOption(fd, family(), opt);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   669
            } else if (opt == StandardSocketOptions.SO_REUSEADDR) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   670
                return (T) getOption(SocketOptions.SO_REUSEADDR);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   671
            } else if (opt == StandardSocketOptions.SO_REUSEPORT) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   672
                return (T) getOption(SocketOptions.SO_REUSEPORT);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   673
            } else {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   674
                // option does not need special handling
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   675
                return (T) Net.getSocketOption(fd, opt);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   676
            }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   677
        }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   678
    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   679
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   680
    private static boolean booleanValue(Object value, String desc)
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   681
        throws SocketException
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   682
    {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   683
        if (!(value instanceof Boolean))
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   684
            throw new SocketException("Bad value for " + desc);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   685
        return (boolean) value;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   686
    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   687
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   688
    private static int intValue(Object value, String desc) throws SocketException {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   689
        if (!(value instanceof Integer))
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   690
            throw new SocketException("Bad value for " + desc);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   691
        return (int) value;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   692
    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   693
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   694
    @Override
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   695
    public void setOption(int opt, Object value) throws SocketException {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   696
        synchronized (stateLock) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   697
            ensureOpen();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   698
            try {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   699
                switch (opt) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   700
                case SO_TIMEOUT: {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   701
                    int i = intValue(value, "SO_TIMEOUT");
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   702
                    if (i < 0)
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   703
                        throw new IllegalArgumentException("timeout < 0");
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   704
                    timeout = i;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   705
                    break;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   706
                }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   707
                case IP_TOS: {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   708
                    int i = intValue(value, "IP_TOS");
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   709
                    Net.setSocketOption(fd, family, StandardSocketOptions.IP_TOS, i);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   710
                    break;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   711
                }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   712
                case SO_REUSEADDR: {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   713
                    boolean b = booleanValue(value, "SO_REUSEADDR");
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   714
                    Net.setSocketOption(fd, StandardSocketOptions.SO_REUSEADDR, b);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   715
                    break;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   716
                }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   717
                case SO_BROADCAST: {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   718
                    boolean b = booleanValue(value, "SO_BROADCAST");
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   719
                    Net.setSocketOption(fd, StandardSocketOptions.SO_BROADCAST, b);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   720
                    break;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   721
                }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   722
                case SO_BINDADDR: {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   723
                    throw new SocketException("Cannot re-bind Socket");
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   724
                }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   725
                case SO_RCVBUF: {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   726
                    int i = intValue(value, "SO_RCVBUF");
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   727
                    if (i <= 0)
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   728
                        throw new SocketException("SO_RCVBUF <= 0");
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   729
                    Net.setSocketOption(fd, StandardSocketOptions.SO_RCVBUF, i);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   730
                    break;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   731
                }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   732
                case SO_SNDBUF: {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   733
                    int i = intValue(value, "SO_SNDBUF");
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   734
                    if (i <= 0)
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   735
                        throw new SocketException("SO_SNDBUF <= 0");
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   736
                    Net.setSocketOption(fd, StandardSocketOptions.SO_SNDBUF, i);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   737
                    break;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   738
                }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   739
                case SO_REUSEPORT: {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   740
                    if (!Net.isReusePortAvailable())
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   741
                        throw new UnsupportedOperationException("SO_REUSEPORT not supported");
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   742
                    boolean b = booleanValue(value, "SO_REUSEPORT");
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   743
                    Net.setSocketOption(fd, StandardSocketOptions.SO_REUSEPORT, b);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   744
                    break;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   745
                }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   746
                default:
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   747
                    throw new SocketException("unknown option: " + opt);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   748
                }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   749
            } catch (SocketException e) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   750
                throw e;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   751
            } catch (IllegalArgumentException | IOException e) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   752
                throw new SocketException(e.getMessage());
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   753
            }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   754
        }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   755
    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   756
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   757
    @Override
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   758
    public Object getOption(int opt) throws SocketException {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   759
        synchronized (stateLock) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   760
            ensureOpen();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   761
            try {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   762
                switch (opt) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   763
                case SO_TIMEOUT:
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   764
                    return timeout;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   765
                case IP_TOS:
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   766
                    return Net.getSocketOption(fd, family(), StandardSocketOptions.IP_TOS);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   767
                case SO_BINDADDR:
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   768
                    return Net.localAddress(fd).getAddress();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   769
                case SO_RCVBUF:
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   770
                    return Net.getSocketOption(fd, StandardSocketOptions.SO_RCVBUF);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   771
                case SO_SNDBUF:
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   772
                    return Net.getSocketOption(fd, StandardSocketOptions.SO_SNDBUF);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   773
                case SO_REUSEADDR:
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   774
                    return Net.getSocketOption(fd, StandardSocketOptions.SO_REUSEADDR);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   775
                case SO_BROADCAST:
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   776
                    return Net.getSocketOption(fd, StandardSocketOptions.SO_BROADCAST);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   777
                case SO_REUSEPORT:
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   778
                    if (!Net.isReusePortAvailable())
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   779
                        throw new UnsupportedOperationException("SO_REUSEPORT not supported");
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   780
                    return Net.getSocketOption(fd, StandardSocketOptions.SO_REUSEPORT);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   781
                default:
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   782
                    throw new SocketException("Unknown option " + opt);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   783
                }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   784
            } catch (SocketException e) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   785
                throw e;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   786
            } catch (IllegalArgumentException | IOException e) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   787
                throw new SocketException(e.getMessage());
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   788
            }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   789
        }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   790
    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   791
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   792
    /**
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   793
     * A task that closes a DatagramSocketImpl's file descriptor. The task is
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   794
     * run when the NioDatagramSocketImpl is explicitly closed or when the
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   795
     * NioDatagramSocketImpl becomes phantom reachable.
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   796
     */
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   797
    private static class FileDescriptorCloser implements Runnable {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   798
        private static final VarHandle CLOSED;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   799
        static {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   800
            try {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   801
                MethodHandles.Lookup l = MethodHandles.lookup();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   802
                CLOSED = l.findVarHandle(FileDescriptorCloser.class,
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   803
                                         "closed",
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   804
                                         boolean.class);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   805
            } catch (Exception e) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   806
                throw new InternalError(e);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   807
            }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   808
        }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   809
        private volatile boolean closed;  // accessed through VarHandle
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   810
        private final FileDescriptor fd;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   811
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   812
        FileDescriptorCloser(FileDescriptor fd) { this.fd = fd; }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   813
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   814
        static FileDescriptorCloser create(NioDatagramSocketImpl impl) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   815
            assert Thread.holdsLock(impl.stateLock);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   816
            var closer = new FileDescriptorCloser(impl.fd);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   817
            CleanerFactory.cleaner().register(impl, closer);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   818
            return closer;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   819
        }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   820
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   821
        @Override
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   822
        public void run() {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   823
            if (CLOSED.compareAndSet(this, false, true)) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   824
                try {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   825
                    nd.close(fd);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   826
                } catch (IOException ioe) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   827
                    throw new UncheckedIOException(ioe);
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   828
                } finally {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   829
                    ResourceManager.afterUdpClose();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   830
                }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   831
            }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   832
        }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   833
    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   834
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   835
    @Deprecated
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   836
    @Override
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   837
    protected void setTTL(byte ttl) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   838
        throw new InternalError("should not reach here");
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   839
    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   840
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   841
    @Deprecated
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   842
    @Override
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   843
    protected byte getTTL() {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   844
        throw new InternalError("should not reach here");
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   845
    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   846
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   847
    @Override
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   848
    protected void setTimeToLive(int ttl) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   849
        throw new InternalError("should not reach here");
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   850
    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   851
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   852
    @Override
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   853
    protected int getTimeToLive() {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   854
        throw new InternalError("should not reach here");
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   855
    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   856
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   857
    @Override
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   858
    protected void join(InetAddress inetaddr) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   859
        throw new InternalError("should not reach here");
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   860
    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   861
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   862
    @Override
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   863
    protected void leave(InetAddress inetaddr) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   864
        throw new InternalError("should not reach here");
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   865
    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   866
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   867
    @Override
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   868
    protected void joinGroup(SocketAddress mcastaddr, NetworkInterface netIf) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   869
        throw new InternalError("should not reach here");
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   870
    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   871
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   872
    @Override
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   873
    protected void leaveGroup(SocketAddress mcastaddr, NetworkInterface netIf) {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   874
        throw new InternalError("should not reach here");
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   875
    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   876
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   877
    /** Set if the native connect() call is not to be used */
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   878
    private static final boolean connectDisabled =
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   879
            GetPropertyAction.privilegedGetProperty("os.name").contains("OS X");
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   880
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   881
    @Override
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   882
    public boolean nativeConnectDisabled() {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   883
        return connectDisabled;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   884
    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   885
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   886
    // -- Native methods --
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   887
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   888
    private static native void initIDs();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   889
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   890
    private native int receive0(FileDescriptor fd,
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   891
                                long address,
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   892
                                int len,
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   893
                                boolean isPeek,
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   894
                                InetAddress cachedSenderAddress,
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   895
                                int cachedSenderPort)
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   896
        throws IOException;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   897
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   898
    private static native int send0(boolean preferIPv6,
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   899
                                    FileDescriptor fd,
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   900
                                    long address,
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   901
                                    int len,
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   902
                                    InetAddress addr,
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   903
                                    int port)
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   904
        throws IOException;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   905
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   906
    private static native void disconnect0(FileDescriptor fd,
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   907
                                           boolean isIPv6)
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   908
        throws IOException;
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   909
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   910
    static {
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   911
        IOUtil.load();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   912
        initIDs();
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   913
    }
7e9e2f10a050 datagramsocketimpl-branch: initial code changes
chegar
parents:
diff changeset
   914
}