001// Generated by delombok at Sat Feb 25 17:58:34 UTC 2023
002package io.cui.tools.concurrent;
003
004import static java.util.concurrent.TimeUnit.NANOSECONDS;
005import java.time.Duration;
006import java.util.concurrent.TimeUnit;
007
008/**
009 * Provides some helper-methods taken from com.google.common.util.concurrent package
010 *
011 * @author Oliver Wolff
012 */
013public final class ConcurrentTools {
014    /**
015     * Invokes {@code unit.}{@link TimeUnit#sleep(long) sleep(sleepFor)} uninterruptibly.
016     *
017     * @param sleepFor
018     */
019    public static void sleepUninterruptibly(Duration sleepFor) {
020        sleepUninterruptibly(saturatedToNanos(sleepFor), TimeUnit.NANOSECONDS);
021    }
022
023    /**
024     * Invokes {@code unit.}{@link TimeUnit#sleep(long) sleep(sleepFor)} uninterruptibly.
025     *
026     * @param sleepFor
027     * @param unit
028     */
029    public static void sleepUninterruptibly(long sleepFor, TimeUnit unit) {
030        var interrupted = false;
031        try {
032            var remainingNanos = unit.toNanos(sleepFor);
033            var end = System.nanoTime() + remainingNanos;
034            while (true) {
035                try {
036                    // TimeUnit.sleep() treats negative timeouts just like zero.
037                    NANOSECONDS.sleep(remainingNanos);
038                    return;
039                } catch (InterruptedException e) {
040                    interrupted = true;
041                    remainingNanos = end - System.nanoTime();
042                }
043            }
044        } finally {
045            if (interrupted) {
046                Thread.currentThread().interrupt();
047            }
048        }
049    }
050
051    /**
052     * Returns the number of nanoseconds of the given duration without throwing or overflowing.
053     *
054     * <p>
055     * Instead of throwing {@link ArithmeticException}, this method silently saturates to either
056     * {@link Long#MAX_VALUE} or {@link Long#MIN_VALUE}. This behavior can be useful when
057     * decomposing
058     * a duration in order to call a legacy API which requires a {@code long, TimeUnit} pair.
059     *
060     * @author com.google.common.util.concurrent.Internal
061     */
062    static long saturatedToNanos(Duration duration) {
063        // Using a try/catch seems lazy, but the catch block will rarely get invoked (except for
064        // durations longer than approximately +/- 292 years).
065        try {
066            return duration.toNanos();
067        } catch (ArithmeticException tooBig) {
068            return duration.isNegative() ? Long.MIN_VALUE : Long.MAX_VALUE;
069        }
070    }
071
072    @java.lang.SuppressWarnings("all")
073    @lombok.Generated
074    private ConcurrentTools() {
075        throw new java.lang.UnsupportedOperationException("This is a utility class and cannot be instantiated");
076    }
077}