summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/java/com/it_jaros/jns/scan/engine/PortScanRateLimiter.java21
1 files changed, 17 insertions, 4 deletions
diff --git a/src/main/java/com/it_jaros/jns/scan/engine/PortScanRateLimiter.java b/src/main/java/com/it_jaros/jns/scan/engine/PortScanRateLimiter.java
index aa897a4..3411367 100644
--- a/src/main/java/com/it_jaros/jns/scan/engine/PortScanRateLimiter.java
+++ b/src/main/java/com/it_jaros/jns/scan/engine/PortScanRateLimiter.java
@@ -23,16 +23,29 @@ public class PortScanRateLimiter {
if (delayInNanos <= 0) {
return;
}
+
+ long deadlineNanos;
synchronized (lock) {
if (cancelledToken.isCancelled()) {
return;
}
long now = System.nanoTime();
- if (nextAllowedTime > now) {
- LockSupport.parkNanos(nextAllowedTime - now);
- now = System.nanoTime(); // re-read after waking
+ if (nextAllowedTime <= now) {
+ // a slot is free: claim it and proceed immediately
+ nextAllowedTime = now + delayInNanos;
+ return;
}
- nextAllowedTime = now + delayInNanos;
+ // claim my slot now, wait for it later
+ deadlineNanos = nextAllowedTime;
+ nextAllowedTime += delayInNanos;
+ }
+
+ // wait outside the lock so the thread is not blocked
+ // while holding the monitor (which would pin virtual threads)
+ LockSupport.parkNanos(Math.max(0, deadlineNanos - System.nanoTime()));
+
+ if (cancelledToken.isCancelled()) {
+ return;
}
}
}