src/java.base/windows/classes/sun/nio/ch/WindowsAsynchronousSocketChannelImpl.java
author michaelm
Fri, 22 Jun 2018 18:10:20 +0100
changeset 50722 bc104aaf24e9
parent 47216 71c04702a3d5
permissions -rw-r--r--
8204233: Add configurable option for enhanced socket IOException messages Reviewed-by: alanb, chegar
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
     1
/*
23010
6dadb192ad81 8029235: Update copyright year to match last edit in jdk8 jdk repository for 2013
lana
parents: 22340
diff changeset
     2
 * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
     4
 *
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3632
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3632
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    10
 *
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    15
 * accompanied this code).
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    16
 *
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
2284
11c388a3591e 6814587: Legal notice repair needed in jdk/src/share/classes/java/nio
tbell
parents: 2057
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3632
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3632
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3632
diff changeset
    23
 * questions.
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    24
 */
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    25
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    26
package sun.nio.ch;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    27
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    28
import java.nio.channels.*;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    29
import java.nio.ByteBuffer;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    30
import java.nio.BufferOverflowException;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    31
import java.net.*;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    32
import java.util.concurrent.*;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    33
import java.io.IOException;
22340
79163d48aeda 8028453: AsynchronousSocketChannel.connect() requires SocketPermission due to bind to local address (win)
michaelm
parents: 19607
diff changeset
    34
import java.security.AccessController;
79163d48aeda 8028453: AsynchronousSocketChannel.connect() requires SocketPermission due to bind to local address (win)
michaelm
parents: 19607
diff changeset
    35
import java.security.PrivilegedActionException;
79163d48aeda 8028453: AsynchronousSocketChannel.connect() requires SocketPermission due to bind to local address (win)
michaelm
parents: 19607
diff changeset
    36
import java.security.PrivilegedExceptionAction;
33674
566777f73c32 8140606: Update library code to use internal Unsafe
chegar
parents: 25859
diff changeset
    37
import jdk.internal.misc.Unsafe;
50722
bc104aaf24e9 8204233: Add configurable option for enhanced socket IOException messages
michaelm
parents: 47216
diff changeset
    38
import sun.net.util.SocketExceptions;
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    39
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    40
/**
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    41
 * Windows implementation of AsynchronousSocketChannel using overlapped I/O.
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    42
 */
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    43
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    44
class WindowsAsynchronousSocketChannelImpl
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    45
    extends AsynchronousSocketChannelImpl implements Iocp.OverlappedChannel
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    46
{
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    47
    private static final Unsafe unsafe = Unsafe.getUnsafe();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    48
    private static int addressSize = unsafe.addressSize();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    49
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    50
    private static int dependsArch(int value32, int value64) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    51
        return (addressSize == 4) ? value32 : value64;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    52
    }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    53
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    54
    /*
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    55
     * typedef struct _WSABUF {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    56
     *     u_long      len;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    57
     *     char FAR *  buf;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    58
     * } WSABUF;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    59
     */
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    60
    private static final int SIZEOF_WSABUF  = dependsArch(8, 16);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    61
    private static final int OFFSETOF_LEN   = 0;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    62
    private static final int OFFSETOF_BUF   = dependsArch(4, 8);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    63
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    64
    // maximum vector size for scatter/gather I/O
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    65
    private static final int MAX_WSABUF     = 16;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    66
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    67
    private static final int SIZEOF_WSABUFARRAY = MAX_WSABUF * SIZEOF_WSABUF;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    68
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    69
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    70
    // socket handle. Use begin()/end() around each usage of this handle.
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    71
    final long handle;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    72
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    73
    // I/O completion port that the socket is associated with
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    74
    private final Iocp iocp;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    75
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    76
    // completion key to identify channel when I/O completes
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    77
    private final int completionKey;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    78
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    79
    // Pending I/O operations are tied to an OVERLAPPED structure that can only
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    80
    // be released when the I/O completion event is posted to the completion
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    81
    // port. Where I/O operations complete immediately then it is possible
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    82
    // there may be more than two OVERLAPPED structures in use.
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    83
    private final PendingIoCache ioCache;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    84
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    85
    // per-channel arrays of WSABUF structures
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    86
    private final long readBufferArray;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    87
    private final long writeBufferArray;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    88
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    89
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    90
    WindowsAsynchronousSocketChannelImpl(Iocp iocp, boolean failIfGroupShutdown)
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    91
        throws IOException
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    92
    {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    93
        super(iocp);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    94
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    95
        // associate socket with default completion port
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    96
        long h = IOUtil.fdVal(fd);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    97
        int key = 0;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    98
        try {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    99
            key = iocp.associate(this, h);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   100
        } catch (ShutdownChannelGroupException x) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   101
            if (failIfGroupShutdown) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   102
                closesocket0(h);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   103
                throw x;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   104
            }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   105
        } catch (IOException x) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   106
            closesocket0(h);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   107
            throw x;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   108
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   109
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   110
        this.handle = h;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   111
        this.iocp = iocp;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   112
        this.completionKey = key;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   113
        this.ioCache = new PendingIoCache();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   114
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   115
        // allocate WSABUF arrays
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   116
        this.readBufferArray = unsafe.allocateMemory(SIZEOF_WSABUFARRAY);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   117
        this.writeBufferArray = unsafe.allocateMemory(SIZEOF_WSABUFARRAY);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   118
    }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   119
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   120
    WindowsAsynchronousSocketChannelImpl(Iocp iocp) throws IOException {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   121
        this(iocp, true);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   122
    }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   123
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   124
    @Override
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   125
    public AsynchronousChannelGroupImpl group() {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   126
        return iocp;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   127
    }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   128
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   129
    /**
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   130
     * Invoked by Iocp when an I/O operation competes.
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   131
     */
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   132
    @Override
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   133
    public <V,A> PendingFuture<V,A> getByOverlapped(long overlapped) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   134
        return ioCache.remove(overlapped);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   135
    }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   136
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   137
    // invoked by WindowsAsynchronousServerSocketChannelImpl
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   138
    long handle() {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   139
        return handle;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   140
    }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   141
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   142
    // invoked by WindowsAsynchronousServerSocketChannelImpl when new connection
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   143
    // accept
