diff --git a/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java b/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java index 06e79f416ac..5fac688b311 100644 --- a/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java +++ b/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java @@ -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;