8338452: (dc) DatagramChannelImpl.blockingReceive with timeout may block indefinitely if all datagrams blocked by SecurityManager

Reviewed-by: dfuchs
This commit is contained in:
Alan Bateman 2024-08-19 12:57:29 +00:00 committed by Jaikiran Pai
parent f0fe31383a
commit 2766b09e29

@ -683,14 +683,12 @@ class DatagramChannelImpl
}
long startNanos = System.nanoTime();
long remainingNanos = nanos;
SocketAddress sender = null;
try {
SocketAddress remote = beginRead(true, false);
boolean connected = (remote != null);
do {
long remainingNanos = (nanos > 0)
? nanos - (System.nanoTime() - startNanos)
: 0;
ByteBuffer dst = tryBlockingReceive(connected, bufLength, remainingNanos);
// if datagram received then get sender and copy to DatagramPacket
@ -711,8 +709,8 @@ class DatagramChannelImpl
}
}
// copy bytes to the DatagramPacket, and set length and sender
if (sender != null) {
// copy bytes to the DatagramPacket, and set length and sender
synchronized (p) {
// re-read p.bufLength in case DatagramPacket changed
int len = Math.min(dst.limit(), DatagramPackets.getBufLength(p));
@ -720,6 +718,14 @@ class DatagramChannelImpl
DatagramPackets.setLength(p, len);
p.setSocketAddress(sender);
}
} else {
// need to retry, adjusting timeout if needed
if (nanos > 0) {
remainingNanos = nanos - (System.nanoTime() - startNanos);
if (remainingNanos <= 0) {
throw new SocketTimeoutException("Receive timed out");
}
}
}
} finally {
Util.offerFirstTemporaryDirectBuffer(dst);
@ -746,6 +752,7 @@ class DatagramChannelImpl
private ByteBuffer tryBlockingReceive(boolean connected, int len, long nanos)
throws IOException
{
assert nanos >= 0;
long startNanos = System.nanoTime();
ByteBuffer dst = Util.getTemporaryDirectBuffer(len);
int n = -1;