1 /*
2  * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 /*
27  */
28 
29 package sun.nio.ch;
30 
31 import java.io.IOException;
32 import java.io.FileDescriptor;
33 import java.nio.ByteBuffer;
34 import java.nio.channels.*;
35 import java.nio.channels.spi.*;
36 
37 /**
38  * Pipe.SourceChannel implementation based on socket connection.
39  */
40 
41 class SourceChannelImpl
42     extends Pipe.SourceChannel
43     implements SelChImpl
44 {
45     // The SocketChannel assoicated with this pipe
46     private final SocketChannel sc;
47 
getFD()48     public FileDescriptor getFD() {
49         return ((SocketChannelImpl) sc).getFD();
50     }
51 
getFDVal()52     public int getFDVal() {
53         return ((SocketChannelImpl) sc).getFDVal();
54     }
55 
SourceChannelImpl(SelectorProvider sp, SocketChannel sc)56     SourceChannelImpl(SelectorProvider sp, SocketChannel sc) {
57         super(sp);
58         this.sc = sc;
59     }
60 
implCloseSelectableChannel()61     protected void implCloseSelectableChannel() throws IOException {
62         if (!isRegistered())
63             kill();
64     }
65 
kill()66     public void kill() throws IOException {
67         sc.close();
68     }
69 
implConfigureBlocking(boolean block)70     protected void implConfigureBlocking(boolean block) throws IOException {
71         sc.configureBlocking(block);
72     }
73 
translateReadyOps(int ops, int initialOps, SelectionKeyImpl ski)74     public boolean translateReadyOps(int ops, int initialOps, SelectionKeyImpl ski) {
75         int intOps = ski.nioInterestOps();
76         int oldOps = ski.nioReadyOps();
77         int newOps = initialOps;
78 
79         if ((ops & Net.POLLNVAL) != 0)
80             throw new Error("POLLNVAL detected");
81 
82         if ((ops & (Net.POLLERR | Net.POLLHUP)) != 0) {
83             newOps = intOps;
84             ski.nioReadyOps(newOps);
85             return (newOps & ~oldOps) != 0;
86         }
87 
88         if (((ops & Net.POLLIN) != 0) &&
89             ((intOps & SelectionKey.OP_READ) != 0))
90             newOps |= SelectionKey.OP_READ;
91 
92         ski.nioReadyOps(newOps);
93         return (newOps & ~oldOps) != 0;
94     }
95 
translateAndUpdateReadyOps(int ops, SelectionKeyImpl ski)96     public boolean translateAndUpdateReadyOps(int ops, SelectionKeyImpl ski) {
97         return translateReadyOps(ops, ski.nioReadyOps(), ski);
98     }
99 
translateAndSetReadyOps(int ops, SelectionKeyImpl ski)100     public boolean translateAndSetReadyOps(int ops, SelectionKeyImpl ski) {
101         return translateReadyOps(ops, 0, ski);
102     }
103 
translateInterestOps(int ops)104     public int translateInterestOps(int ops) {
105         int newOps = 0;
106         if ((ops & SelectionKey.OP_READ) != 0)
107             newOps |= Net.POLLIN;
108         return newOps;
109     }
110 
read(ByteBuffer dst)111     public int read(ByteBuffer dst) throws IOException {
112         try {
113             return sc.read(dst);
114         } catch (AsynchronousCloseException x) {
115             close();
116             throw x;
117         }
118     }
119 
read(ByteBuffer[] dsts, int offset, int length)120     public long read(ByteBuffer[] dsts, int offset, int length)
121         throws IOException
122     {
123         if ((offset < 0) || (length < 0) || (offset > dsts.length - length))
124            throw new IndexOutOfBoundsException();
125         try {
126             return read(Util.subsequence(dsts, offset, length));
127         } catch (AsynchronousCloseException x) {
128             close();
129             throw x;
130         }
131     }
132 
read(ByteBuffer[] dsts)133     public long read(ByteBuffer[] dsts) throws IOException {
134         try {
135             return sc.read(dsts);
136         } catch (AsynchronousCloseException x) {
137             close();
138             throw x;
139         }
140     }
141 
142 }
143