jdk/src/windows/classes/sun/nio/ch/WindowsAsynchronousSocketChannelImpl.java
author khazra
Thu, 28 Mar 2013 14:34:18 -0700
changeset 18212 22f8c33b0690
parent 10137 d92637d3d673
child 19607 bee007586d06
permissions -rw-r--r--
8001318: Socket.getLocalAddress not consistent with InetAddress.getLocalHost Reviewed-by: alanb, chegar, hawtin
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
/*
9035
1255eb81cc2f 7033660: Update copyright year to 2011 on any files changed in 2011
ohair
parents: 8568
diff changeset
     2
 * Copyright (c) 2008, 2011, 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;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    34
import sun.misc.Unsafe;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    35
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    36
/**
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    37
 * 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
    38
 */
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
class WindowsAsynchronousSocketChannelImpl
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    41
    extends AsynchronousSocketChannelImpl implements Iocp.OverlappedChannel
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
    private static final Unsafe unsafe = Unsafe.getUnsafe();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    44
    private static int addressSize = unsafe.addressSize();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    45
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    46
    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
    47
        return (addressSize == 4) ? value32 : value64;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    48
    }
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
    /*
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    51
     * typedef struct _WSABUF {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    52
     *     u_long      len;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    53
     *     char FAR *  buf;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    54
     * } WSABUF;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    55
     */
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    56
    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
    57
    private static final int OFFSETOF_LEN   = 0;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    58
    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
    59
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    60
    // 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
    61
    private static final int MAX_WSABUF     = 16;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    62
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    63
    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
    64
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    65
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    66
    // 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
    67
    final long handle;
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
    // 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
    70
    private final Iocp iocp;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    71
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    72
    // 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
    73
    private final int completionKey;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    74
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    75
    // 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
    76
    // 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
    77
    // 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
    78
    // 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
    79
    private final PendingIoCache ioCache;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    80
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    81
    // per-channel arrays of WSABUF structures
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    82
    private final long readBufferArray;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    83
    private final long writeBufferArray;
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
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    86
    WindowsAsynchronousSocketChannelImpl(Iocp iocp, boolean failIfGroupShutdown)
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    87
        throws IOException
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
        super(iocp);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    90
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    91
        // associate socket with default completion port
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    92
        long h = IOUtil.fdVal(fd);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    93
        int key = 0;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    94
        try {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    95
            key = iocp.associate(this, h);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    96
        } catch (ShutdownChannelGroupException x) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    97
            if (failIfGroupShutdown) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    98
                closesocket0(h);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
    99
                throw x;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   100
            }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   101
        } catch (IOException x) {
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
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   106
        this.handle = h;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   107
        this.iocp = iocp;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   108
        this.completionKey = key;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   109
        this.ioCache = new PendingIoCache();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   110
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   111
        // allocate WSABUF arrays
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   112
        this.readBufferArray = unsafe.allocateMemory(SIZEOF_WSABUFARRAY);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   113
        this.writeBufferArray = unsafe.allocateMemory(SIZEOF_WSABUFARRAY);
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
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   116
    WindowsAsynchronousSocketChannelImpl(Iocp iocp) throws IOException {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   117
        this(iocp, true);
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
    @Override
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   121
    public AsynchronousChannelGroupImpl group() {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   122
        return iocp;
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
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   125
    /**
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   126
     * 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
   127
     */
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   128
    @Override
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   129
    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
   130
        return ioCache.remove(overlapped);
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
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   133
    // invoked by WindowsAsynchronousServerSocketChannelImpl
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   134
    long handle() {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   135
        return handle;
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
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   138
    // invoked by WindowsAsynchronousServerSocketChannelImpl when new connection
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   139
    // accept
18212
22f8c33b0690 8001318: Socket.getLocalAddress not consistent with InetAddress.getLocalHost
khazra
parents: 10137
diff changeset
   140
    void setConnected(InetSocketAddress localAddress,
22f8c33b0690 8001318: Socket.getLocalAddress not consistent with InetAddress.getLocalHost
khazra
parents: 10137
diff changeset
   141
                      InetSocketAddress remoteAddress)
22f8c33b0690 8001318: Socket.getLocalAddress not consistent with InetAddress.getLocalHost
khazra
parents: 10137
diff changeset
   142
    {
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   143
        synchronized (stateLock) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   144
            state = ST_CONNECTED;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   145
            this.localAddress = localAddress;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   146
            this.remoteAddress = remoteAddress;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   147
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   148
    }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   149
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   150
    @Override
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   151
    void implClose() throws IOException {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   152
        // 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
   153
        closesocket0(handle);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   154
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   155
        // 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
   156
        ioCache.close();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   157
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   158
        // release arrays of WSABUF structures
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   159
        unsafe.freeMemory(readBufferArray);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   160
        unsafe.freeMemory(writeBufferArray);
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
        // 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
   163
        // channel created when group is shutdown)
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   164
        if (completionKey != 0)
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   165
            iocp.disassociate(completionKey);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   166
    }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   167
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   168
    @Override
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   169
    public void onCancel(PendingFuture<?,?> task) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   170
        if (task.getContext() instanceof ConnectTask)
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   171
            killConnect();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   172
        if (task.getContext() instanceof ReadTask)
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   173
            killReading();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   174
        if (task.getContext() instanceof WriteTask)
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   175
            killWriting();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   176
    }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   177
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   178
    /**
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   179
     * 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
   180
     * 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
   181
     */
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   182
    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
   183
        private final InetSocketAddress remote;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   184
        private final PendingFuture<Void,A> result;
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
        ConnectTask(InetSocketAddress remote, PendingFuture<Void,A> result) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   187
            this.remote = remote;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   188
            this.result = 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
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   191
        private void closeChannel() {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   192
            try {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   193
                close();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   194
            } catch (IOException ignore) { }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   195
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   196
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   197
        private IOException toIOException(Throwable x) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   198
            if (x instanceof IOException) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   199
                if (x instanceof ClosedChannelException)
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   200
                    x = new AsynchronousCloseException();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   201
                return (IOException)x;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   202
            }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   203
            return new IOException(x);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   204
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   205
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
         * Invoke after a connection is successfully established.
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
        private void afterConnect() throws IOException {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   210
            updateConnectContext(handle);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   211
            synchronized (stateLock) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   212
                state = ST_CONNECTED;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   213
                remoteAddress = remote;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   214
            }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   215
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   216
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   217
        /**
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   218
         * Task to initiate a connection.
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
        @Override
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   221
        public void run() {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   222
            long overlapped = 0L;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   223
            Throwable exc = null;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   224
            try {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   225
                begin();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   226
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   227
                // 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
   228
                // where the connection is established immediately.
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   229
                synchronized (result) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   230
                    overlapped = ioCache.add(result);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   231
                    // initiate the connection
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   232
                    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
   233
                                     remote.getPort(), overlapped);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   234
                    if (n == IOStatus.UNAVAILABLE) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   235
                        // connection is pending
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   236
                        return;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   237
                    }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   238
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   239
                    // connection established immediately
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   240
                    afterConnect();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   241
                    result.setResult(null);
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
            } catch (Throwable x) {
8568
f59001e07166 6944810: (ch) Assert failure in sun.nio.ch.PendingIoCache.clearPendingIoMap [win]
alanb
parents: 5506
diff changeset
   244
                if (overlapped != 0L)
f59001e07166 6944810: (ch) Assert failure in sun.nio.ch.PendingIoCache.clearPendingIoMap [win]
alanb
parents: 5506
diff changeset
   245
                    ioCache.remove(overlapped);
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   246
                exc = x;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   247
            } finally {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   248
                end();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   249
            }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   250
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   251
            if (exc != null) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   252
                closeChannel();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   253
                result.setFailure(toIOException(exc));
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   254
            }
3632
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   255
            Invoker.invoke(result);
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   256
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   257
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   258
        /**
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   259
         * Invoked by handler thread when connection established.
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   260
         */
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   261
        @Override
3632
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   262
        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
   263
            Throwable exc = null;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   264
            try {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   265
                begin();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   266
                afterConnect();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   267
                result.setResult(null);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   268
            } catch (Throwable x) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   269
                // 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
   270
                exc = x;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   271
            } finally {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   272
                end();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   273
            }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   274
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   275
            // 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
   276
            if (exc != null) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   277
                closeChannel();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   278
                result.setFailure(toIOException(exc));
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
3632
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   281
            if (canInvokeDirect) {
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   282
                Invoker.invokeUnchecked(result);
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   283
            } else {
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   284
                Invoker.invoke(result);
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   285
            }
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
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   288
        /**
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   289
         * 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
   290
         */
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   291
        @Override
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   292
        public void failed(int error, IOException x) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   293
            if (isOpen()) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   294
                closeChannel();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   295
                result.setFailure(x);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   296
            } else {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   297
                result.setFailure(new AsynchronousCloseException());
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   298
            }
3632
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   299
            Invoker.invoke(result);
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   300
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   301
    }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   302
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   303
    @Override
