-
Bug
-
Resolution: Duplicate
-
P4
-
None
-
21.0.4
-
generic
-
generic
A DESCRIPTION OF THE PROBLEM :
Calling `java.net.DatagramSocket#receive` in virtual thread would lead to virtualthread unparker scheduled after about Long.MAX_VALUE, which leading to negative time returned by `java.util.concurrent.ScheduledThreadPoolExecutor#triggerTime(long)`
It may become the head of workQueue (depends on whether it overflows again when compareTo). If that happens, the unparker thread could park forever because getDelay is overflowed again to a very big number.
Even worse, when first task is canceled (park condition met), the unparker thread is still parking because java.lang.VirtualThread#cancel pass false to maybeInterruptIfRunning.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Start a larger number of virtual thread calls datagramSocket.receive.
2. Start a large number of virtual thread, park and do other things.
3. "Other things" get blocked.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
No overflow happened.
ACTUAL -
All virutal thread is blocked.
---------- BEGIN SOURCE ----------
I can't reproduce the blocking with simple code, but negative trigger time is easily reproduced using debugger:
public static void main(String[] args) throws InterruptedException {
Thread.ofVirtual().start(() -> {
try {
// make nanoTime bigger
DatagramSocket datagramSocket = new DatagramSocket(null);
datagramSocket.bind(new InetSocketAddress("0.0.0.0", 0));
datagramSocket.receive(new DatagramPacket(new byte[4096], 4096)); // debug at java.lang.VirtualThread#scheduleUnpark and we will find out that trigger time of unpark task is negative which may cause java.util.concurrent.ScheduledThreadPoolExecutor.ScheduledFutureTask#getDelay overflow again to a very large number.
} catch (IOException e) {
throw new RuntimeException(e);
}
});
Thread.sleep(10000000);
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
setSoTimeout for DatagramSocket.
Calling `java.net.DatagramSocket#receive` in virtual thread would lead to virtualthread unparker scheduled after about Long.MAX_VALUE, which leading to negative time returned by `java.util.concurrent.ScheduledThreadPoolExecutor#triggerTime(long)`
It may become the head of workQueue (depends on whether it overflows again when compareTo). If that happens, the unparker thread could park forever because getDelay is overflowed again to a very big number.
Even worse, when first task is canceled (park condition met), the unparker thread is still parking because java.lang.VirtualThread#cancel pass false to maybeInterruptIfRunning.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Start a larger number of virtual thread calls datagramSocket.receive.
2. Start a large number of virtual thread, park and do other things.
3. "Other things" get blocked.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
No overflow happened.
ACTUAL -
All virutal thread is blocked.
---------- BEGIN SOURCE ----------
I can't reproduce the blocking with simple code, but negative trigger time is easily reproduced using debugger:
public static void main(String[] args) throws InterruptedException {
Thread.ofVirtual().start(() -> {
try {
// make nanoTime bigger
DatagramSocket datagramSocket = new DatagramSocket(null);
datagramSocket.bind(new InetSocketAddress("0.0.0.0", 0));
datagramSocket.receive(new DatagramPacket(new byte[4096], 4096)); // debug at java.lang.VirtualThread#scheduleUnpark and we will find out that trigger time of unpark task is negative which may cause java.util.concurrent.ScheduledThreadPoolExecutor.ScheduledFutureTask#getDelay overflow again to a very large number.
} catch (IOException e) {
throw new RuntimeException(e);
}
});
Thread.sleep(10000000);
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
setSoTimeout for DatagramSocket.
- duplicates
-
JDK-8338765 ScheduledThreadPoolExecutor struggles with extremely long delays
- Resolved
- relates to
-
JDK-8338142 (dc) DatagramChannelImpl.blockingReceive can use untimed-park when no timeout set
- Resolved