18212
22f8c33b0690 8001318: Socket.getLocalAddress not consistent with InetAddress.getLocalHost
khazra
parents: 10137
diff changeset
   144
    void setConnected(InetSocketAddress localAddress,
22f8c33b0690 8001318: Socket.getLocalAddress not consistent with InetAddress.getLocalHost
khazra
parents: 10137
diff changeset
   145
                      InetSocketAddress remoteAddress)
22f8c33b0690 8001318: Socket.getLocalAddress not consistent with InetAddress.getLocalHost
khazra
parents: 10137
diff changeset
   146
    {
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   147
        synchronized (stateLock) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   148
            state = ST_CONNECTED;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   149
            this.localAddress = localAddress;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   150
            this.remoteAddress = remoteAddress;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   151
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   152
    }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   153
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   154
    @Override
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   155
    void implClose() throws IOException {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   156
        // close socket (may cause outstanding async I/O operations to fail).
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   157
        closesocket0(handle);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   158
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   159
        // waits until all I/O operations have completed
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   160
        ioCache.close();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   161
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   162
        // release arrays of WSABUF structures
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   163
        unsafe.freeMemory(readBufferArray);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   164
        unsafe.freeMemory(writeBufferArray);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   165
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   166
        // finally disassociate from the completion port (key can be 0 if
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   167
        // channel created when group is shutdown)
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   168
        if (completionKey != 0)
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   169
            iocp.disassociate(completionKey);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   170
    }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   171
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   172
    @Override
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   173
    public void onCancel(PendingFuture<?,?> task) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   174
        if (task.getContext() instanceof ConnectTask)
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   175
            killConnect();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   176
        if (task.getContext() instanceof ReadTask)
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   177
            killReading();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   178
        if (task.getContext() instanceof WriteTask)
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   179
            killWriting();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   180
    }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   181
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   182
    /**
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   183
     * Implements the task to initiate a connection and the handler to
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   184
     * consume the result when the connection is established (or fails).
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   185
     */
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   186
    private class ConnectTask<A> implements Runnable, Iocp.ResultHandler {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   187
        private final InetSocketAddress remote;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   188
        private final PendingFuture<Void,A> result;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   189
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   190
        ConnectTask(InetSocketAddress remote, PendingFuture<Void,A> result) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   191
            this.remote = remote;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   192
            this.result = result;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   193
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   194
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   195
        private void closeChannel() {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   196
            try {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   197
                close();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   198
            } catch (IOException ignore) { }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   199
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   200
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   201
        private IOException toIOException(Throwable x) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   202
            if (x instanceof IOException) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   203
                if (x instanceof ClosedChannelException)
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   204
                    x = new AsynchronousCloseException();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   205
                return (IOException)x;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   206
            }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   207
            return new IOException(x);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   208
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   209
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   210
        /**
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   211
         * Invoke after a connection is successfully established.
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   212
         */
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   213
        private void afterConnect() throws IOException {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   214
            updateConnectContext(handle);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   215
            synchronized (stateLock) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   216
                state = ST_CONNECTED;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   217
                remoteAddress = remote;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   218
            }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   219
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   220
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   221
        /**
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   222
         * Task to initiate a connection.
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   223
         */
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   224
        @Override
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   225
        public void run() {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   226
            long overlapped = 0L;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   227
            Throwable exc = null;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   228
            try {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   229
                begin();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   230
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   231
                // synchronize on result to allow this thread handle the case
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   232
                // where the connection is established immediately.
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   233
                synchronized (result) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   234
                    overlapped = ioCache.add(result);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   235
                    // initiate the connection
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   236
                    int n = connect0(handle, Net.isIPv6Available(), remote.getAddress(),
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   237
                                     remote.getPort(), overlapped);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   238
                    if (n == IOStatus.UNAVAILABLE) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   239
                        // connection is pending
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   240
                        return;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   241
                    }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   242
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   243
                    // connection established immediately
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   244
                    afterConnect();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   245
                    result.setResult(null);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   246
                }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   247
            } catch (Throwable x) {
8568
f59001e07166 6944810: (ch) Assert failure in sun.nio.ch.PendingIoCache.clearPendingIoMap [win]
alanb
parents: 5506
diff changeset
   248
                if (overlapped != 0L)
f59001e07166 6944810: (ch) Assert failure in sun.nio.ch.PendingIoCache.clearPendingIoMap [win]
alanb
parents: 5506
diff changeset
   249
                    ioCache.remove(overlapped);
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   250
                exc = x;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   251
            } finally {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   252
                end();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   253
            }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   254
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   255
            if (exc != null) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   256
                closeChannel();