3632
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   304
    <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
   305
                                 A attachment,
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   306
                                 CompletionHandler<Void,? super A> handler)
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   307
    {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   308
        if (!isOpen()) {
3632
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   309
            Throwable exc = new ClosedChannelException();
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   310
            if (handler == null)
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   311
                return CompletedFuture.withFailure(exc);
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   312
            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
   313
            return null;
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   314
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   315
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   316
        InetSocketAddress isa = Net.checkAddress(remote);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   317
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   318
        // permission check
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   319
        SecurityManager sm = System.getSecurityManager();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   320
        if (sm != null)
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   321
            sm.checkConnect(isa.getAddress().getHostAddress(), isa.getPort());
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   322
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   323
        // check and update state
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   324
        // 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
   325
        IOException bindException = null;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   326
        synchronized (stateLock) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   327
            if (state == ST_CONNECTED)
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   328
                throw new AlreadyConnectedException();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   329
            if (state == ST_PENDING)
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   330
                throw new ConnectionPendingException();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   331
            if (localAddress == null) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   332
                try {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   333
                    bind(new InetSocketAddress(0));
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   334
                } catch (IOException x) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   335
                    bindException = x;
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
            if (bindException == null)
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   339
                state = ST_PENDING;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   340
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   341
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   342
        // handle bind failure
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   343
        if (bindException != null) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   344
            try {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   345
                close();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   346
            } catch (IOException ignore) { }
3632
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   347
            if (handler == null)
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   348
                return CompletedFuture.withFailure(bindException);
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   349
            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
   350
            return null;
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   351
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   352
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   353
        // setup task
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   354
        PendingFuture<Void,A> result =
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   355
            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
   356
        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
   357
        result.setContext(task);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   358
3632
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   359
        // initiate I/O
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   360
        if (Iocp.supportsThreadAgnosticIo()) {
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   361
            task.run();
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   362
        } else {
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   363
            Invoker.invokeOnThreadInThreadPool(this, task);
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   364
        }
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   365
        return result;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   366
    }
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
     * 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
   370
     * result when the read completes.
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   371
     */
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   372
    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
   373
        private final ByteBuffer[] bufs;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   374
        private final int numBufs;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   375
        private final boolean scatteringRead;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   376
        private final PendingFuture<V,A> result;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   377
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   378
        // set by run method
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   379
        private ByteBuffer[] shadow;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   380
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   381
        ReadTask(ByteBuffer[] bufs,
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   382
                 boolean scatteringRead,
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   383
                 PendingFuture<V,A> result)
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   384
        {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   385
            this.bufs = bufs;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   386
            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
   387
            this.scatteringRead = scatteringRead;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   388
            this.result = 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
         * 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
   393
         * 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
   394
         */
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   395
        void prepareBuffers() {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   396
            shadow = new ByteBuffer[numBufs];
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   397
            long address = readBufferArray;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   398
            for (int i=0; i<numBufs; i++) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   399
                ByteBuffer dst = bufs[i];
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   400
                int pos = dst.position();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   401
                int lim = dst.limit();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   402
                assert (pos <= lim);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   403
                int rem = (pos <= lim ? lim - pos : 0);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   404
                long a;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   405
                if (!(dst instanceof DirectBuffer)) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   406
                    // substitute with direct buffer
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   407
                    ByteBuffer bb = Util.getTemporaryDirectBuffer(rem);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   408
                    shadow[i] = bb;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   409
                    a = ((DirectBuffer)bb).address();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   410
                } else {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   411
                    shadow[i] = dst;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   412
                    a = ((DirectBuffer)dst).address() + pos;
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
                unsafe.putAddress(address + OFFSETOF_BUF, a);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   415
                unsafe.putInt(address + OFFSETOF_LEN, rem);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   416
                address += SIZEOF_WSABUF;
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
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   419
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   420
        /**
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   421
         * 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
   422
         * and release any substituted buffers.
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   423
         */
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   424
        void updateBuffers(int bytesRead) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   425
            for (int i=0; i<numBufs; i++) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   426
                ByteBuffer nextBuffer = shadow[i];
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   427
                int pos = nextBuffer.position();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   428
                int len = nextBuffer.remaining();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   429
                if (bytesRead >= len) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   430
                    bytesRead -= len;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   431
                    int newPosition = pos + len;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   432
                    try {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   433
                        nextBuffer.position(newPosition);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   434
                    } catch (IllegalArgumentException x) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   435
                        // position changed by another
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
                } else { // Buffers not completely filled
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   438
                    if (bytesRead > 0) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   439
                        assert(pos + bytesRead < (long)Integer.MAX_VALUE);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   440
                        int newPosition = pos + bytesRead;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   441
                        try {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   442
                            nextBuffer.position(newPosition);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   443
                        } catch (IllegalArgumentException x) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   444
                            // position changed by another
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   445
                        }
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
                    break;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   448
                }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   449
            }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   450
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   451
            // 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
   452
            for (int i=0; i<numBufs; i++) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   453
                if (!(bufs[i] instanceof DirectBuffer)) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   454
                    shadow[i].flip();
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
                        bufs[i].put(shadow[i]);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   457
                    } catch (BufferOverflowException 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
                }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   461
            }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   462
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   463
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   464
        void releaseBuffers() {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   465
            for (int i=0; i<numBufs; i++) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   466
                if (!(bufs[i] instanceof DirectBuffer)) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   467
                    Util.releaseTemporaryDirectBuffer(shadow[i]);
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
        }
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
        @Override
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   473
        @SuppressWarnings("unchecked")
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   474
        public void run() {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   475
            long overlapped = 0L;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   476
            boolean prepared = false;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   477
            boolean pending = false;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   478
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   479
            try {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   480
                begin();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   481
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   482
                // substitute non-direct buffers
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   483
                prepareBuffers();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   484
                prepared = true;
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
                // 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
   487
                overlapped = ioCache.add(result);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   488
2705
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   489
                // initiate read
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   490
                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
   491
                if (n == IOStatus.UNAVAILABLE) {
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   492
                    // I/O is pending
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   493
                    pending = true;
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   494
                    return;
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   495
                }
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   496
                if (n == IOStatus.EOF) {
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   497
                    // input shutdown
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   498
                    enableReading();
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   499
                    if (scatteringRead) {
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   500
                        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
   501
                    } else {
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   502
                        result.setResult((V)Integer.valueOf(-1));
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   503
                    }
2705
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   504
                } else {
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   505
                    throw new InternalError("Read completed immediately");
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   506
                }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   507
            } catch (Throwable x) {
2705
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   508
                // failed to initiate read
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   509
                // reset read flag before releasing waiters
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   510
                enableReading();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   511
                if (x instanceof ClosedChannelException)
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   512
                    x = new AsynchronousCloseException();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   513
                if (!(x instanceof IOException))
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   514
                    x = new IOException(x);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   515
                result.setFailure(x);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   516
            } finally {
2705
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   517
                // 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
   518
                if (!pending) {
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   519
                    if (overlapped != 0L)
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   520
                        ioCache.remove(overlapped);
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   521
                    if (prepared)
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   522
                        releaseBuffers();
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   523
                }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   524
                end();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   525
            }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   526
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   527
            // invoke completion handler
3632
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   528
            Invoker.invoke(result);
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
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   531
        /**
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   532
         * Executed when the I/O has completed
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   533
         */
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   534
        @Override
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   535
        @SuppressWarnings("unchecked")
3632
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   536
        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
   537
            if (bytesTransferred == 0) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   538
                bytesTransferred = -1;  // EOF
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   539
            } else {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   540
                updateBuffers(bytesTransferred);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   541
            }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   542
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   543
            // return direct buffer to cache if substituted
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   544
            releaseBuffers();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   545
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   546
            // 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
   547
            synchronized (result) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   548
                if (result.isDone())
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   549
                    return;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   550
                enableReading();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   551
                if (scatteringRead) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   552
                    result.setResult((V)Long.valueOf(bytesTransferred));
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   553
                } else {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   554
                    result.setResult((V)Integer.valueOf(bytesTransferred));
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   555
                }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   556
            }
