Skip to content

Commit 9ef7852

Browse files
committed
8290714: Make com.sun.jndi.dns.DnsClient virtual threads friendly
Reviewed-by: dfuchs, jpai
1 parent d6468be commit 9ef7852

File tree

3 files changed

+164
-113
lines changed

3 files changed

+164
-113
lines changed

src/jdk.naming.dns/share/classes/com/sun/jndi/dns/DNSDatagramSocketFactory.java src/jdk.naming.dns/share/classes/com/sun/jndi/dns/DNSDatagramChannelFactory.java

+36-50
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,14 @@
2727
import java.io.IOException;
2828
import java.net.DatagramSocket;
2929
import java.net.ProtocolFamily;
30-
import java.net.SocketException;
3130
import java.net.InetSocketAddress;
3231
import java.nio.channels.DatagramChannel;
3332
import java.security.AccessController;
3433
import java.security.PrivilegedExceptionAction;
3534
import java.util.Objects;
3635
import java.util.Random;
3736

38-
class DNSDatagramSocketFactory {
37+
class DNSDatagramChannelFactory {
3938
static final int DEVIATION = 3;
4039
static final int THRESHOLD = 6;
4140
static final int BIT_DEVIATION = 2;
@@ -120,17 +119,17 @@ public boolean offer(int port) {
120119
final Random random;
121120
final PortHistory history;
122121

123-
DNSDatagramSocketFactory() {
122+
DNSDatagramChannelFactory() {
124123
this(new Random());
125124
}
126125

127-
DNSDatagramSocketFactory(Random random) {
126+
DNSDatagramChannelFactory(Random random) {
128127
this(Objects.requireNonNull(random), null, DEVIATION, THRESHOLD);
129128
}
130-
DNSDatagramSocketFactory(Random random,
131-
ProtocolFamily family,
132-
int deviation,
133-
int threshold) {
129+
DNSDatagramChannelFactory(Random random,
130+
ProtocolFamily family,
131+
int deviation,
132+
int threshold) {
134133
this.random = Objects.requireNonNull(random);
135134
this.history = new PortHistory(HISTORY, random);
136135
this.family = family;
@@ -145,12 +144,13 @@ public boolean offer(int port) {
145144
* port) then the underlying OS implementation is used. Otherwise, this
146145
* method will allocate and bind a socket on a randomly selected ephemeral
147146
* port in the dynamic range.
148-
* @return A new DatagramSocket bound to a random port.
149-
* @throws SocketException if the socket cannot be created.
147+
*
148+
* @return A new DatagramChannel bound to a random port.
149+
* @throws IOException if the socket cannot be created.
150150
*/
151-
public synchronized DatagramSocket open() throws SocketException {
151+
public synchronized DatagramChannel open() throws IOException {
152152
int lastseen = lastport;
153-
DatagramSocket s;
153+
DatagramChannel s;
154154

155155
boolean thresholdCrossed = unsuitablePortCount > thresholdCount;
156156
if (thresholdCrossed) {
@@ -166,7 +166,7 @@ public synchronized DatagramSocket open() throws SocketException {
166166

167167
// Allocate an ephemeral port (port 0)
168168
s = openDefault();
169-
lastport = s.getLocalPort();
169+
lastport = getLocalPort(s);
170170
if (lastseen == 0) {
171171
lastSystemAllocated = lastport;
172172
history.offer(lastport);
@@ -199,36 +199,27 @@ public synchronized DatagramSocket open() throws SocketException {
199199
// Undecided... the new port was too close. Let's allocate a random
200200
// port using our own algorithm
201201
assert !thresholdCrossed;
202-
DatagramSocket ss = openRandom();
202+
DatagramChannel ss = openRandom();
203203
if (ss == null) return s;
204204
unsuitablePortCount++;
205205
s.close();
206206
return ss;
207207
}
208208

209-
private DatagramSocket openDefault() throws SocketException {
210-
if (family != null) {
211-
try {
212-
DatagramChannel c = DatagramChannel.open(family);
213-
try {
214-
DatagramSocket s = c.socket();
215-
s.bind(null);
216-
return s;
217-
} catch (Throwable x) {
218-
c.close();
219-
throw x;
220-
}
221-
} catch (SocketException x) {
222-
throw x;
223-
} catch (IOException x) {
224-
throw new SocketException(x.getMessage(), x);
225-
}
209+
private DatagramChannel openDefault() throws IOException {
210+
DatagramChannel c = family != null ? DatagramChannel.open(family)
211+
: DatagramChannel.open();
212+
try {
213+
c.bind(null);
214+
return c;
215+
} catch (Throwable x) {
216+
c.close();
217+
throw x;
226218
}
227-
return new DatagramSocket();
228219
}
229220

230221
synchronized boolean isUsingNativePortRandomization() {
231-
return unsuitablePortCount <= thresholdCount
222+
return unsuitablePortCount <= thresholdCount
232223
&& suitablePortCount > thresholdCount;
233224
}
234225

@@ -246,7 +237,7 @@ private boolean farEnough(int port) {
246237
&& Math.abs(port - lastport) > deviation;
247238
}
248239

249-
private DatagramSocket openRandom() {
240+
private DatagramChannel openRandom() throws IOException {
250241
int maxtries = MAX_RANDOM_TRIES;
251242
while (maxtries-- > 0) {
252243
int port;
@@ -265,29 +256,24 @@ private DatagramSocket openRandom() {
265256
// times - but that should be OK with MAX_RANDOM_TRIES = 5.
266257
if (!suitable) continue;
267258

259+
DatagramChannel dc = (family != null)
260+
? DatagramChannel.open(family)
261+
: DatagramChannel.open();
268262
try {
269-
if (family != null) {
270-
DatagramChannel c = DatagramChannel.open(family);
271-
try {
272-
DatagramSocket s = c.socket();
273-
s.bind(new InetSocketAddress(port));
274-
lastport = s.getLocalPort();
275-
if (!recycled) history.add(port);
276-
return s;
277-
} catch (Throwable x) {
278-
c.close();
279-
throw x;
280-
}
281-
}
282-
DatagramSocket s = new DatagramSocket(port);
283-
lastport = s.getLocalPort();
263+
dc.bind(new InetSocketAddress(port));
264+
lastport = getLocalPort(dc);
284265
if (!recycled) history.add(port);
285-
return s;
266+
return dc;
286267
} catch (IOException x) {
268+
dc.close();
287269
// try again until maxtries == 0;
288270
}
289271
}
290272
return null;
291273
}
292274

275+
private static int getLocalPort(DatagramChannel dc) throws IOException {
276+
return ((InetSocketAddress) dc.getLocalAddress()).getPort();
277+
}
278+
293279
}

0 commit comments

Comments
 (0)