50722
bc104aaf24e9 8204233: Add configurable option for enhanced socket IOException messages
michaelm
parents: 47216
diff changeset
   257
                exc = SocketExceptions.of(toIOException(exc), remote);
bc104aaf24e9 8204233: Add configurable option for enhanced socket IOException messages
michaelm
parents: 47216
diff changeset
   258
                result.setFailure(exc);
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   259
            }
3632
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   260
            Invoker.invoke(result);
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   261
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   262
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   263
        /**
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   264
         * Invoked by handler thread when connection established.
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   265
         */
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   266
        @Override
3632
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   267
        public void completed(int bytesTransferred, boolean canInvokeDirect) {
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   268
            Throwable exc = null;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   269
            try {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   270
                begin();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   271
                afterConnect();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   272
                result.setResult(null);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   273
            } catch (Throwable x) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   274
                // channel is closed or unable to finish connect
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   275
                exc = x;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   276
            } finally {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   277
                end();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   278
            }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   279
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   280
            // can't close channel while in begin/end block
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   281
            if (exc != null) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   282
                closeChannel();
50722
bc104aaf24e9 8204233: Add configurable option for enhanced socket IOException messages
michaelm
parents: 47216
diff changeset
   283
                IOException ee = toIOException(exc);
bc104aaf24e9 8204233: Add configurable option for enhanced socket IOException messages
michaelm
parents: 47216
diff changeset
   284
                ee = SocketExceptions.of(ee, remote);
bc104aaf24e9 8204233: Add configurable option for enhanced socket IOException messages
michaelm
parents: 47216
diff changeset
   285
                result.setFailure(ee);
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   286
            }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   287
3632
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   288
            if (canInvokeDirect) {
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   289
                Invoker.invokeUnchecked(result);
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   290
            } else {
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   291
                Invoker.invoke(result);
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   292
            }
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   293
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   294
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   295
        /**
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   296
         * Invoked by handler thread when failed to establish connection.
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   297
         */
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   298
        @Override
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   299
        public void failed(int error, IOException x) {
50722
bc104aaf24e9 8204233: Add configurable option for enhanced socket IOException messages
michaelm
parents: 47216
diff changeset
   300
            x = SocketExceptions.of(x, remote);
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   301
            if (isOpen()) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   302
                closeChannel();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   303
                result.setFailure(x);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   304
            } else {
50722
bc104aaf24e9 8204233: Add configurable option for enhanced socket IOException messages
michaelm
parents: 47216
diff changeset
   305
                x = SocketExceptions.of(new AsynchronousCloseException(), remote);
bc104aaf24e9 8204233: Add configurable option for enhanced socket IOException messages
michaelm
parents: 47216
diff changeset
   306
                result.setFailure(x);
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   307
            }
3632
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   308
            Invoker.invoke(result);
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   309
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   310
    }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   311
22340
79163d48aeda 8028453: AsynchronousSocketChannel.connect() requires SocketPermission due to bind to local address (win)
michaelm
parents: 19607
diff changeset
   312
    private void doPrivilegedBind(final SocketAddress sa) throws IOException {
79163d48aeda 8028453: AsynchronousSocketChannel.connect() requires SocketPermission due to bind to local address (win)
michaelm
parents: 19607
diff changeset
   313
        try {
79163d48aeda 8028453: AsynchronousSocketChannel.connect() requires SocketPermission due to bind to local address (win)
michaelm
parents: 19607
diff changeset
   314
            AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
79163d48aeda 8028453: AsynchronousSocketChannel.connect() requires SocketPermission due to bind to local address (win)
michaelm
parents: 19607
diff changeset
   315
                public Void run() throws IOException {
79163d48aeda 8028453: AsynchronousSocketChannel.connect() requires SocketPermission due to bind to local address (win)
michaelm
parents: 19607
diff changeset
   316
                    bind(sa);
79163d48aeda 8028453: AsynchronousSocketChannel.connect() requires SocketPermission due to bind to local address (win)
michaelm
parents: 19607
diff changeset
   317
                    return null;
79163d48aeda 8028453: AsynchronousSocketChannel.connect() requires SocketPermission due to bind to local address (win)
michaelm
parents: 19607
diff changeset
   318
                }
79163d48aeda 8028453: AsynchronousSocketChannel.connect() requires SocketPermission due to bind to local address (win)
michaelm
parents: 19607
diff changeset
   319
            });