3632
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   557
            if (canInvokeDirect) {
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   558
                Invoker.invokeUnchecked(result);
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   559
            } else {
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   560
                Invoker.invoke(result);
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   561
            }
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   562
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   563
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   564
        @Override
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   565
        public void failed(int error, IOException x) {
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
            if (!isOpen())
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   571
                x = new AsynchronousCloseException();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   572
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   573
            synchronized (result) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   574
                if (result.isDone())
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   575
                    return;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   576
                enableReading();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   577
                result.setFailure(x);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   578
            }
3632
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   579
            Invoker.invoke(result);
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   580
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   581
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   582
        /**
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   583
         * 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
   584
         */
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   585
        void timeout() {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   586
            // 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
   587
            synchronized (result) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   588
                if (result.isDone())
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   589
                    return;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   590
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   591
                // kill further reading before releasing waiters
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   592
                enableReading(true);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   593
                result.setFailure(new InterruptedByTimeoutException());
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   594
            }
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
            // 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
   597
            Invoker.invoke(result);
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   598
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   599
    }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   600
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   601
    @Override
3632
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   602
    <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
   603
                                            ByteBuffer dst,
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   604
                                            ByteBuffer[] dsts,
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   605
                                            long timeout,
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   606
                                            TimeUnit unit,
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   607
                                            A attachment,
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   608
                                            CompletionHandler<V,? super A> handler)
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   609
    {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   610
        // setup task
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   611
        PendingFuture<V,A> result =
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   612
            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
   613
        ByteBuffer[] bufs;
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   614
        if (isScatteringRead) {
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   615
            bufs = dsts;
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   616
        } else {
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   617
            bufs = new ByteBuffer[1];
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   618
            bufs[0] = dst;
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   619
        }
10137
d92637d3d673 7068616: NIO libraries do not build with javac -Xlint:all,-deprecation -Werror
jjg
parents: 9035
diff changeset
   620
        final ReadTask<V,A> readTask =
d92637d3d673 7068616: NIO libraries do not build with javac -Xlint:all,-deprecation -Werror
jjg
parents: 9035
diff changeset
   621
                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
   622
        result.setContext(readTask);
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
        // schedule timeout
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   625
        if (timeout > 0L) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   626
            Future<?> timeoutTask = iocp.schedule(new Runnable() {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   627
                public void run() {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   628
                    readTask.timeout();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   629
                }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   630
            }, timeout, unit);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   631
            result.setTimeoutTask(timeoutTask);
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
3632
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   634
        // initiate I/O
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   635
        if (Iocp.supportsThreadAgnosticIo()) {
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   636
            readTask.run();
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   637
        } else {
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   638
            Invoker.invokeOnThreadInThreadPool(this, readTask);
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   639
        }
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   640
        return result;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   641
    }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   642
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   643
    /**
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   644
     * 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
   645
     * result when the write completes.
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
    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
   648
        private final ByteBuffer[] bufs;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   649
        private final int numBufs;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   650
        private final boolean gatheringWrite;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   651
        private final PendingFuture<V,A> result;
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
        // set by run method
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   654
        private ByteBuffer[] shadow;
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
        WriteTask(ByteBuffer[] bufs,
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   657
                  boolean gatheringWrite,
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   658
                  PendingFuture<V,A> result)
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   659
        {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   660
            this.bufs = bufs;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   661
            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
   662
            this.gatheringWrite = gatheringWrite;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   663
            this.result = result;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   664
        }
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
        /**
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   667
         * 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
   668
         * 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
   669
         */
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   670
        void prepareBuffers() {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   671
            shadow = new ByteBuffer[numBufs];
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   672
            long address = writeBufferArray;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   673
            for (int i=0; i<numBufs; i++) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   674
                ByteBuffer src = bufs[i];
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   675
                int pos = src.position();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   676
                int lim = src.limit();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   677
                assert (pos <= lim);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   678
                int rem = (pos <= lim ? lim - pos : 0);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   679
                long a;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   680
                if (!(src instanceof DirectBuffer)) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   681
                    // substitute with direct buffer
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   682
                    ByteBuffer bb = Util.getTemporaryDirectBuffer(rem);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   683
                    bb.put(src);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   684
                    bb.flip();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   685
                    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
   686
                    shadow[i] = bb;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   687
                    a = ((DirectBuffer)bb).address();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   688
                } else {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   689
                    shadow[i] = src;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   690
                    a = ((DirectBuffer)src).address() + pos;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   691
                }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   692
                unsafe.putAddress(address + OFFSETOF_BUF, a);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   693
                unsafe.putInt(address + OFFSETOF_LEN, rem);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   694
                address += SIZEOF_WSABUF;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   695
            }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   696
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   697
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   698
        /**
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   699
         * 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
   700
         * and release any substituted buffers.
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   701
         */
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   702
        void updateBuffers(int bytesWritten) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   703
            // 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
   704
            for (int i=0; i<numBufs; i++) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   705
                ByteBuffer nextBuffer = bufs[i];
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   706
                int pos = nextBuffer.position();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   707
                int lim = nextBuffer.limit();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   708
                int len = (pos <= lim ? lim - pos : lim);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   709
                if (bytesWritten >= len) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   710
                    bytesWritten -= len;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   711
                    int newPosition = pos + len;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   712
                    try {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   713
                        nextBuffer.position(newPosition);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   714
                    } catch (IllegalArgumentException x) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   715
                        // position changed by someone else
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
                } else { // Buffers not completely filled
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   718
                    if (bytesWritten > 0) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   719
                        assert(pos + bytesWritten < (long)Integer.MAX_VALUE);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   720
                        int newPosition = pos + bytesWritten;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   721
                        try {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   722
                            nextBuffer.position(newPosition);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   723
                        } catch (IllegalArgumentException x) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   724
                            // position changed by someone else
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   725
                        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   726
                    }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   727
                    break;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   728
                }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   729
            }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   730
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   731
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   732
        void releaseBuffers() {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   733
            for (int i=0; i<numBufs; i++) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   734
                if (!(bufs[i] instanceof DirectBuffer)) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   735
                    Util.releaseTemporaryDirectBuffer(shadow[i]);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   736
                }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   737
            }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   738
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   739
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   740
        @Override
