Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/windows/classes/java/net/TwoStacksPlainSocketImpl.java
32287 views
1
/*
2
* Copyright (c) 2007, 2013, 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
package java.net;
26
27
import java.io.IOException;
28
import java.io.FileDescriptor;
29
import sun.net.ResourceManager;
30
31
/*
32
* This class defines the plain SocketImpl that is used for all
33
* Windows version lower than Vista. It adds support for IPv6 on
34
* these platforms where available.
35
*
36
* For backward compatibility Windows platforms that do not have IPv6
37
* support also use this implementation, and fd1 gets set to null
38
* during socket creation.
39
*
40
* @author Chris Hegarty
41
*/
42
43
class TwoStacksPlainSocketImpl extends AbstractPlainSocketImpl
44
{
45
/* second fd, used for ipv6 on windows only.
46
* fd1 is used for listeners and for client sockets at initialization
47
* until the socket is connected. Up to this point fd always refers
48
* to the ipv4 socket and fd1 to the ipv6 socket. After the socket
49
* becomes connected, fd always refers to the connected socket
50
* (either v4 or v6) and fd1 is closed.
51
*
52
* For ServerSockets, fd always refers to the v4 listener and
53
* fd1 the v6 listener.
54
*/
55
private FileDescriptor fd1;
56
57
/*
58
* Needed for ipv6 on windows because we need to know
59
* if the socket is bound to ::0 or 0.0.0.0, when a caller
60
* asks for it. Otherwise we don't know which socket to ask.
61
*/
62
private InetAddress anyLocalBoundAddr = null;
63
64
/* to prevent starvation when listening on two sockets, this is
65
* is used to hold the id of the last socket we accepted on.
66
*/
67
private int lastfd = -1;
68
69
// true if this socket is exclusively bound
70
private final boolean exclusiveBind;
71
72
// emulates SO_REUSEADDR when exclusiveBind is true
73
private boolean isReuseAddress;
74
75
static {
76
initProto();
77
}
78
79
public TwoStacksPlainSocketImpl(boolean exclBind) {
80
exclusiveBind = exclBind;
81
}
82
83
public TwoStacksPlainSocketImpl(FileDescriptor fd, boolean exclBind) {
84
this.fd = fd;
85
exclusiveBind = exclBind;
86
}
87
88
/**
89
* Creates a socket with a boolean that specifies whether this
90
* is a stream socket (true) or an unconnected UDP socket (false).
91
*/
92
protected synchronized void create(boolean stream) throws IOException {
93
fd1 = new FileDescriptor();
94
try {
95
super.create(stream);
96
} catch (IOException e) {
97
fd1 = null;
98
throw e;
99
}
100
}
101
102
/**
103
* Binds the socket to the specified address of the specified local port.
104
* @param address the address
105
* @param port the port
106
*/
107
protected synchronized void bind(InetAddress address, int lport)
108
throws IOException
109
{
110
super.bind(address, lport);
111
if (address.isAnyLocalAddress()) {
112
anyLocalBoundAddr = address;
113
}
114
}
115
116
public Object getOption(int opt) throws SocketException {
117
if (isClosedOrPending()) {
118
throw new SocketException("Socket Closed");
119
}
120
if (opt == SO_BINDADDR) {
121
if (fd != null && fd1 != null ) {
122
/* must be unbound or else bound to anyLocal */
123
return anyLocalBoundAddr;
124
}
125
InetAddressContainer in = new InetAddressContainer();
126
socketGetOption(opt, in);
127
return in.addr;
128
} else if (opt == SO_REUSEADDR && exclusiveBind) {
129
// SO_REUSEADDR emulated when using exclusive bind
130
return isReuseAddress;
131
} else
132
return super.getOption(opt);
133
}
134
135
@Override
136
void socketBind(InetAddress address, int port) throws IOException {
137
socketBind(address, port, exclusiveBind);
138
}
139
140
@Override
141
void socketSetOption(int opt, boolean on, Object value)
142
throws SocketException
143
{
144
// SO_REUSEADDR emulated when using exclusive bind
145
if (opt == SO_REUSEADDR && exclusiveBind)
146
isReuseAddress = on;
147
else
148
socketNativeSetOption(opt, on, value);
149
}
150
151
/**
152
* Closes the socket.
153
*/
154
@Override
155
protected void close() throws IOException {
156
synchronized(fdLock) {
157
if (fd != null || fd1 != null) {
158
if (!stream) {
159
ResourceManager.afterUdpClose();
160
}
161
if (fdUseCount == 0) {
162
if (closePending) {
163
return;
164
}
165
closePending = true;
166
socketClose();
167
fd = null;
168
fd1 = null;
169
return;
170
} else {
171
/*
172
* If a thread has acquired the fd and a close
173
* isn't pending then use a deferred close.
174
* Also decrement fdUseCount to signal the last
175
* thread that releases the fd to close it.
176
*/
177
if (!closePending) {
178
closePending = true;
179
fdUseCount--;
180
socketClose();
181
}
182
}
183
}
184
}
185
}
186
187
@Override
188
void reset() throws IOException {
189
if (fd != null || fd1 != null) {
190
socketClose();
191
}
192
fd = null;
193
fd1 = null;
194
super.reset();
195
}
196
197
/*
198
* Return true if already closed or close is pending
199
*/
200
@Override
201
public boolean isClosedOrPending() {
202
/*
203
* Lock on fdLock to ensure that we wait if a
204
* close is in progress.
205
*/
206
synchronized (fdLock) {
207
if (closePending || (fd == null && fd1 == null)) {
208
return true;
209
} else {
210
return false;
211
}
212
}
213
}
214
215
/* Native methods */
216
217
static native void initProto();
218
219
native void socketCreate(boolean isServer) throws IOException;
220
221
native void socketConnect(InetAddress address, int port, int timeout)
222
throws IOException;
223
224
native void socketBind(InetAddress address, int port, boolean exclBind)
225
throws IOException;
226
227
native void socketListen(int count) throws IOException;
228
229
native void socketAccept(SocketImpl s) throws IOException;
230
231
native int socketAvailable() throws IOException;
232
233
native void socketClose0(boolean useDeferredClose) throws IOException;
234
235
native void socketShutdown(int howto) throws IOException;
236
237
native void socketNativeSetOption(int cmd, boolean on, Object value)
238
throws SocketException;
239
240
native int socketGetOption(int opt, Object iaContainerObj) throws SocketException;
241
242
native void socketSendUrgentData(int data) throws IOException;
243
}
244
245