Skip to content

Commit

Permalink
Repaired some of ListenableFuture.kt's cancellation corner cases.
Browse files Browse the repository at this point in the history
This fixes:
  - Cancellation without an untrapped CancellationException propagating
    through a Callback; isCancelled() is the correct way to check for
    cancellation
  - Bidirectional propagation of cancellation through
    `asListenableFuture()`
  - The cause getting lost in the `asListenableFuture()` future  when
    cancelling its `Deferred` parent with a cause

This also:
  - Extensively documents the package and the contracts created by the
    promise-creating extension methods and `future()`
  - Uses `getUninterruptibly()` for speed
  - Uses `AbstractFuture` to make as certain as possible that
    `Future.cancel()` will return `true` at most once
  - Should clear up rare spooky race conditions around
    cancellation/interruption in hybrid Coroutines/Guava Futures
    codebases

There are probably a few more interesting corner cases hiding in here,
but this should be a good start improving the correctness of `.guava`'s
adapters.

This is a squash commit of kotlin/pr/1347, rebased on develop:

- Incorporated first-round feedback.

- Merged CancellationToCoroutine into ListenableFutureCoroutine to save an
allocation.

- Documented and tested for null completion of asDeferred()'s parent
Future.

- Renamed a cancellation test case for clarity of purpose.

- Split asDeferred() documentation between KDoc/details

- Implemented InternalFutures faster-fast path. Documented.
  • Loading branch information
yorickhenning authored and elizarov committed Aug 29, 2019
1 parent 95d88ab commit 57cc364
Show file tree
Hide file tree
Showing 2 changed files with 596 additions and 92 deletions.

0 comments on commit 57cc364

Please sign in to comment.