79163d48aeda 8028453: AsynchronousSocketChannel.connect() requires SocketPermission due to bind to local address (win)
michaelm
parents: 19607
diff changeset
   320
        } catch (PrivilegedActionException e) {
79163d48aeda 8028453: AsynchronousSocketChannel.connect() requires SocketPermission due to bind to local address (win)
michaelm
parents: 19607
diff changeset
   321
            throw (IOException) e.getException();
79163d48aeda 8028453: AsynchronousSocketChannel.connect() requires SocketPermission due to bind to local address (win)
michaelm
parents: 19607
diff changeset
   322
        }
79163d48aeda 8028453: AsynchronousSocketChannel.connect() requires SocketPermission due to bind to local address (win)
michaelm
parents: 19607
diff changeset
   323
    }
79163d48aeda 8028453: AsynchronousSocketChannel.connect() requires SocketPermission due to bind to local address (win)
michaelm
parents: 19607
diff changeset
   324
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   325
    @Override
3632
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   326
    <A> Future<Void> implConnect(SocketAddress remote,
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   327
                                 A attachment,
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   328
                                 CompletionHandler<Void,? super A> handler)
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   329
    {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   330
        if (!isOpen()) {
3632
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   331
            Throwable exc = new ClosedChannelException();
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   332
            if (handler == null)
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   333
                return CompletedFuture.withFailure(exc);
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   334
            Invoker.invoke(this, handler, attachment, null, exc);
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   335
            return null;
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   336
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   337
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   338
        InetSocketAddress isa = Net.checkAddress(remote);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   339
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   340
        // permission check
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   341
        SecurityManager sm = System.getSecurityManager();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   342
        if (sm != null)
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   343
            sm.checkConnect(isa.getAddress().getHostAddress(), isa.getPort());
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   344
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   345
        // check and update state
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   346
        // ConnectEx requires the socket to be bound to a local address
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   347
        IOException bindException = null;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   348
        synchronized (stateLock) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   349
            if (state == ST_CONNECTED)
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   350
                throw new AlreadyConnectedException();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   351
            if (state == ST_PENDING)
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   352
                throw new ConnectionPendingException();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   353
            if (localAddress == null) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   354
                try {
22340
79163d48aeda 8028453: AsynchronousSocketChannel.connect() requires SocketPermission due to bind to local address (win)
michaelm
parents: 19607
diff changeset
   355
                    SocketAddress any = new InetSocketAddress(0);
79163d48aeda 8028453: AsynchronousSocketChannel.connect() requires SocketPermission due to bind to local address (win)
michaelm
parents: 19607
diff changeset
   356
                    if (sm == null) {
79163d48aeda 8028453: AsynchronousSocketChannel.connect() requires SocketPermission due to bind to local address (win)
michaelm
parents: 19607
diff changeset
   357
                        bind(any);
79163d48aeda 8028453: AsynchronousSocketChannel.connect() requires SocketPermission due to bind to local address (win)
michaelm
parents: 19607
diff changeset
   358
                    } else {
79163d48aeda 8028453: AsynchronousSocketChannel.connect() requires SocketPermission due to bind to local address (win)
michaelm
parents: 19607
diff changeset
   359
                        doPrivilegedBind(any);
79163d48aeda 8028453: AsynchronousSocketChannel.connect() requires SocketPermission due to bind to local address (win)
michaelm
parents: 19607
diff changeset
   360
                    }
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   361
                } catch (IOException x) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   362
                    bindException = x;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   363
                }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   364
            }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   365
            if (bindException == null)
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   366
                state = ST_PENDING;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   367
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   368
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   369
        // handle bind failure
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   370
        if (bindException != null) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   371
            try {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   372
                close();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   373
            } catch (IOException ignore) { }
3632
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   374
            if (handler == null)
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   375
                return CompletedFuture.withFailure(bindException);
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   376
            Invoker.invoke(this, handler, attachment, null, bindException);
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   377
            return null;
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   378
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   379
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   380
        // setup task
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   381
        PendingFuture<Void,A> result =
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   382
            new PendingFuture<Void,A>(this, handler, attachment);
10137
d92637d3d673 7068616: NIO libraries do not build with javac -Xlint:all,-deprecation -Werror
jjg
parents: 9035
diff changeset
   383
        ConnectTask<A> task = new ConnectTask<A>(isa, result);
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   384
        result.setContext(task);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   385
3632
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   386
        // initiate I/O
