• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2  * contributor license agreements.  See the NOTICE file distributed with
3  * this work for additional information regarding copyright ownership.
4  * The ASF licenses this file to You under the Apache License, Version 2.0
5  * (the "License"); you may not use this file except in compliance with
6  * the License.  You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package java.nio;
18 
19 import java.io.Closeable;
20 import java.io.FileDescriptor;
21 import java.io.IOException;
22 import java.nio.channels.Pipe;
23 import java.nio.channels.SocketChannel;
24 import java.nio.channels.spi.SelectorProvider;
25 import libcore.io.ErrnoException;
26 import libcore.io.IoUtils;
27 import libcore.io.Libcore;
28 import static libcore.io.OsConstants.*;
29 
30 /*
31  * Implements {@link java.nio.channels.Pipe}.
32  */
33 final class PipeImpl extends Pipe {
34     private final PipeSinkChannel sink;
35     private final PipeSourceChannel source;
36 
PipeImpl(SelectorProvider selectorProvider)37     public PipeImpl(SelectorProvider selectorProvider) throws IOException {
38         try {
39             FileDescriptor fd1 = new FileDescriptor();
40             FileDescriptor fd2 = new FileDescriptor();
41             Libcore.os.socketpair(AF_UNIX, SOCK_STREAM, 0, fd1, fd2);
42 
43             // It doesn't matter which file descriptor we use for which end;
44             // they're guaranteed to be indistinguishable.
45             this.sink = new PipeSinkChannel(selectorProvider, fd1);
46             this.source = new PipeSourceChannel(selectorProvider, fd2);
47         } catch (ErrnoException errnoException) {
48             throw errnoException.rethrowAsIOException();
49         }
50     }
51 
sink()52     @Override public SinkChannel sink() {
53         return sink;
54     }
55 
source()56     @Override public SourceChannel source() {
57         return source;
58     }
59 
60     private class PipeSourceChannel extends Pipe.SourceChannel implements FileDescriptorChannel {
61         private final FileDescriptor fd;
62         private final SocketChannel channel;
63 
PipeSourceChannel(SelectorProvider selectorProvider, FileDescriptor fd)64         private PipeSourceChannel(SelectorProvider selectorProvider, FileDescriptor fd) throws IOException {
65             super(selectorProvider);
66             this.fd = fd;
67             this.channel = new SocketChannelImpl(selectorProvider, fd);
68         }
69 
implCloseSelectableChannel()70         @Override protected void implCloseSelectableChannel() throws IOException {
71             channel.close();
72         }
73 
implConfigureBlocking(boolean blocking)74         @Override protected void implConfigureBlocking(boolean blocking) throws IOException {
75             IoUtils.setBlocking(getFD(), blocking);
76         }
77 
read(ByteBuffer buffer)78         public int read(ByteBuffer buffer) throws IOException {
79             return channel.read(buffer);
80         }
81 
read(ByteBuffer[] buffers)82         public long read(ByteBuffer[] buffers) throws IOException {
83             return channel.read(buffers);
84         }
85 
read(ByteBuffer[] buffers, int offset, int length)86         public long read(ByteBuffer[] buffers, int offset, int length) throws IOException {
87             return channel.read(buffers, offset, length);
88         }
89 
getFD()90         public FileDescriptor getFD() {
91             return fd;
92         }
93     }
94 
95     private class PipeSinkChannel extends Pipe.SinkChannel implements FileDescriptorChannel {
96         private final FileDescriptor fd;
97         private final SocketChannel channel;
98 
PipeSinkChannel(SelectorProvider selectorProvider, FileDescriptor fd)99         private PipeSinkChannel(SelectorProvider selectorProvider, FileDescriptor fd) throws IOException {
100             super(selectorProvider);
101             this.fd = fd;
102             this.channel = new SocketChannelImpl(selectorProvider, fd);
103         }
104 
implCloseSelectableChannel()105         @Override protected void implCloseSelectableChannel() throws IOException {
106             channel.close();
107         }
108 
implConfigureBlocking(boolean blocking)109         @Override protected void implConfigureBlocking(boolean blocking) throws IOException {
110             IoUtils.setBlocking(getFD(), blocking);
111         }
112 
write(ByteBuffer buffer)113         public int write(ByteBuffer buffer) throws IOException {
114             return channel.write(buffer);
115         }
116 
write(ByteBuffer[] buffers)117         public long write(ByteBuffer[] buffers) throws IOException {
118             return channel.write(buffers);
119         }
120 
write(ByteBuffer[] buffers, int offset, int length)121         public long write(ByteBuffer[] buffers, int offset, int length) throws IOException {
122             return channel.write(buffers, offset, length);
123         }
124 
getFD()125         public FileDescriptor getFD() {
126             return fd;
127         }
128     }
129 }
130