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