37369
770f6e0237e4 8154436: Drop code to support Windows XP in windows async channel impl
redestad
parents: 33674
diff changeset
   387
        task.run();
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   388
        return result;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   389
    }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   390
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   391
    /**
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   392
     * Implements the task to initiate a read and the handler to consume the
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   393
     * result when the read completes.
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   394
     */
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   395
    private class ReadTask<V,A> implements Runnable, Iocp.ResultHandler {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   396
        private final ByteBuffer[] bufs;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   397
        private final int numBufs;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   398
        private final boolean scatteringRead;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   399
        private final PendingFuture<V,A> result;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   400
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   401
        // set by run method
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   402
        private ByteBuffer[] shadow;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   403
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   404
        ReadTask(ByteBuffer[] bufs,
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   405
                 boolean scatteringRead,
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   406
                 PendingFuture<V,A> result)
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   407
        {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   408
            this.bufs = bufs;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   409
            this.numBufs = (bufs.length > MAX_WSABUF) ? MAX_WSABUF : bufs.length;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   410
            this.scatteringRead = scatteringRead;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   411
            this.result = result;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   412
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   413
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   414
        /**
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   415
         * Invoked prior to read to prepare the WSABUF array. Where necessary,
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   416
         * it substitutes non-direct buffers with direct buffers.
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   417
         */
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   418
        void prepareBuffers() {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   419
            shadow = new ByteBuffer[numBufs];
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   420
            long address = readBufferArray;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   421
            for (int i=0; i<numBufs; i++) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   422
                ByteBuffer dst = bufs[i];
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   423
                int pos = dst.position();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   424
                int lim = dst.limit();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   425
                assert (pos <= lim);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   426
                int rem = (pos <= lim ? lim - pos : 0);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   427
                long a;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   428
                if (!(dst instanceof DirectBuffer)) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   429
                    // substitute with direct buffer
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   430
                    ByteBuffer bb = Util.getTemporaryDirectBuffer(rem);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   431
                    shadow[i] = bb;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   432
                    a = ((DirectBuffer)bb).address();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   433
                } else {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   434
                    shadow[i] = dst;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   435
                    a = ((DirectBuffer)dst).address() + pos;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   436
                }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   437
                unsafe.putAddress(address + OFFSETOF_BUF, a);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   438
                unsafe.putInt(address + OFFSETOF_LEN, rem);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   439
                address += SIZEOF_WSABUF;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   440
            }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   441
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   442
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   443
        /**
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   444
         * Invoked after a read has completed to update the buffer positions
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   445
         * and release any substituted buffers.
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   446
         */
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   447
        void updateBuffers(int bytesRead) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   448
            for (int i=0; i<numBufs; i++) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   449
                ByteBuffer nextBuffer = shadow[i];
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   450
                int pos = nextBuffer.position();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   451
                int len = nextBuffer.remaining();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   452
                if (bytesRead >= len) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   453
                    bytesRead -= len;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   454
                    int newPosition = pos + len;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   455
                    try {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   456
                        nextBuffer.position(newPosition);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   457
                    } catch (IllegalArgumentException x) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   458
                        // position changed by another
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   459
                    }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   460
                } else { // Buffers not completely filled
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   461
                    if (bytesRead > 0) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   462
                        assert(pos + bytesRead < (long)Integer.MAX_VALUE);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   463
                        int newPosition = pos + bytesRead;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   464
                        try {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   465
                            nextBuffer.position(newPosition);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   466
                        } catch (IllegalArgumentException x) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   467
                            // position changed by another
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   468
                        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   469
                    }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   470
                    break;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   471
                }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   472
            }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   473
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   474
            // Put results from shadow into the slow buffers
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   475
            for (int i=0; i<numBufs; i++) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   476
                if (!(bufs[i] instanceof DirectBuffer)) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   477
                    shadow[i].flip();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   478
                    try {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   479
                        bufs[i].put(shadow[i]);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   480
                    } catch (BufferOverflowException x) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   481
                        // position changed by another
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   482
                    }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   483
                }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   484
            }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   485
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   486
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   487
        void releaseBuffers() {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   488
            for (int i=0; i<numBufs; i++) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   489
                if (!(bufs[i] instanceof DirectBuffer)) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   490
                    Util.releaseTemporaryDirectBuffer(shadow[i]);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   491
                }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   492
            }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   493
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   494
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   495
        @Override
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   496
        @SuppressWarnings("unchecked")
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   497
        public void run() {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   498
            long overlapped = 0L;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   499
            boolean prepared = false;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   500
            boolean pending = false;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   501
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   502
            try {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   503
                begin();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   504
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   505
                // substitute non-direct buffers
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   506
                prepareBuffers();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   507
                prepared = true;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   508
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   509
                // get an OVERLAPPED structure (from the cache or allocate)
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   510
                overlapped = ioCache.add(result);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   511
2705
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   512
                // initiate read
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   513
                int n = read0(handle, numBufs, readBufferArray, overlapped);
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   514
                if (n == IOStatus.UNAVAILABLE) {
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   515
                    // I/O is pending
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   516
                    pending = true;
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   517
                    return;
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   518
                }
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   519
                if (n == IOStatus.EOF) {
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   520
                    // input shutdown
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   521
                    enableReading();
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   522
                    if (scatteringRead) {
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   523
                        result.setResult((V)Long.valueOf(-1L));
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   524
                    } else {
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   525
                        result.setResult((V)Integer.valueOf(-1));
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   526
                    }
2705
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   527
                } else {
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   528
                    throw new InternalError("Read completed immediately");
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   529
                }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   530
            } catch (Throwable x) {
2705
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   531
                // failed to initiate read
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   532
                // reset read flag before releasing waiters
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   533
                enableReading();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   534
                if (x instanceof ClosedChannelException)
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   535
                    x = new AsynchronousCloseException();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   536
                if (!(x instanceof IOException))
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   537
                    x = new IOException(x);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   538
                result.setFailure(x);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   539
            } finally {
2705
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   540
                // release resources if I/O not pending
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   541
                if (!pending) {
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   542
                    if (overlapped != 0L)
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   543
                        ioCache.remove(overlapped);
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   544
                    if (prepared)
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   545
                        releaseBuffers();
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   546
                }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   547
                end();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   548
            }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   549
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   550
            // invoke completion handler
3632
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   551
            Invoker.invoke(result);
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   552
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   553
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   554
        /**
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   555
         * Executed when the I/O has completed
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   556
         */
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   557
        @Override
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   558
        @SuppressWarnings("unchecked")
3632
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   559
        public void completed(int bytesTransferred, boolean canInvokeDirect) {
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   560
            if (bytesTransferred == 0) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   561
                bytesTransferred = -1;  // EOF
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   562
            } else {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   563
                updateBuffers(bytesTransferred);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   564
            }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   565
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   566
            // return direct buffer to cache if substituted
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   567
            releaseBuffers();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   568
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   569
            // release waiters if not already released by timeout
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   570
            synchronized (result) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   571
                if (result.isDone())
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   572
                    return;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   573
                enableReading();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   574
                if (scatteringRead) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   575
                    result.setResult((V)Long.valueOf(bytesTransferred));
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   576
                } else {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   577
                    result.setResult((V)Integer.valueOf(bytesTransferred));
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   578
                }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   579
            }
