Coverage Summary for Class: Uninterruptibles (com.google.common.util.concurrent)

Class Class, % Method, % Line, %
Uninterruptibles 0% (0/1) 0% (0/25) 0% (0/142)


1 /* 2  * Copyright (C) 2011 The Guava Authors 3  * 4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5  * in compliance with the License. You may obtain a copy of the License at 6  * 7  * http://www.apache.org/licenses/LICENSE-2.0 8  * 9  * Unless required by applicable law or agreed to in writing, software distributed under the License 10  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11  * or implied. See the License for the specific language governing permissions and limitations under 12  * the License. 13  */ 14  15 package com.google.common.util.concurrent; 16  17 import static com.google.common.base.Verify.verify; 18 import static com.google.common.util.concurrent.Internal.toNanosSaturated; 19 import static java.util.concurrent.TimeUnit.NANOSECONDS; 20  21 import com.google.common.annotations.Beta; 22 import com.google.common.annotations.GwtCompatible; 23 import com.google.common.annotations.GwtIncompatible; 24 import com.google.common.base.Preconditions; 25 import com.google.errorprone.annotations.CanIgnoreReturnValue; 26 import java.time.Duration; 27 import java.util.concurrent.BlockingQueue; 28 import java.util.concurrent.CancellationException; 29 import java.util.concurrent.CountDownLatch; 30 import java.util.concurrent.ExecutionException; 31 import java.util.concurrent.ExecutorService; 32 import java.util.concurrent.Future; 33 import java.util.concurrent.Semaphore; 34 import java.util.concurrent.TimeUnit; 35 import java.util.concurrent.TimeoutException; 36 import java.util.concurrent.locks.Condition; 37 import java.util.concurrent.locks.Lock; 38 import org.checkerframework.checker.nullness.qual.Nullable; 39  40 /** 41  * Utilities for treating interruptible operations as uninterruptible. In all cases, if a thread is 42  * interrupted during such a call, the call continues to block until the result is available or the 43  * timeout elapses, and only then re-interrupts the thread. 44  * 45  * @author Anthony Zana 46  * @since 10.0 47  */ 48 @GwtCompatible(emulated = true) 49 @ElementTypesAreNonnullByDefault 50 public final class Uninterruptibles { 51  52  // Implementation Note: As of 3-7-11, the logic for each blocking/timeout 53  // methods is identical, save for method being invoked. 54  55  /** Invokes {@code latch.}{@link CountDownLatch#await() await()} uninterruptibly. */ 56  @GwtIncompatible // concurrency 57  public static void awaitUninterruptibly(CountDownLatch latch) { 58  boolean interrupted = false; 59  try { 60  while (true) { 61  try { 62  latch.await(); 63  return; 64  } catch (InterruptedException e) { 65  interrupted = true; 66  } 67  } 68  } finally { 69  if (interrupted) { 70  Thread.currentThread().interrupt(); 71  } 72  } 73  } 74  75  /** 76  * Invokes {@code latch.}{@link CountDownLatch#await(long, TimeUnit) await(timeout, unit)} 77  * uninterruptibly. 78  * 79  * @since 28.0 80  */ 81  @CanIgnoreReturnValue // TODO(cpovirk): Consider being more strict. 82  @GwtIncompatible // concurrency 83  @Beta 84  public static boolean awaitUninterruptibly(CountDownLatch latch, Duration timeout) { 85  return awaitUninterruptibly(latch, toNanosSaturated(timeout), TimeUnit.NANOSECONDS); 86  } 87  88  /** 89  * Invokes {@code latch.}{@link CountDownLatch#await(long, TimeUnit) await(timeout, unit)} 90  * uninterruptibly. 91  */ 92  @CanIgnoreReturnValue // TODO(cpovirk): Consider being more strict. 93  @GwtIncompatible // concurrency 94  @SuppressWarnings("GoodTime") // should accept a java.time.Duration 95  public static boolean awaitUninterruptibly(CountDownLatch latch, long timeout, TimeUnit unit) { 96  boolean interrupted = false; 97  try { 98  long remainingNanos = unit.toNanos(timeout); 99  long end = System.nanoTime() + remainingNanos; 100  101  while (true) { 102  try { 103  // CountDownLatch treats negative timeouts just like zero. 104  return latch.await(remainingNanos, NANOSECONDS); 105  } catch (InterruptedException e) { 106  interrupted = true; 107  remainingNanos = end - System.nanoTime(); 108  } 109  } 110  } finally { 111  if (interrupted) { 112  Thread.currentThread().interrupt(); 113  } 114  } 115  } 116  117  /** 118  * Invokes {@code condition.}{@link Condition#await(long, TimeUnit) await(timeout, unit)} 119  * uninterruptibly. 120  * 121  * @since 28.0 122  */ 123  @GwtIncompatible // concurrency 124  @Beta 125  public static boolean awaitUninterruptibly(Condition condition, Duration timeout) { 126  return awaitUninterruptibly(condition, toNanosSaturated(timeout), TimeUnit.NANOSECONDS); 127  } 128  129  /** 130  * Invokes {@code condition.}{@link Condition#await(long, TimeUnit) await(timeout, unit)} 131  * uninterruptibly. 132  * 133  * @since 23.6 134  */ 135  @GwtIncompatible // concurrency 136  @SuppressWarnings("GoodTime") // should accept a java.time.Duration 137  public static boolean awaitUninterruptibly(Condition condition, long timeout, TimeUnit unit) { 138  boolean interrupted = false; 139  try { 140  long remainingNanos = unit.toNanos(timeout); 141  long end = System.nanoTime() + remainingNanos; 142  143  while (true) { 144  try { 145  return condition.await(remainingNanos, NANOSECONDS); 146  } catch (InterruptedException e) { 147  interrupted = true; 148  remainingNanos = end - System.nanoTime(); 149  } 150  } 151  } finally { 152  if (interrupted) { 153  Thread.currentThread().interrupt(); 154  } 155  } 156  } 157  158  /** Invokes {@code toJoin.}{@link Thread#join() join()} uninterruptibly. */ 159  @GwtIncompatible // concurrency 160  public static void joinUninterruptibly(Thread toJoin) { 161  boolean interrupted = false; 162  try { 163  while (true) { 164  try { 165  toJoin.join(); 166  return; 167  } catch (InterruptedException e) { 168  interrupted = true; 169  } 170  } 171  } finally { 172  if (interrupted) { 173  Thread.currentThread().interrupt(); 174  } 175  } 176  } 177  178  /** 179  * Invokes {@code unit.}{@link TimeUnit#timedJoin(Thread, long) timedJoin(toJoin, timeout)} 180  * uninterruptibly. 181  * 182  * @since 28.0 183  */ 184  @GwtIncompatible // concurrency 185  @Beta 186  public static void joinUninterruptibly(Thread toJoin, Duration timeout) { 187  joinUninterruptibly(toJoin, toNanosSaturated(timeout), TimeUnit.NANOSECONDS); 188  } 189  190  /** 191  * Invokes {@code unit.}{@link TimeUnit#timedJoin(Thread, long) timedJoin(toJoin, timeout)} 192  * uninterruptibly. 193  */ 194  @GwtIncompatible // concurrency 195  @SuppressWarnings("GoodTime") // should accept a java.time.Duration 196  public static void joinUninterruptibly(Thread toJoin, long timeout, TimeUnit unit) { 197  Preconditions.checkNotNull(toJoin); 198  boolean interrupted = false; 199  try { 200  long remainingNanos = unit.toNanos(timeout); 201  long end = System.nanoTime() + remainingNanos; 202  while (true) { 203  try { 204  // TimeUnit.timedJoin() treats negative timeouts just like zero. 205  NANOSECONDS.timedJoin(toJoin, remainingNanos); 206  return; 207  } catch (InterruptedException e) { 208  interrupted = true; 209  remainingNanos = end - System.nanoTime(); 210  } 211  } 212  } finally { 213  if (interrupted) { 214  Thread.currentThread().interrupt(); 215  } 216  } 217  } 218  219  /** 220  * Invokes {@code future.}{@link Future#get() get()} uninterruptibly. 221  * 222  * <p>Similar methods: 223  * 224  * <ul> 225  * <li>To retrieve a result from a {@code Future} that is already done, use {@link 226  * Futures#getDone Futures.getDone}. 227  * <li>To treat {@link InterruptedException} uniformly with other exceptions, use {@link 228  * Futures#getChecked(Future, Class) Futures.getChecked}. 229  * <li>To get uninterruptibility and remove checked exceptions, use {@link 230  * Futures#getUnchecked}. 231  * </ul> 232  * 233  * @throws ExecutionException if the computation threw an exception 234  * @throws CancellationException if the computation was cancelled 235  */ 236  @CanIgnoreReturnValue 237  @ParametricNullness 238  public static <V extends @Nullable Object> V getUninterruptibly(Future<V> future) 239  throws ExecutionException { 240  boolean interrupted = false; 241  try { 242  while (true) { 243  try { 244  return future.get(); 245  } catch (InterruptedException e) { 246  interrupted = true; 247  } 248  } 249  } finally { 250  if (interrupted) { 251  Thread.currentThread().interrupt(); 252  } 253  } 254  } 255  256  /** 257  * Invokes {@code future.}{@link Future#get(long, TimeUnit) get(timeout, unit)} uninterruptibly. 258  * 259  * <p>Similar methods: 260  * 261  * <ul> 262  * <li>To retrieve a result from a {@code Future} that is already done, use {@link 263  * Futures#getDone Futures.getDone}. 264  * <li>To treat {@link InterruptedException} uniformly with other exceptions, use {@link 265  * Futures#getChecked(Future, Class, long, TimeUnit) Futures.getChecked}. 266  * <li>To get uninterruptibility and remove checked exceptions, use {@link 267  * Futures#getUnchecked}. 268  * </ul> 269  * 270  * @throws ExecutionException if the computation threw an exception 271  * @throws CancellationException if the computation was cancelled 272  * @throws TimeoutException if the wait timed out 273  * @since 28.0 274  */ 275  @CanIgnoreReturnValue 276  @GwtIncompatible // java.time.Duration 277  @Beta 278  @ParametricNullness 279  public static <V extends @Nullable Object> V getUninterruptibly( 280  Future<V> future, Duration timeout) throws ExecutionException, TimeoutException { 281  return getUninterruptibly(future, toNanosSaturated(timeout), TimeUnit.NANOSECONDS); 282  } 283  284  /** 285  * Invokes {@code future.}{@link Future#get(long, TimeUnit) get(timeout, unit)} uninterruptibly. 286  * 287  * <p>Similar methods: 288  * 289  * <ul> 290  * <li>To retrieve a result from a {@code Future} that is already done, use {@link 291  * Futures#getDone Futures.getDone}. 292  * <li>To treat {@link InterruptedException} uniformly with other exceptions, use {@link 293  * Futures#getChecked(Future, Class, long, TimeUnit) Futures.getChecked}. 294  * <li>To get uninterruptibility and remove checked exceptions, use {@link 295  * Futures#getUnchecked}. 296  * </ul> 297  * 298  * @throws ExecutionException if the computation threw an exception 299  * @throws CancellationException if the computation was cancelled 300  * @throws TimeoutException if the wait timed out 301  */ 302  @CanIgnoreReturnValue 303  @GwtIncompatible // TODO 304  @SuppressWarnings("GoodTime") // should accept a java.time.Duration 305  @ParametricNullness 306  public static <V extends @Nullable Object> V getUninterruptibly( 307  Future<V> future, long timeout, TimeUnit unit) throws ExecutionException, TimeoutException { 308  boolean interrupted = false; 309  try { 310  long remainingNanos = unit.toNanos(timeout); 311  long end = System.nanoTime() + remainingNanos; 312  313  while (true) { 314  try { 315  // Future treats negative timeouts just like zero. 316  return future.get(remainingNanos, NANOSECONDS); 317  } catch (InterruptedException e) { 318  interrupted = true; 319  remainingNanos = end - System.nanoTime(); 320  } 321  } 322  } finally { 323  if (interrupted) { 324  Thread.currentThread().interrupt(); 325  } 326  } 327  } 328  329  /** Invokes {@code queue.}{@link BlockingQueue#take() take()} uninterruptibly. */ 330  @GwtIncompatible // concurrency 331  public static <E> E takeUninterruptibly(BlockingQueue<E> queue) { 332  boolean interrupted = false; 333  try { 334  while (true) { 335  try { 336  return queue.take(); 337  } catch (InterruptedException e) { 338  interrupted = true; 339  } 340  } 341  } finally { 342  if (interrupted) { 343  Thread.currentThread().interrupt(); 344  } 345  } 346  } 347  348  /** 349  * Invokes {@code queue.}{@link BlockingQueue#put(Object) put(element)} uninterruptibly. 350  * 351  * @throws ClassCastException if the class of the specified element prevents it from being added 352  * to the given queue 353  * @throws IllegalArgumentException if some property of the specified element prevents it from 354  * being added to the given queue 355  */ 356  @GwtIncompatible // concurrency 357  public static <E> void putUninterruptibly(BlockingQueue<E> queue, E element) { 358  boolean interrupted = false; 359  try { 360  while (true) { 361  try { 362  queue.put(element); 363  return; 364  } catch (InterruptedException e) { 365  interrupted = true; 366  } 367  } 368  } finally { 369  if (interrupted) { 370  Thread.currentThread().interrupt(); 371  } 372  } 373  } 374  375  // TODO(user): Support Sleeper somehow (wrapper or interface method)? 376  /** 377  * Invokes {@code unit.}{@link TimeUnit#sleep(long) sleep(sleepFor)} uninterruptibly. 378  * 379  * @since 28.0 380  */ 381  @GwtIncompatible // concurrency 382  @Beta 383  public static void sleepUninterruptibly(Duration sleepFor) { 384  sleepUninterruptibly(toNanosSaturated(sleepFor), TimeUnit.NANOSECONDS); 385  } 386  387  // TODO(user): Support Sleeper somehow (wrapper or interface method)? 388  /** Invokes {@code unit.}{@link TimeUnit#sleep(long) sleep(sleepFor)} uninterruptibly. */ 389  @GwtIncompatible // concurrency 390  @SuppressWarnings("GoodTime") // should accept a java.time.Duration 391  public static void sleepUninterruptibly(long sleepFor, TimeUnit unit) { 392  boolean interrupted = false; 393  try { 394  long remainingNanos = unit.toNanos(sleepFor); 395  long end = System.nanoTime() + remainingNanos; 396  while (true) { 397  try { 398  // TimeUnit.sleep() treats negative timeouts just like zero. 399  NANOSECONDS.sleep(remainingNanos); 400  return; 401  } catch (InterruptedException e) { 402  interrupted = true; 403  remainingNanos = end - System.nanoTime(); 404  } 405  } 406  } finally { 407  if (interrupted) { 408  Thread.currentThread().interrupt(); 409  } 410  } 411  } 412  413  /** 414  * Invokes {@code semaphore.}{@link Semaphore#tryAcquire(int, long, TimeUnit) tryAcquire(1, 415  * timeout, unit)} uninterruptibly. 416  * 417  * @since 28.0 418  */ 419  @GwtIncompatible // concurrency 420  @Beta 421  public static boolean tryAcquireUninterruptibly(Semaphore semaphore, Duration timeout) { 422  return tryAcquireUninterruptibly(semaphore, toNanosSaturated(timeout), TimeUnit.NANOSECONDS); 423  } 424  425  /** 426  * Invokes {@code semaphore.}{@link Semaphore#tryAcquire(int, long, TimeUnit) tryAcquire(1, 427  * timeout, unit)} uninterruptibly. 428  * 429  * @since 18.0 430  */ 431  @GwtIncompatible // concurrency 432  @SuppressWarnings("GoodTime") // should accept a java.time.Duration 433  public static boolean tryAcquireUninterruptibly( 434  Semaphore semaphore, long timeout, TimeUnit unit) { 435  return tryAcquireUninterruptibly(semaphore, 1, timeout, unit); 436  } 437  438  /** 439  * Invokes {@code semaphore.}{@link Semaphore#tryAcquire(int, long, TimeUnit) tryAcquire(permits, 440  * timeout, unit)} uninterruptibly. 441  * 442  * @since 28.0 443  */ 444  @GwtIncompatible // concurrency 445  @Beta 446  public static boolean tryAcquireUninterruptibly( 447  Semaphore semaphore, int permits, Duration timeout) { 448  return tryAcquireUninterruptibly( 449  semaphore, permits, toNanosSaturated(timeout), TimeUnit.NANOSECONDS); 450  } 451  452  /** 453  * Invokes {@code semaphore.}{@link Semaphore#tryAcquire(int, long, TimeUnit) tryAcquire(permits, 454  * timeout, unit)} uninterruptibly. 455  * 456  * @since 18.0 457  */ 458  @GwtIncompatible // concurrency 459  @SuppressWarnings("GoodTime") // should accept a java.time.Duration 460  public static boolean tryAcquireUninterruptibly( 461  Semaphore semaphore, int permits, long timeout, TimeUnit unit) { 462  boolean interrupted = false; 463  try { 464  long remainingNanos = unit.toNanos(timeout); 465  long end = System.nanoTime() + remainingNanos; 466  467  while (true) { 468  try { 469  // Semaphore treats negative timeouts just like zero. 470  return semaphore.tryAcquire(permits, remainingNanos, NANOSECONDS); 471  } catch (InterruptedException e) { 472  interrupted = true; 473  remainingNanos = end - System.nanoTime(); 474  } 475  } 476  } finally { 477  if (interrupted) { 478  Thread.currentThread().interrupt(); 479  } 480  } 481  } 482  483  /** 484  * Invokes {@code lock.}{@link Lock#tryLock(long, TimeUnit) tryLock(timeout, unit)} 485  * uninterruptibly. 486  * 487  * @since 30.0 488  */ 489  @GwtIncompatible // concurrency 490  @Beta 491  public static boolean tryLockUninterruptibly(Lock lock, Duration timeout) { 492  return tryLockUninterruptibly(lock, toNanosSaturated(timeout), TimeUnit.NANOSECONDS); 493  } 494  495  /** 496  * Invokes {@code lock.}{@link Lock#tryLock(long, TimeUnit) tryLock(timeout, unit)} 497  * uninterruptibly. 498  * 499  * @since 30.0 500  */ 501  @GwtIncompatible // concurrency 502  @SuppressWarnings("GoodTime") // should accept a java.time.Duration 503  public static boolean tryLockUninterruptibly(Lock lock, long timeout, TimeUnit unit) { 504  boolean interrupted = false; 505  try { 506  long remainingNanos = unit.toNanos(timeout); 507  long end = System.nanoTime() + remainingNanos; 508  509  while (true) { 510  try { 511  return lock.tryLock(remainingNanos, NANOSECONDS); 512  } catch (InterruptedException e) { 513  interrupted = true; 514  remainingNanos = end - System.nanoTime(); 515  } 516  } 517  } finally { 518  if (interrupted) { 519  Thread.currentThread().interrupt(); 520  } 521  } 522  } 523  524  /** 525  * Invokes {@code executor.}{@link ExecutorService#awaitTermination(long, TimeUnit) 526  * awaitTermination(long, TimeUnit)} uninterruptibly with no timeout. 527  * 528  * @since 30.0 529  */ 530  @Beta 531  @GwtIncompatible // concurrency 532  public static void awaitTerminationUninterruptibly(ExecutorService executor) { 533  // TODO(cpovirk): We could optimize this to avoid calling nanoTime() at all. 534  verify(awaitTerminationUninterruptibly(executor, Long.MAX_VALUE, NANOSECONDS)); 535  } 536  537  /** 538  * Invokes {@code executor.}{@link ExecutorService#awaitTermination(long, TimeUnit) 539  * awaitTermination(long, TimeUnit)} uninterruptibly. 540  * 541  * @since 30.0 542  */ 543  @Beta 544  @GwtIncompatible // concurrency 545  public static boolean awaitTerminationUninterruptibly( 546  ExecutorService executor, Duration timeout) { 547  return awaitTerminationUninterruptibly(executor, toNanosSaturated(timeout), NANOSECONDS); 548  } 549  550  /** 551  * Invokes {@code executor.}{@link ExecutorService#awaitTermination(long, TimeUnit) 552  * awaitTermination(long, TimeUnit)} uninterruptibly. 553  * 554  * @since 30.0 555  */ 556  @Beta 557  @GwtIncompatible // concurrency 558  @SuppressWarnings("GoodTime") 559  public static boolean awaitTerminationUninterruptibly( 560  ExecutorService executor, long timeout, TimeUnit unit) { 561  boolean interrupted = false; 562  try { 563  long remainingNanos = unit.toNanos(timeout); 564  long end = System.nanoTime() + remainingNanos; 565  566  while (true) { 567  try { 568  return executor.awaitTermination(remainingNanos, NANOSECONDS); 569  } catch (InterruptedException e) { 570  interrupted = true; 571  remainingNanos = end - System.nanoTime(); 572  } 573  } 574  } finally { 575  if (interrupted) { 576  Thread.currentThread().interrupt(); 577  } 578  } 579  } 580  581  // TODO(user): Add support for waitUninterruptibly. 582  583  private Uninterruptibles() {} 584 }