3632
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   741
        //@SuppressWarnings("unchecked")
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   742
        public void run() {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   743
            long overlapped = 0L;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   744
            boolean prepared = false;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   745
            boolean pending = false;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   746
            boolean shutdown = false;
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
            try {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   749
                begin();
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
                // substitute non-direct buffers
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   752
                prepareBuffers();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   753
                prepared = true;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   754
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   755
                // 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
   756
                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
   757
                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
   758
                if (n == IOStatus.UNAVAILABLE) {
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   759
                    // I/O is pending
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   760
                    pending = true;
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   761
                    return;
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   762
                }
2705
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   763
                if (n == IOStatus.EOF) {
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   764
                    // 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
   765
                    shutdown = true;
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   766
                    throw new ClosedChannelException();
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   767
                }
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   768
                // write completed immediately
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   769
                throw new InternalError("Write completed immediately");
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   770
            } catch (Throwable x) {
2705
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   771
                // 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
   772
                enableWriting();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   773
                if (!shutdown && (x instanceof ClosedChannelException))
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   774
                    x = new AsynchronousCloseException();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   775
                if (!(x instanceof IOException))
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   776
                    x = new IOException(x);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   777
                result.setFailure(x);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   778
            } finally {
2705
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   779
                // 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
   780
                if (!pending) {
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   781
                    if (overlapped != 0L)
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   782
                        ioCache.remove(overlapped);
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   783
                    if (prepared)
27b7f2d5e949 6834246: (ch) AsynchronousSocketChannel#write completes with wrong number of bytes written under load (win)
alanb
parents: 2284
diff changeset
   784
                        releaseBuffers();
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   785
                }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   786
                end();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   787
            }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   788
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   789
            // invoke completion handler
3632
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   790
            Invoker.invoke(result);
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   791
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   792
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   793
        /**
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   794
         * Executed when the I/O has completed
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   795
         */
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   796
        @Override
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   797
        @SuppressWarnings("unchecked")
3632
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   798
        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
   799
            updateBuffers(bytesTransferred);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   800
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   801
            // return direct buffer to cache if substituted
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   802
            releaseBuffers();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   803
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   804
            // 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
   805
            synchronized (result) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   806
                if (result.isDone())
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   807
                    return;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   808
                enableWriting();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   809
                if (gatheringWrite) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   810
                    result.setResult((V)Long.valueOf(bytesTransferred));
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   811
                } else {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   812
                    result.setResult((V)Integer.valueOf(bytesTransferred));
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   813
                }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   814
            }