3632
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   580
            if (canInvokeDirect) {
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   581
                Invoker.invokeUnchecked(result);
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   582
            } else {
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   583
                Invoker.invoke(result);
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   584
            }
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   585
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   586
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   587
        @Override
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   588
        public void failed(int error, IOException x) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   589
            // return direct buffer to cache if substituted
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   590
            releaseBuffers();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   591
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   592
            // release waiters if not already released by timeout
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   593
            if (!isOpen())
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   594
                x = new AsynchronousCloseException();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   595
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   596
            synchronized (result) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   597
                if (result.isDone())
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   598
                    return;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   599
                enableReading();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   600
                result.setFailure(x);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   601
            }
3632
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   602
            Invoker.invoke(result);
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   603
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   604
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   605
        /**
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   606
         * Invoked if timeout expires before it is cancelled
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   607
         */
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   608
        void timeout() {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   609
            // synchronize on result as the I/O could complete/fail
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   610
            synchronized (result) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   611
                if (result.isDone())
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   612
                    return;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   613
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   614
                // kill further reading before releasing waiters
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   615
                enableReading(true);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   616
                result.setFailure(new InterruptedByTimeoutException());
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   617
            }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   618
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   619
            // invoke handler without any locks
3632
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   620
            Invoker.invoke(result);
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   621
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   622
    }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   623
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   624
    @Override
