{"record":{"id":"040b2296512c45cf","repo":"google/guava","slug":"unexpected-interrupt-while-waiting-for-latch","errorCode":null,"errorMessage":"Unexpected interrupt while waiting for latch","messagePattern":"Unexpected interrupt while waiting for latch","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"android/guava-testlib/src/com/google/common/testing/GcFinalization.java","lineNumber":226,"sourceCode":"   */\n  public static void await(CountDownLatch latch) {\n    if (latch.getCount() == 0) {\n      return;\n    }\n    long timeoutSeconds = timeoutSeconds();\n    long deadline = System.nanoTime() + SECONDS.toNanos(timeoutSeconds);\n    do {\n      runFinalization();\n      if (latch.getCount() == 0) {\n        return;\n      }\n      System.gc();\n      try {\n        if (latch.await(1L, SECONDS)) {\n          return;\n        }\n      } catch (InterruptedException ie) {\n        throw new RuntimeException(\"Unexpected interrupt while waiting for latch\", ie);\n      }\n    } while (System.nanoTime() - deadline < 0);\n    throw formatRuntimeException(\n        \"Latch failed to count down within %d second timeout\", timeoutSeconds);\n  }\n\n  /**\n   * Creates a garbage object that counts down the latch in its finalizer. Sequestered into a\n   * separate method to make it somewhat more likely to be unreachable.\n   */\n  private static void createUnreachableLatchFinalizer(CountDownLatch latch) {\n    FinalizableReference.register(new Object(), latch);\n  }\n\n  /**\n   * A predicate that is expected to return true subsequent to <em>finalization</em>, that is, one\n   * of the following actions taken by the garbage collector when performing a full collection in\n   * response to {@link System#gc()}:","sourceCodeStart":208,"sourceCodeEnd":244,"githubUrl":"https://github.com/google/guava/blob/94f39958baf7ad51ddf9c70e406ed6b188194daa/android/guava-testlib/src/com/google/common/testing/GcFinalization.java#L208-L244","documentation":"GcFinalization.await(CountDownLatch) loops, calling System.gc() and latch.await(1, SECONDS) until the latch counts down or the deadline expires. An InterruptedException is treated as unexpected and rethrown wrapped in a RuntimeException, because the helper assumes the awaiting thread should not be cancelled mid-wait.","triggerScenarios":"Calling GcFinalization.await(latch)/awaitFullGc() (latch variant) while the running thread is concurrently interrupted — test timeouts, executor shutdown, or harness cancellation.","commonSituations":"Test-framework timeouts interrupting the thread; finalizer-based tests where the latch is registered via FinalizableReference and the thread is cancelled before the latch counts down; stray interrupt status from prior tests.","solutions":["Ensure the thread running the await is not interrupted — widen test timeouts or move off interruptible threads.","Make the latch count down promptly (release references fast) so await(1s) returns before any interrupt lands.","If interruption is legitimate in your environment, do not use this helper; await the latch yourself and restore interrupt status on InterruptedException.","Clear stray interrupt status (Thread.interrupted()) before calling await."],"exampleFix":"// before\nGcFinalization.await(latch); // thread was interrupted -> RuntimeException\n\n// after\nThread.interrupted(); // clear status\nGcFinalization.await(latch);","handlingStrategy":"try-catch","validationCode":"// Clear stray interrupt status before awaiting the latch.\nThread.interrupted();\nassert !Thread.currentThread().isInterrupted();\nGcFinalization.await(latch);","typeGuard":null,"tryCatchPattern":"try {\n  GcFinalization.await(latch);\n} catch (RuntimeException e) {\n  if (!(e.getCause() instanceof InterruptedException)) throw e;\n  Thread.currentThread().interrupt();\n  throw e;\n}","preventionTips":["Do not run the latch await on interruptible test threads.","Set test timeouts above the GcFinalization deadline.","Clear stray interrupt status before calling await.","Ensure the latch counts down promptly (release references quickly)."],"tags":["guava","testing","concurrency","gc","interrupt","latch"],"backgroundTag":null,"analyzedSha":"94f39958baf7ad51ddf9c70e406ed6b188194daa","analyzedAt":"2026-08-13T22:50:30.265Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}