3632
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   815
            if (canInvokeDirect) {
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   816
                Invoker.invokeUnchecked(result);
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   817
            } else {
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   818
                Invoker.invoke(result);
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   819
            }
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   820
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   821
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   822
        @Override
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   823
        public void failed(int error, IOException x) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   824
            // return direct buffer to cache if substituted
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   825
            releaseBuffers();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   826
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   827
            // 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
   828
            if (!isOpen())
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   829
                x = new AsynchronousCloseException();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   830
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   831
            synchronized (result) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   832
                if (result.isDone())
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   833
                    return;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   834
                enableWriting();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   835
                result.setFailure(x);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   836
            }
3632
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   837
            Invoker.invoke(result);
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   838
        }
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
         * 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
   842
         */
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   843
        void timeout() {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   844
            // 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
   845
            synchronized (result) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   846
                if (result.isDone())
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   847
                    return;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   848
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   849
                // kill further writing before releasing waiters
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   850
                enableWriting(true);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   851
                result.setFailure(new InterruptedByTimeoutException());
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   852
            }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   853
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   854
            // 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
   855
            Invoker.invoke(result);
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   856
        }
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
    @Override
3632
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   860
    <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
   861
                                             ByteBuffer src,
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   862
                                             ByteBuffer[] srcs,
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   863
                                             long timeout,
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   864
                                             TimeUnit unit,
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   865
                                             A attachment,
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   866
                                             CompletionHandler<V,? super A> handler)
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
        // setup task
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   869
        PendingFuture<V,A> result =
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   870
            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
   871
        ByteBuffer[] bufs;
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   872
        if (gatheringWrite) {
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   873
            bufs = srcs;
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   874
        } else {
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   875
            bufs = new ByteBuffer[1];
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   876
            bufs[0] = src;
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   877
        }
