History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/nio/ch/AsynchronousServerSocketChannelImpl.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/nio/ch/AsynchronousServerSocketChannelImpl.java+245−0
@@ -0,0 +1,245 @@
1/*
2 * Copyright (c) 2008, 2009, 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
26package sun.nio.ch;
27
28import java.nio.channels.*;
29import java.net.SocketAddress;
30import java.net.SocketOption;
31import java.net.StandardSocketOptions;
32import java.net.InetSocketAddress;
33import java.io.FileDescriptor;
34import java.io.IOException;
35import java.util.Set;
36import java.util.HashSet;
37import java.util.Collections;
38import java.util.concurrent.Future;
39import java.util.concurrent.locks.ReadWriteLock;
40import java.util.concurrent.locks.ReentrantReadWriteLock;
41import sun.net.NetHooks;
42
43/**
44 * Base implementation of AsynchronousServerSocketChannel.
45 */
46
47abstract class AsynchronousServerSocketChannelImpl
48 extends AsynchronousServerSocketChannel
49 implements Cancellable, Groupable
50{
51 protected final FileDescriptor fd;
52
53 // the local address to which the channel's socket is bound
54 protected volatile SocketAddress localAddress = null;
55
56 // need this lock to set local address
57 private final Object stateLock = new Object();
58
59 // close support
60 private ReadWriteLock closeLock = new ReentrantReadWriteLock();
61 private volatile boolean open = true;
62
63 // set true when accept operation is cancelled
64 private volatile boolean acceptKilled;
65
66
67 AsynchronousServerSocketChannelImpl(AsynchronousChannelGroupImpl group) {
68 super(group.provider());
69 this.fd = Net.serverSocket(true);
70 }
71
72 @Override
73 public final boolean isOpen() {
74 return open;
75 }
76
77 /**
78 * Marks beginning of access to file descriptor/handle
79 */
80 final void begin() throws IOException {
81 closeLock.readLock().lock();
82 if (!isOpen())
83 throw new ClosedChannelException();
84 }
85
86 /**
87 * Marks end of access to file descriptor/handle
88 */
89 final void end() {
90 closeLock.readLock().unlock();
91 }
92
93 /**
94 * Invoked to close file descriptor/handle.
95 */
96 abstract void implClose() throws IOException;
97
98 @Override
99 public final void close() throws IOException {
100 // synchronize with any threads using file descriptor/handle
101 closeLock.writeLock().lock();
102 try {
103 if (!open)
104 return; // already closed
105 open = false;
106 } finally {
107 closeLock.writeLock().unlock();
108 }
109 implClose();
110 }
111
112 /**
113 * Invoked by accept to accept connection
114 */
115 abstract Future<AsynchronousSocketChannel>
116 implAccept(Object attachment,
117 CompletionHandler<AsynchronousSocketChannel,Object> handler);
118
119
120 @Override
121 public final Future<AsynchronousSocketChannel> accept() {
122 return implAccept(null, null);
123 }
124
125 @Override
126 @SuppressWarnings("unchecked")
127 public final <A> void accept(A attachment,
128 CompletionHandler<AsynchronousSocketChannel,? super A> handler)
129 {
130 if (handler == null)
131 throw new NullPointerException("'handler' is null");
132 implAccept(attachment, (CompletionHandler<AsynchronousSocketChannel,Object>)handler);
133 }
134
135 final boolean isAcceptKilled() {
136 return acceptKilled;
137 }
138
139 @Override
140 public final void onCancel(PendingFuture<?,?> task) {
141 acceptKilled = true;
142 }
143
144 @Override
145 public final AsynchronousServerSocketChannel bind(SocketAddress local, int backlog)
146 throws IOException
147 {
148 InetSocketAddress isa = (local == null) ? new InetSocketAddress(0) :
149 Net.checkAddress(local);
150 SecurityManager sm = System.getSecurityManager();
151 if (sm != null)
152 sm.checkListen(isa.getPort());
153
154 try {
155 begin();
156 synchronized (stateLock) {
157 if (localAddress != null)
158 throw new AlreadyBoundException();
159 NetHooks.beforeTcpBind(fd, isa.getAddress(), isa.getPort());
160 Net.bind(fd, isa.getAddress(), isa.getPort());
161 Net.listen(fd, backlog < 1 ? 50 : backlog);
162 localAddress = Net.localAddress(fd);
163 }
164 } finally {
165 end();
166 }
167 return this;
168 }
169
170 @Override
171 public final SocketAddress getLocalAddress() throws IOException {
172 if (!isOpen())
173 throw new ClosedChannelException();
174 return localAddress;
175 }
176
177 @Override
178 public final <T> AsynchronousServerSocketChannel setOption(SocketOption<T> name,
179 T value)
180 throws IOException
181 {
182 if (name == null)
183 throw new NullPointerException();
184 if (!supportedOptions().contains(name))
185 throw new UnsupportedOperationException("'" + name + "' not supported");
186
187 try {
188 begin();
189 Net.setSocketOption(fd, Net.UNSPEC, name, value);
190 return this;
191 } finally {
192 end();
193 }
194 }
195
196 @Override
197 @SuppressWarnings("unchecked")
198 public final <T> T getOption(SocketOption<T> name) throws IOException {
199 if (name == null)
200 throw new NullPointerException();
201 if (!supportedOptions().contains(name))
202 throw new UnsupportedOperationException("'" + name + "' not supported");
203
204 try {
205 begin();
206 return (T) Net.getSocketOption(fd, Net.UNSPEC, name);
207 } finally {
208 end();
209 }
210 }
211
212 private static class DefaultOptionsHolder {
213 static final Set<SocketOption<?>> defaultOptions = defaultOptions();
214
215 private static Set<SocketOption<?>> defaultOptions() {
216 HashSet<SocketOption<?>> set = new HashSet<SocketOption<?>>(2);
217 set.add(StandardSocketOptions.SO_RCVBUF);
218 set.add(StandardSocketOptions.SO_REUSEADDR);
219 return Collections.unmodifiableSet(set);
220 }
221 }
222
223 @Override
224 public final Set<SocketOption<?>> supportedOptions() {
225 return DefaultOptionsHolder.defaultOptions;
226 }
227
228 @Override
229 public final String toString() {
230 StringBuilder sb = new StringBuilder();
231 sb.append(this.getClass().getName());
232 sb.append('[');
233 if (!isOpen())
234 sb.append("closed");
235 else {
236 if (localAddress == null) {
237 sb.append("unbound");
238 } else {
239 sb.append(localAddress.toString());
240 }
241 }
242 sb.append(']');
243 return sb.toString();
244 }
245}