3632
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   625
    <V extends Number,A> Future<V> implRead(boolean isScatteringRead,
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   626
                                            ByteBuffer dst,
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   627
                                            ByteBuffer[] dsts,
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   628
                                            long timeout,
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   629
                                            TimeUnit unit,
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   630
                                            A attachment,
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   631
                                            CompletionHandler<V,? super A> handler)
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   632
    {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   633
        // setup task
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   634
        PendingFuture<V,A> result =
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   635
            new PendingFuture<V,A>(this, handler, attachment);
3632
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   636
        ByteBuffer[] bufs;
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   637
        if (isScatteringRead) {
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   638
            bufs = dsts;
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   639
        } else {
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   640
            bufs = new ByteBuffer[1];
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   641
            bufs[0] = dst;
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   642
        }
10137
d92637d3d673 7068616: NIO libraries do not build with javac -Xlint:all,-deprecation -Werror
jjg
parents: 9035
diff changeset
   643
        final ReadTask<V,A> readTask =
d92637d3d673 7068616: NIO libraries do not build with javac -Xlint:all,-deprecation -Werror
jjg
parents: 9035
diff changeset
   644
                new ReadTask<V,A>(bufs, isScatteringRead, result);
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   645
        result.setContext(readTask);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   646
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   647
        // schedule timeout
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   648
        if (timeout > 0L) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   649
            Future<?> timeoutTask = iocp.schedule(new Runnable() {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   650
                public void run() {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   651
                    readTask.timeout();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   652
                }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   653
            }, timeout, unit);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   654
            result.setTimeoutTask(timeoutTask);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   655
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   656
3632
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   657
        // initiate I/O
37371
12cf839a9b2d 8154455: Fix compilation issue in WindowsAsynchronousSocketChannelImpl
redestad
parents: 37369
diff changeset
   658
        readTask.run();
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   659
        return result;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   660
    }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   661
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   662
    /**
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   663
     * Implements the task to initiate a write and the handler to consume the
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   664
     * result when the write completes.
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   665
     */
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   666
    private class WriteTask<V,A> implements Runnable, Iocp.ResultHandler {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   667
        private final ByteBuffer[] bufs;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   668
        private final int numBufs;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   669
        private final boolean gatheringWrite;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   670
        private final PendingFuture<V,A> result;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   671
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   672
        // set by run method
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   673
        private ByteBuffer[] shadow;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   674
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   675
        WriteTask(ByteBuffer[] bufs,
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   676
                  boolean gatheringWrite,
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   677
                  PendingFuture<V,A> result)
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   678
        {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   679
            this.bufs = bufs;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   680
            this.numBufs = (bufs.length > MAX_WSABUF) ? MAX_WSABUF : bufs.length;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   681
            this.gatheringWrite = gatheringWrite;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   682
            this.result = result;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   683
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   684
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   685
        /**
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   686
         * Invoked prior to write to prepare the WSABUF array. Where necessary,
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   687
         * it substitutes non-direct buffers with direct buffers.
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   688
         */
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   689
        void prepareBuffers() {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   690
            shadow = new ByteBuffer[numBufs];
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   691
            long address = writeBufferArray;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   692
            for (int i=0; i<numBufs; i++) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   693
                ByteBuffer src = bufs[i];
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   694
                int pos = src.position();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   695
                int lim = src.limit();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   696
                assert (pos <= lim);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   697
                int rem = (pos <= lim ? lim - pos : 0);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   698
                long a;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   699
                if (!(src instanceof DirectBuffer)) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   700
                    // substitute with direct buffer
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   701
                    ByteBuffer bb = Util.getTemporaryDirectBuffer(rem);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   702
                    bb.put(src);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   703
                    bb.flip();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   704
                    src.position(pos);  // leave heap buffer untouched for now
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   705
                    shadow[i] = bb;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   706
                    a = ((DirectBuffer)bb).address();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   707
                } else {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   708
                    shadow[i] = src;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   709
                    a = ((DirectBuffer)src).address() + pos;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   710
                }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   711
                unsafe.putAddress(address + OFFSETOF_BUF, a);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   712
                unsafe.putInt(address + OFFSETOF_LEN, rem);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   713
                address += SIZEOF_WSABUF;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   714
            }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   715
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   716
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   717
        /**
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   718
         * Invoked after a write has completed to update the buffer positions
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   719
         * and release any substituted buffers.
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   720
         */
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   721
        void updateBuffers(int bytesWritten) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   722
            // Notify the buffers how many bytes were taken
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   723
            for (int i=0; i<numBufs; i++) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   724
                ByteBuffer nextBuffer = bufs[i];
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   725
                int pos = nextBuffer.position();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   726
                int lim = nextBuffer.limit();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   727
                int len = (pos <= lim ? lim - pos : lim);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   728
                if (bytesWritten >= len) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   729
                    bytesWritten -= len;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   730
                    int newPosition = pos + len;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   731
                    try {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   732
                        nextBuffer.position(newPosition);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   733
                    } catch (IllegalArgumentException x) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   734
                        // position changed by someone else
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   735
                    }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   736
                } else { // Buffers not completely filled
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   737
                    if (bytesWritten > 0) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   738
                        assert(pos + bytesWritten < (long)Integer.MAX_VALUE);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   739
                        int newPosition = pos + bytesWritten;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   740
                        try {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   741
                            nextBuffer.position(newPosition);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   742
                        } catch (IllegalArgumentException x) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   743
                            // position changed by someone else
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   744
                        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   745
                    }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   746
                    break;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   747
                }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   748
            }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   749
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   750
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   751
        void releaseBuffers() {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   752
            for (int i=0; i<numBufs; i++) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   753
                if (!(bufs[i] instanceof DirectBuffer)) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   754
                    Util.releaseTemporaryDirectBuffer(shadow[i]);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   755
                }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   756
            }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   757
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   758
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   759
        @Override
3632
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   760
        //@SuppressWarnings("unchecked")
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   761
        public void run() {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   762
            long overlapped = 0L;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   763
            boolean prepared = false;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   764
            boolean pending = false;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   765
            boolean shutdown = false;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   766
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   767
            try {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   768
                begin();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   769
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   770
                // substitute non-direct buffers
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   771
                prepareBuffers();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   772
                prepared = true;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   773
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   774
                // get an OVERLAPPED structure (from the cache or allocate)
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   775
                overlapped = ioCache.add(result);
2705
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   776
                int n = write0(handle, numBufs, writeBufferArray, overlapped);
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   777
                if (n == IOStatus.UNAVAILABLE) {
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   778
                    // I/O is pending
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   779
                    pending = true;
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   780
                    return;
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   781
                }
2705
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   782
                if (n == IOStatus.EOF) {
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   783
                    // special case for shutdown output
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   784
                    shutdown = true;
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   785
                    throw new ClosedChannelException();
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   786
                }
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   787
                // write completed immediately
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   788
                throw new InternalError("Write completed immediately");
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   789
            } catch (Throwable x) {
2705
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   790
                // write failed. Enable writing before releasing waiters.
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   791
                enableWriting();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   792
                if (!shutdown && (x instanceof ClosedChannelException))
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   793
                    x = new AsynchronousCloseException();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   794
                if (!(x instanceof IOException))
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   795
                    x = new IOException(x);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   796
                result.setFailure(x);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   797
            } finally {
2705
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   798
                // release resources if I/O not pending
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   799
                if (!pending) {
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   800
                    if (overlapped != 0L)
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   801
                        ioCache.remove(overlapped);
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   802
                    if (prepared)
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   803
                        releaseBuffers();
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   804
                }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   805
                end();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   806
            }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   807
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   808
            // invoke completion handler
3632
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   809
            Invoker.invoke(result);
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   810
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   811
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   812
        /**
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   813
         * Executed when the I/O has completed
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   814
         */
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   815
        @Override
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   816
        @SuppressWarnings("unchecked")
3632
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   817
        public void completed(int bytesTransferred, boolean canInvokeDirect) {
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   818
            updateBuffers(bytesTransferred);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   819
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   820
            // return direct buffer to cache if substituted
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   821
            releaseBuffers();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   822
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   823
            // release waiters if not already released by timeout
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   824
            synchronized (result) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   825
                if (result.isDone())
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   826
                    return;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   827
                enableWriting();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   828
                if (gatheringWrite) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   829
                    result.setResult((V)Long.valueOf(bytesTransferred));
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   830
                } else {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   831
                    result.setResult((V)Integer.valueOf(bytesTransferred));
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   832
                }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   833
            }
