Skip to content

Commit 8f0350a

Browse files
cpovirkGoogle Java Core Libraries
authored and
Google Java Core Libraries
committedMay 10, 2022
When we catch InterruptedException, take care to restore the interrupt bit.
We already were doing this in the cases in which our `catch` block was of the form `catch (InterruptedException e)`, but we weren't doing it when we were catching a more general type, such as `Exception`. RELNOTES=`util.concurrent`: Fixed some cases in which we could catch `InterruptedException` but fail to restore the interrupt bit. PiperOrigin-RevId: 447706714
1 parent cd5cf32 commit 8f0350a

22 files changed

+80
-0
lines changed
 

‎android/guava/src/com/google/common/util/concurrent/AbstractCatchingFuture.java

+2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import static com.google.common.util.concurrent.MoreExecutors.rejectionPropagatingExecutor;
2020
import static com.google.common.util.concurrent.NullnessCasts.uncheckedCastNullableTToT;
2121
import static com.google.common.util.concurrent.Platform.isInstanceOfThrowableClass;
22+
import static com.google.common.util.concurrent.Platform.restoreInterruptIfIsInterruptedException;
2223

2324
import com.google.common.annotations.GwtCompatible;
2425
import com.google.common.base.Function;
@@ -132,6 +133,7 @@ public final void run() {
132133
try {
133134
fallbackResult = doFallback(localFallback, castThrowable);
134135
} catch (Throwable t) {
136+
restoreInterruptIfIsInterruptedException(t);
135137
setException(t);
136138
return;
137139
} finally {

‎android/guava/src/com/google/common/util/concurrent/AbstractExecutionThreadService.java

+5
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
package com.google.common.util.concurrent;
1616

17+
import static com.google.common.util.concurrent.Platform.restoreInterruptIfIsInterruptedException;
18+
1719
import com.google.common.annotations.Beta;
1820
import com.google.common.annotations.GwtIncompatible;
1921
import com.google.common.base.Supplier;
@@ -65,9 +67,11 @@ public void run() {
6567
try {
6668
AbstractExecutionThreadService.this.run();
6769
} catch (Throwable t) {
70+
restoreInterruptIfIsInterruptedException(t);
6871
try {
6972
shutDown();
7073
} catch (Exception ignored) {
74+
restoreInterruptIfIsInterruptedException(ignored);
7175
// TODO(lukes): if guava ever moves to java7, this would be a good
7276
// candidate for a suppressed exception, or maybe we could generalize
7377
// Closer.Suppressor
@@ -84,6 +88,7 @@ public void run() {
8488
shutDown();
8589
notifyStopped();
8690
} catch (Throwable t) {
91+
restoreInterruptIfIsInterruptedException(t);
8792
notifyFailed(t);
8893
}
8994
}

‎android/guava/src/com/google/common/util/concurrent/AbstractIdleService.java

+4
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
package com.google.common.util.concurrent;
1616

17+
import static com.google.common.util.concurrent.Platform.restoreInterruptIfIsInterruptedException;
18+
1719
import com.google.common.annotations.GwtIncompatible;
1820
import com.google.common.base.Supplier;
1921
import com.google.errorprone.annotations.CanIgnoreReturnValue;
@@ -61,6 +63,7 @@ public void run() {
6163
startUp();
6264
notifyStarted();
6365
} catch (Throwable t) {
66+
restoreInterruptIfIsInterruptedException(t);
6467
notifyFailed(t);
6568
}
6669
}
@@ -78,6 +81,7 @@ public void run() {
7881
shutDown();
7982
notifyStopped();
8083
} catch (Throwable t) {
84+
restoreInterruptIfIsInterruptedException(t);
8185
notifyFailed(t);
8286
}
8387
}

‎android/guava/src/com/google/common/util/concurrent/AbstractScheduledService.java

+6
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import static com.google.common.base.Preconditions.checkNotNull;
1919
import static com.google.common.util.concurrent.Futures.immediateCancelledFuture;
2020
import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
21+
import static com.google.common.util.concurrent.Platform.restoreInterruptIfIsInterruptedException;
2122
import static java.util.Objects.requireNonNull;
2223

2324
import com.google.common.annotations.GwtIncompatible;
@@ -202,9 +203,11 @@ public void run() {
202203
}
203204
AbstractScheduledService.this.runOneIteration();
204205
} catch (Throwable t) {
206+
restoreInterruptIfIsInterruptedException(t);
205207
try {
206208
shutDown();
207209
} catch (Exception ignored) {
210+
restoreInterruptIfIsInterruptedException(ignored);
208211
logger.log(
209212
Level.WARNING,
210213
"Error while attempting to shut down the service after failure.",
@@ -242,6 +245,7 @@ public void run() {
242245
runningTask = scheduler().schedule(delegate, executorService, task);
243246
notifyStarted();
244247
} catch (Throwable t) {
248+
restoreInterruptIfIsInterruptedException(t);
245249
notifyFailed(t);
246250
if (runningTask != null) {
247251
// prevent the task from running if possible
@@ -280,6 +284,7 @@ public void run() {
280284
}
281285
notifyStopped();
282286
} catch (Throwable t) {
287+
restoreInterruptIfIsInterruptedException(t);
283288
notifyFailed(t);
284289
}
285290
}
@@ -553,6 +558,7 @@ public Cancellable reschedule() {
553558
try {
554559
schedule = CustomScheduler.this.getNextSchedule();
555560
} catch (Throwable t) {
561+
restoreInterruptIfIsInterruptedException(t);
556562
service.notifyFailed(t);
557563
return new FutureAsCancellable(immediateCancelledFuture());
558564
}

‎android/guava/src/com/google/common/util/concurrent/AbstractService.java

+3
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import static com.google.common.base.Preconditions.checkArgument;
1818
import static com.google.common.base.Preconditions.checkNotNull;
1919
import static com.google.common.base.Preconditions.checkState;
20+
import static com.google.common.util.concurrent.Platform.restoreInterruptIfIsInterruptedException;
2021
import static com.google.common.util.concurrent.Service.State.FAILED;
2122
import static com.google.common.util.concurrent.Service.State.NEW;
2223
import static com.google.common.util.concurrent.Service.State.RUNNING;
@@ -249,6 +250,7 @@ public final Service startAsync() {
249250
enqueueStartingEvent();
250251
doStart();
251252
} catch (Throwable startupFailure) {
253+
restoreInterruptIfIsInterruptedException(startupFailure);
252254
notifyFailed(startupFailure);
253255
} finally {
254256
monitor.leave();
@@ -288,6 +290,7 @@ public final Service stopAsync() {
288290
throw new AssertionError("isStoppable is incorrectly implemented, saw: " + previous);
289291
}
290292
} catch (Throwable shutdownFailure) {
293+
restoreInterruptIfIsInterruptedException(shutdownFailure);
291294
notifyFailed(shutdownFailure);
292295
} finally {
293296
monitor.leave();

‎android/guava/src/com/google/common/util/concurrent/AbstractTransformFuture.java

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import static com.google.common.base.Preconditions.checkNotNull;
1818
import static com.google.common.util.concurrent.Futures.getDone;
1919
import static com.google.common.util.concurrent.MoreExecutors.rejectionPropagatingExecutor;
20+
import static com.google.common.util.concurrent.Platform.restoreInterruptIfIsInterruptedException;
2021

2122
import com.google.common.annotations.GwtCompatible;
2223
import com.google.common.base.Function;
@@ -121,6 +122,7 @@ public final void run() {
121122
try {
122123
transformResult = doTransform(localFunction, sourceResult);
123124
} catch (Throwable t) {
125+
restoreInterruptIfIsInterruptedException(t);
124126
// This exception is irrelevant in this thread, but useful for the client.
125127
setException(t);
126128
return;

‎android/guava/src/com/google/common/util/concurrent/FakeTimeLimiter.java

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package com.google.common.util.concurrent;
1616

1717
import static com.google.common.base.Preconditions.checkNotNull;
18+
import static com.google.common.util.concurrent.Platform.restoreInterruptIfIsInterruptedException;
1819

1920
import com.google.common.annotations.Beta;
2021
import com.google.common.annotations.GwtIncompatible;
@@ -59,6 +60,7 @@ public <T> T newProxy(
5960
} catch (RuntimeException e) {
6061
throw new UncheckedExecutionException(e);
6162
} catch (Exception e) {
63+
restoreInterruptIfIsInterruptedException(e);
6264
throw new ExecutionException(e);
6365
} catch (Error e) {
6466
throw new ExecutionError(e);

‎android/guava/src/com/google/common/util/concurrent/InterruptibleTask.java

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package com.google.common.util.concurrent;
1616

1717
import static com.google.common.util.concurrent.NullnessCasts.uncheckedCastNullableTToT;
18+
import static com.google.common.util.concurrent.Platform.restoreInterruptIfIsInterruptedException;
1819

1920
import com.google.common.annotations.GwtCompatible;
2021
import com.google.common.annotations.VisibleForTesting;
@@ -74,6 +75,7 @@ public final void run() {
7475
result = runInterruptibly();
7576
}
7677
} catch (Throwable t) {
78+
restoreInterruptIfIsInterruptedException(t);
7779
error = t;
7880
} finally {
7981
// Attempt to set the task as done so that further attempts to interrupt will fail.

‎android/guava/src/com/google/common/util/concurrent/Platform.java

+10
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414

1515
package com.google.common.util.concurrent;
1616

17+
import static com.google.common.base.Preconditions.checkNotNull;
18+
import static java.lang.Thread.currentThread;
19+
1720
import com.google.common.annotations.GwtCompatible;
1821
import javax.annotation.CheckForNull;
1922

@@ -26,5 +29,12 @@ static boolean isInstanceOfThrowableClass(
2629
return expectedClass.isInstance(t);
2730
}
2831

32+
static void restoreInterruptIfIsInterruptedException(Throwable t) {
33+
checkNotNull(t); // to satisfy NullPointerTester
34+
if (t instanceof InterruptedException) {
35+
currentThread().interrupt();
36+
}
37+
}
38+
2939
private Platform() {}
3040
}

‎android/guava/src/com/google/common/util/concurrent/WrappingExecutorService.java

+2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import static com.google.common.base.Preconditions.checkNotNull;
1818
import static com.google.common.base.Throwables.throwIfUnchecked;
19+
import static com.google.common.util.concurrent.Platform.restoreInterruptIfIsInterruptedException;
1920

2021
import com.google.common.annotations.GwtIncompatible;
2122
import com.google.common.collect.ImmutableList;
@@ -66,6 +67,7 @@ protected Runnable wrapTask(Runnable command) {
6667
try {
6768
wrapped.call();
6869
} catch (Exception e) {
70+
restoreInterruptIfIsInterruptedException(e);
6971
throwIfUnchecked(e);
7072
throw new RuntimeException(e);
7173
}

‎guava-gwt/src-super/com/google/common/util/concurrent/super/com/google/common/util/concurrent/Platform.java

+2
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,7 @@ static boolean isInstanceOfThrowableClass(Throwable t, Class<? extends Throwable
2626
return true;
2727
}
2828

29+
static void restoreInterruptIfIsInterruptedException(Throwable t) {}
30+
2931
private Platform() {}
3032
}

‎guava/src/com/google/common/util/concurrent/AbstractCatchingFuture.java

+2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import static com.google.common.util.concurrent.MoreExecutors.rejectionPropagatingExecutor;
2020
import static com.google.common.util.concurrent.NullnessCasts.uncheckedCastNullableTToT;
2121
import static com.google.common.util.concurrent.Platform.isInstanceOfThrowableClass;
22+
import static com.google.common.util.concurrent.Platform.restoreInterruptIfIsInterruptedException;
2223

2324
import com.google.common.annotations.GwtCompatible;
2425
import com.google.common.base.Function;
@@ -132,6 +133,7 @@ public final void run() {
132133
try {
133134
fallbackResult = doFallback(localFallback, castThrowable);
134135
} catch (Throwable t) {
136+
restoreInterruptIfIsInterruptedException(t);
135137
setException(t);
136138
return;
137139
} finally {

‎guava/src/com/google/common/util/concurrent/AbstractExecutionThreadService.java

+5
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
package com.google.common.util.concurrent;
1616

17+
import static com.google.common.util.concurrent.Platform.restoreInterruptIfIsInterruptedException;
18+
1719
import com.google.common.annotations.Beta;
1820
import com.google.common.annotations.GwtIncompatible;
1921
import com.google.common.base.Supplier;
@@ -66,9 +68,11 @@ public void run() {
6668
try {
6769
AbstractExecutionThreadService.this.run();
6870
} catch (Throwable t) {
71+
restoreInterruptIfIsInterruptedException(t);
6972
try {
7073
shutDown();
7174
} catch (Exception ignored) {
75+
restoreInterruptIfIsInterruptedException(ignored);
7276
// TODO(lukes): if guava ever moves to java7, this would be a good
7377
// candidate for a suppressed exception, or maybe we could generalize
7478
// Closer.Suppressor
@@ -85,6 +89,7 @@ public void run() {
8589
shutDown();
8690
notifyStopped();
8791
} catch (Throwable t) {
92+
restoreInterruptIfIsInterruptedException(t);
8893
notifyFailed(t);
8994
}
9095
}

‎guava/src/com/google/common/util/concurrent/AbstractIdleService.java

+4
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
package com.google.common.util.concurrent;
1616

17+
import static com.google.common.util.concurrent.Platform.restoreInterruptIfIsInterruptedException;
18+
1719
import com.google.common.annotations.GwtIncompatible;
1820
import com.google.common.base.Supplier;
1921
import com.google.errorprone.annotations.CanIgnoreReturnValue;
@@ -62,6 +64,7 @@ public void run() {
6264
startUp();
6365
notifyStarted();
6466
} catch (Throwable t) {
67+
restoreInterruptIfIsInterruptedException(t);
6568
notifyFailed(t);
6669
}
6770
}
@@ -79,6 +82,7 @@ public void run() {
7982
shutDown();
8083
notifyStopped();
8184
} catch (Throwable t) {
85+
restoreInterruptIfIsInterruptedException(t);
8286
notifyFailed(t);
8387
}
8488
}

‎guava/src/com/google/common/util/concurrent/AbstractScheduledService.java

+6
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import static com.google.common.util.concurrent.Futures.immediateCancelledFuture;
2020
import static com.google.common.util.concurrent.Internal.toNanosSaturated;
2121
import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
22+
import static com.google.common.util.concurrent.Platform.restoreInterruptIfIsInterruptedException;
2223
import static java.util.Objects.requireNonNull;
2324
import static java.util.concurrent.TimeUnit.NANOSECONDS;
2425

@@ -232,9 +233,11 @@ public void run() {
232233
}
233234
AbstractScheduledService.this.runOneIteration();
234235
} catch (Throwable t) {
236+
restoreInterruptIfIsInterruptedException(t);
235237
try {
236238
shutDown();
237239
} catch (Exception ignored) {
240+
restoreInterruptIfIsInterruptedException(ignored);
238241
logger.log(
239242
Level.WARNING,
240243
"Error while attempting to shut down the service after failure.",
@@ -272,6 +275,7 @@ public void run() {
272275
runningTask = scheduler().schedule(delegate, executorService, task);
273276
notifyStarted();
274277
} catch (Throwable t) {
278+
restoreInterruptIfIsInterruptedException(t);
275279
notifyFailed(t);
276280
if (runningTask != null) {
277281
// prevent the task from running if possible
@@ -310,6 +314,7 @@ public void run() {
310314
}
311315
notifyStopped();
312316
} catch (Throwable t) {
317+
restoreInterruptIfIsInterruptedException(t);
313318
notifyFailed(t);
314319
}
315320
}
@@ -595,6 +600,7 @@ public Cancellable reschedule() {
595600
try {
596601
schedule = CustomScheduler.this.getNextSchedule();
597602
} catch (Throwable t) {
603+
restoreInterruptIfIsInterruptedException(t);
598604
service.notifyFailed(t);
599605
return new FutureAsCancellable(immediateCancelledFuture());
600606
}

‎guava/src/com/google/common/util/concurrent/AbstractService.java

+3
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import static com.google.common.base.Preconditions.checkArgument;
1818
import static com.google.common.base.Preconditions.checkNotNull;
1919
import static com.google.common.base.Preconditions.checkState;
20+
import static com.google.common.util.concurrent.Platform.restoreInterruptIfIsInterruptedException;
2021
import static com.google.common.util.concurrent.Service.State.FAILED;
2122
import static com.google.common.util.concurrent.Service.State.NEW;
2223
import static com.google.common.util.concurrent.Service.State.RUNNING;
@@ -250,6 +251,7 @@ public final Service startAsync() {
250251
enqueueStartingEvent();
251252
doStart();
252253
} catch (Throwable startupFailure) {
254+
restoreInterruptIfIsInterruptedException(startupFailure);
253255
notifyFailed(startupFailure);
254256
} finally {
255257
monitor.leave();
@@ -289,6 +291,7 @@ public final Service stopAsync() {
289291
throw new AssertionError("isStoppable is incorrectly implemented, saw: " + previous);
290292
}
291293
} catch (Throwable shutdownFailure) {
294+
restoreInterruptIfIsInterruptedException(shutdownFailure);
292295
notifyFailed(shutdownFailure);
293296
} finally {
294297
monitor.leave();

‎guava/src/com/google/common/util/concurrent/AbstractTransformFuture.java

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import static com.google.common.base.Preconditions.checkNotNull;
1818
import static com.google.common.util.concurrent.Futures.getDone;
1919
import static com.google.common.util.concurrent.MoreExecutors.rejectionPropagatingExecutor;
20+
import static com.google.common.util.concurrent.Platform.restoreInterruptIfIsInterruptedException;
2021

2122
import com.google.common.annotations.GwtCompatible;
2223
import com.google.common.base.Function;
@@ -121,6 +122,7 @@ public final void run() {
121122
try {
122123
transformResult = doTransform(localFunction, sourceResult);
123124
} catch (Throwable t) {
125+
restoreInterruptIfIsInterruptedException(t);
124126
// This exception is irrelevant in this thread, but useful for the client.
125127
setException(t);
126128
return;

‎guava/src/com/google/common/util/concurrent/ClosingFuture.java

+2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import static com.google.common.util.concurrent.Futures.immediateFuture;
3333
import static com.google.common.util.concurrent.Futures.nonCancellationPropagating;
3434
import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
35+
import static com.google.common.util.concurrent.Platform.restoreInterruptIfIsInterruptedException;
3536
import static java.util.logging.Level.FINER;
3637
import static java.util.logging.Level.SEVERE;
3738
import static java.util.logging.Level.WARNING;
@@ -2169,6 +2170,7 @@ public void run() {
21692170
try {
21702171
closeable.close();
21712172
} catch (Exception e) {
2173+
restoreInterruptIfIsInterruptedException(e);
21722174
logger.log(WARNING, "thrown by close()", e);
21732175
}
21742176
}

‎guava/src/com/google/common/util/concurrent/FakeTimeLimiter.java

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package com.google.common.util.concurrent;
1616

1717
import static com.google.common.base.Preconditions.checkNotNull;
18+
import static com.google.common.util.concurrent.Platform.restoreInterruptIfIsInterruptedException;
1819

1920
import com.google.common.annotations.Beta;
2021
import com.google.common.annotations.GwtIncompatible;
@@ -59,6 +60,7 @@ public <T> T newProxy(
5960
} catch (RuntimeException e) {
6061
throw new UncheckedExecutionException(e);
6162
} catch (Exception e) {
63+
restoreInterruptIfIsInterruptedException(e);
6264
throw new ExecutionException(e);
6365
} catch (Error e) {
6466
throw new ExecutionError(e);

‎guava/src/com/google/common/util/concurrent/InterruptibleTask.java

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package com.google.common.util.concurrent;
1616

1717
import static com.google.common.util.concurrent.NullnessCasts.uncheckedCastNullableTToT;
18+
import static com.google.common.util.concurrent.Platform.restoreInterruptIfIsInterruptedException;
1819

1920
import com.google.common.annotations.GwtCompatible;
2021
import com.google.common.annotations.VisibleForTesting;
@@ -74,6 +75,7 @@ public final void run() {
7475
result = runInterruptibly();
7576
}
7677
} catch (Throwable t) {
78+
restoreInterruptIfIsInterruptedException(t);
7779
error = t;
7880
} finally {
7981
// Attempt to set the task as done so that further attempts to interrupt will fail.

‎guava/src/com/google/common/util/concurrent/Platform.java

+10
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414

1515
package com.google.common.util.concurrent;
1616

17+
import static com.google.common.base.Preconditions.checkNotNull;
18+
import static java.lang.Thread.currentThread;
19+
1720
import com.google.common.annotations.GwtCompatible;
1821
import javax.annotation.CheckForNull;
1922

@@ -26,5 +29,12 @@ static boolean isInstanceOfThrowableClass(
2629
return expectedClass.isInstance(t);
2730
}
2831

32+
static void restoreInterruptIfIsInterruptedException(Throwable t) {
33+
checkNotNull(t); // to satisfy NullPointerTester
34+
if (t instanceof InterruptedException) {
35+
currentThread().interrupt();
36+
}
37+
}
38+
2939
private Platform() {}
3040
}

‎guava/src/com/google/common/util/concurrent/WrappingExecutorService.java

+2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import static com.google.common.base.Preconditions.checkNotNull;
1818
import static com.google.common.base.Throwables.throwIfUnchecked;
19+
import static com.google.common.util.concurrent.Platform.restoreInterruptIfIsInterruptedException;
1920

2021
import com.google.common.annotations.GwtIncompatible;
2122
import com.google.common.collect.ImmutableList;
@@ -66,6 +67,7 @@ protected Runnable wrapTask(Runnable command) {
6667
try {
6768
wrapped.call();
6869
} catch (Exception e) {
70+
restoreInterruptIfIsInterruptedException(e);
6971
throwIfUnchecked(e);
7072
throw new RuntimeException(e);
7173
}

0 commit comments

Comments
 (0)
Please sign in to comment.