10137
d92637d3d673 7068616: NIO libraries do not build with javac -Xlint:all,-deprecation -Werror
jjg
parents: 9035
diff changeset
   878
        final WriteTask<V,A> writeTask =
d92637d3d673 7068616: NIO libraries do not build with javac -Xlint:all,-deprecation -Werror
jjg
parents: 9035
diff changeset
   879
                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
   880
        result.setContext(writeTask);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   881
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   882
        // schedule timeout
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   883
        if (timeout > 0L) {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   884
            Future<?> timeoutTask = iocp.schedule(new Runnable() {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   885
                public void run() {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   886
                    writeTask.timeout();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   887
                }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   888
            }, timeout, unit);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   889
            result.setTimeoutTask(timeoutTask);
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   890
        }
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   891
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   892
        // initiate I/O (can only be done from thread in thread pool)
3632
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   893
        // initiate I/O
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   894
        if (Iocp.supportsThreadAgnosticIo()) {
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   895
            writeTask.run();
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   896
        } else {
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   897
            Invoker.invokeOnThreadInThreadPool(this, writeTask);
399359a027de 6842687: New I/O: Update Asynchronous I/O API to jsr203/nio2-b101
alanb
parents: 2705
diff changeset
   898
        }
2057
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   899
        return result;
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
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   902
    // -- Native methods --
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   903
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   904
    private static native void initIDs();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   905
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   906
    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
   907
        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
   908
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   909
    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
   910
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   911
    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
   912
        throws IOException;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   913
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   914
    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
   915
        long overlapped) throws IOException;
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   916
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   917
    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
   918
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   919
    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
   920
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   921
    static {
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   922
        Util.load();
3acf8e5e2ca0 6781363: New I/O: Update socket-channel API to jsr203/nio2-b99
alanb
parents:
diff changeset
   923
        initIDs();
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
}