3632
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   834
            if (canInvokeDirect) {
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   835
                Invoker.invokeUnchecked(result);
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   836
            } else {
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   837
                Invoker.invoke(result);
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   838
            }
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   839
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   840
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   841
        @Override
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   842
        public void failed(int error, IOException x) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   843
            // return direct buffer to cache if substituted
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   844
            releaseBuffers();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   845
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   846
            // release waiters if not already released by timeout
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   847
            if (!isOpen())
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   848
                x = new AsynchronousCloseException();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   849
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   850
            synchronized (result) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   851
                if (result.isDone())
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   852
                    return;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   853
                enableWriting();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   854
                result.setFailure(x);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   855
            }
3632
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   856
            Invoker.invoke(result);
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   857
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   858
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   859
        /**
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   860
         * Invoked if timeout expires before it is cancelled
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   861
         */
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   862
        void timeout() {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   863
            // synchronize on result as the I/O could complete/fail
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   864
            synchronized (result) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   865
                if (result.isDone())
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   866
                    return;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   867
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   868
                // kill further writing before releasing waiters
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   869
                enableWriting(true);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   870
                result.setFailure(new InterruptedByTimeoutException());
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   871
            }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   872
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   873
            // invoke handler without any locks
3632
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   874
            Invoker.invoke(result);
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   875
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   876
    }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   877
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   878
    @Override
3632
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   879
    <V extends Number,A> Future<V> implWrite(boolean gatheringWrite,
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   880
                                             ByteBuffer src,
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   881
                                             ByteBuffer[] srcs,
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   882
                                             long timeout,
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   883
                                             TimeUnit unit,
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   884
                                             A attachment,
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   885
                                             CompletionHandler<V,? super A> handler)
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   886
    {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   887
        // setup task
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   888
        PendingFuture<V,A> result =
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   889
            new PendingFuture<V,A>(this, handler, attachment);
3632
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   890
        ByteBuffer[] bufs;
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   891
        if (gatheringWrite) {
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   892
            bufs = srcs;
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   893
        } else {
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   894
            bufs = new ByteBuffer[1];
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   895
            bufs[0] = src;
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   896
        }
10137
d92637d3d673 7068616: NIO libraries do not build with javac -Xlint:all,-deprecation -Werror
jjg
parents: 9035
diff changeset
   897
        final WriteTask<V,A> writeTask =
d92637d3d673 7068616: NIO libraries do not build with javac -Xlint:all,-deprecation -Werror
jjg
parents: 9035
diff changeset
   898
                new WriteTask<V,A>(bufs, gatheringWrite, result);
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   899
        result.setContext(writeTask);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   900
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   901
        // schedule timeout
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   902
        if (timeout > 0L) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   903
            Future<?> timeoutTask = iocp.schedule(new Runnable() {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   904
                public void run() {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   905
                    writeTask.timeout();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   906
                }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   907
            }, timeout, unit);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   908
            result.setTimeoutTask(timeoutTask);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   909
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   910
3632
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   911
        // initiate I/O
37371
12cf839a9b2d 8154455: Fix compilation issue in WindowsAsynchronousSocketChannelImpl
redestad
parents: 37369
diff changeset
   912
        writeTask.run();
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   913
        return result;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   914
    }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   915
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   916
    // -- Native methods --
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   917
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   918
    private static native void initIDs();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   919
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   920
    private static native int connect0(long socket, boolean preferIPv6,
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   921
        InetAddress remote, int remotePort, long overlapped) throws IOException;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   922
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   923
    private static native void updateConnectContext(long socket) throws IOException;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   924
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   925
    private static native int read0(long socket, int count, long addres, long overlapped)
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   926
        throws IOException;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   927
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   928
    private static native int write0(long socket, int count, long address,
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   929
        long overlapped) throws IOException;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   930
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   931
    private static native void shutdown0(long socket, int how) throws IOException;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   932
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   933
    private static native void closesocket0(long socket) throws IOException;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   934
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   935
    static {
19607
bee007586d06 8022594: Potential deadlock in <clinit> of sun.nio.ch.Util/IOUtil
alanb
parents: 18212
diff changeset
   936
        IOUtil.load();
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   937
        initIDs();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   938
    }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   939
}