Skip to content

Commit 26dddf5

Browse files
authored
3.x: Fix Schedulers.from to honor interruptibleWorker across methods (#7203)
1 parent 2591862 commit 26dddf5

14 files changed

+499
-28
lines changed

Diff for: src/main/java/io/reactivex/rxjava3/internal/schedulers/AbstractDirectTask.java

+14-3
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,17 @@ abstract class AbstractDirectTask
3232

3333
protected final Runnable runnable;
3434

35+
protected final boolean interruptOnCancel;
36+
3537
protected Thread runner;
3638

3739
protected static final FutureTask<Void> FINISHED = new FutureTask<>(Functions.EMPTY_RUNNABLE, null);
3840

3941
protected static final FutureTask<Void> DISPOSED = new FutureTask<>(Functions.EMPTY_RUNNABLE, null);
4042

41-
AbstractDirectTask(Runnable runnable) {
43+
AbstractDirectTask(Runnable runnable, boolean interruptOnCancel) {
4244
this.runnable = runnable;
45+
this.interruptOnCancel = interruptOnCancel;
4346
}
4447

4548
@Override
@@ -48,7 +51,7 @@ public final void dispose() {
4851
if (f != FINISHED && f != DISPOSED) {
4952
if (compareAndSet(f, DISPOSED)) {
5053
if (f != null) {
51-
f.cancel(runner != Thread.currentThread());
54+
cancelFuture(f);
5255
}
5356
}
5457
}
@@ -67,7 +70,7 @@ public final void setFuture(Future<?> future) {
6770
break;
6871
}
6972
if (f == DISPOSED) {
70-
future.cancel(runner != Thread.currentThread());
73+
cancelFuture(future);
7174
break;
7275
}
7376
if (compareAndSet(f, future)) {
@@ -76,6 +79,14 @@ public final void setFuture(Future<?> future) {
7679
}
7780
}
7881

82+
private void cancelFuture(Future<?> future) {
83+
if (runner == Thread.currentThread()) {
84+
future.cancel(false);
85+
} else {
86+
future.cancel(interruptOnCancel);
87+
}
88+
}
89+
7990
@Override
8091
public Runnable getWrappedRunnable() {
8192
return runnable;

Diff for: src/main/java/io/reactivex/rxjava3/internal/schedulers/ExecutorScheduler.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public Disposable scheduleDirect(@NonNull Runnable run) {
5858
Runnable decoratedRun = RxJavaPlugins.onSchedule(run);
5959
try {
6060
if (executor instanceof ExecutorService) {
61-
ScheduledDirectTask task = new ScheduledDirectTask(decoratedRun);
61+
ScheduledDirectTask task = new ScheduledDirectTask(decoratedRun, interruptibleWorker);
6262
Future<?> f = ((ExecutorService)executor).submit(task);
6363
task.setFuture(f);
6464
return task;
@@ -85,7 +85,7 @@ public Disposable scheduleDirect(@NonNull Runnable run, final long delay, final
8585
final Runnable decoratedRun = RxJavaPlugins.onSchedule(run);
8686
if (executor instanceof ScheduledExecutorService) {
8787
try {
88-
ScheduledDirectTask task = new ScheduledDirectTask(decoratedRun);
88+
ScheduledDirectTask task = new ScheduledDirectTask(decoratedRun, interruptibleWorker);
8989
Future<?> f = ((ScheduledExecutorService)executor).schedule(task, delay, unit);
9090
task.setFuture(f);
9191
return task;
@@ -110,7 +110,7 @@ public Disposable schedulePeriodicallyDirect(@NonNull Runnable run, long initial
110110
if (executor instanceof ScheduledExecutorService) {
111111
Runnable decoratedRun = RxJavaPlugins.onSchedule(run);
112112
try {
113-
ScheduledDirectPeriodicTask task = new ScheduledDirectPeriodicTask(decoratedRun);
113+
ScheduledDirectPeriodicTask task = new ScheduledDirectPeriodicTask(decoratedRun, interruptibleWorker);
114114
Future<?> f = ((ScheduledExecutorService)executor).scheduleAtFixedRate(task, initialDelay, period, unit);
115115
task.setFuture(f);
116116
return task;

Diff for: src/main/java/io/reactivex/rxjava3/internal/schedulers/NewThreadWorker.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public Disposable schedule(@NonNull final Runnable action, long delayTime, @NonN
5959
* @return the ScheduledRunnable instance
6060
*/
6161
public Disposable scheduleDirect(final Runnable run, long delayTime, TimeUnit unit) {
62-
ScheduledDirectTask task = new ScheduledDirectTask(RxJavaPlugins.onSchedule(run));
62+
ScheduledDirectTask task = new ScheduledDirectTask(RxJavaPlugins.onSchedule(run), true);
6363
try {
6464
Future<?> f;
6565
if (delayTime <= 0L) {
@@ -104,7 +104,7 @@ public Disposable schedulePeriodicallyDirect(Runnable run, long initialDelay, lo
104104

105105
return periodicWrapper;
106106
}
107-
ScheduledDirectPeriodicTask task = new ScheduledDirectPeriodicTask(decoratedRun);
107+
ScheduledDirectPeriodicTask task = new ScheduledDirectPeriodicTask(decoratedRun, true);
108108
try {
109109
Future<?> f = executor.scheduleAtFixedRate(task, initialDelay, period, unit);
110110
task.setFuture(f);

Diff for: src/main/java/io/reactivex/rxjava3/internal/schedulers/ScheduledDirectPeriodicTask.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ public final class ScheduledDirectPeriodicTask extends AbstractDirectTask implem
2424

2525
private static final long serialVersionUID = 1811839108042568751L;
2626

27-
public ScheduledDirectPeriodicTask(Runnable runnable) {
28-
super(runnable);
27+
public ScheduledDirectPeriodicTask(Runnable runnable, boolean interruptOnCancel) {
28+
super(runnable, interruptOnCancel);
2929
}
3030

3131
@Override

Diff for: src/main/java/io/reactivex/rxjava3/internal/schedulers/ScheduledDirectTask.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ public final class ScheduledDirectTask extends AbstractDirectTask implements Cal
2626

2727
private static final long serialVersionUID = 1811839108042568751L;
2828

29-
public ScheduledDirectTask(Runnable runnable) {
30-
super(runnable);
29+
public ScheduledDirectTask(Runnable runnable, boolean interruptOnCancel) {
30+
super(runnable, interruptOnCancel);
3131
}
3232

3333
@Override

Diff for: src/main/java/io/reactivex/rxjava3/internal/schedulers/SingleScheduler.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ public Worker createWorker() {
106106
@NonNull
107107
@Override
108108
public Disposable scheduleDirect(@NonNull Runnable run, long delay, TimeUnit unit) {
109-
ScheduledDirectTask task = new ScheduledDirectTask(RxJavaPlugins.onSchedule(run));
109+
ScheduledDirectTask task = new ScheduledDirectTask(RxJavaPlugins.onSchedule(run), true);
110110
try {
111111
Future<?> f;
112112
if (delay <= 0L) {
@@ -146,7 +146,7 @@ public Disposable schedulePeriodicallyDirect(@NonNull Runnable run, long initial
146146

147147
return periodicWrapper;
148148
}
149-
ScheduledDirectPeriodicTask task = new ScheduledDirectPeriodicTask(decoratedRun);
149+
ScheduledDirectPeriodicTask task = new ScheduledDirectPeriodicTask(decoratedRun, true);
150150
try {
151151
Future<?> f = executor.get().scheduleAtFixedRate(task, initialDelay, period, unit);
152152
task.setFuture(f);

Diff for: src/test/java/io/reactivex/rxjava3/internal/operators/completable/CompletableTimerTest.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public void dispose() {
3737
public void timerInterruptible() throws Exception {
3838
ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
3939
try {
40-
for (Scheduler s : new Scheduler[] { Schedulers.single(), Schedulers.computation(), Schedulers.newThread(), Schedulers.io(), Schedulers.from(exec) }) {
40+
for (Scheduler s : new Scheduler[] { Schedulers.single(), Schedulers.computation(), Schedulers.newThread(), Schedulers.io(), Schedulers.from(exec, true) }) {
4141
final AtomicBoolean interrupted = new AtomicBoolean();
4242
TestObserver<Void> to = Completable.timer(1, TimeUnit.MILLISECONDS, s)
4343
.doOnComplete(new Action() {

Diff for: src/test/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableTimerTest.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ public void timerDelayZero() {
352352
public void timerInterruptible() throws Exception {
353353
ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
354354
try {
355-
for (Scheduler s : new Scheduler[] { Schedulers.single(), Schedulers.computation(), Schedulers.newThread(), Schedulers.io(), Schedulers.from(exec) }) {
355+
for (Scheduler s : new Scheduler[] { Schedulers.single(), Schedulers.computation(), Schedulers.newThread(), Schedulers.io(), Schedulers.from(exec, true) }) {
356356
final AtomicBoolean interrupted = new AtomicBoolean();
357357
TestSubscriber<Long> ts = Flowable.timer(1, TimeUnit.MILLISECONDS, s)
358358
.map(new Function<Long, Long>() {

Diff for: src/test/java/io/reactivex/rxjava3/internal/operators/maybe/MaybeTimerTest.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public void dispose() {
3737
public void timerInterruptible() throws Exception {
3838
ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
3939
try {
40-
for (Scheduler s : new Scheduler[] { Schedulers.single(), Schedulers.computation(), Schedulers.newThread(), Schedulers.io(), Schedulers.from(exec) }) {
40+
for (Scheduler s : new Scheduler[] { Schedulers.single(), Schedulers.computation(), Schedulers.newThread(), Schedulers.io(), Schedulers.from(exec, true) }) {
4141
final AtomicBoolean interrupted = new AtomicBoolean();
4242
TestObserver<Long> to = Maybe.timer(1, TimeUnit.MILLISECONDS, s)
4343
.map(new Function<Long, Long>() {

Diff for: src/test/java/io/reactivex/rxjava3/internal/operators/observable/ObservableTimerTest.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ public void timerDelayZero() {
317317
public void timerInterruptible() throws Exception {
318318
ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
319319
try {
320-
for (Scheduler s : new Scheduler[] { Schedulers.single(), Schedulers.computation(), Schedulers.newThread(), Schedulers.io(), Schedulers.from(exec) }) {
320+
for (Scheduler s : new Scheduler[] { Schedulers.single(), Schedulers.computation(), Schedulers.newThread(), Schedulers.io(), Schedulers.from(exec, true) }) {
321321
final AtomicBoolean interrupted = new AtomicBoolean();
322322
TestObserver<Long> to = Observable.timer(1, TimeUnit.MILLISECONDS, s)
323323
.map(new Function<Long, Long>() {

Diff for: src/test/java/io/reactivex/rxjava3/internal/operators/single/SingleTimerTest.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public void disposed() {
3737
public void timerInterruptible() throws Exception {
3838
ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
3939
try {
40-
for (Scheduler s : new Scheduler[] { Schedulers.single(), Schedulers.computation(), Schedulers.newThread(), Schedulers.io(), Schedulers.from(exec) }) {
40+
for (Scheduler s : new Scheduler[] { Schedulers.single(), Schedulers.computation(), Schedulers.newThread(), Schedulers.io(), Schedulers.from(exec, true) }) {
4141
final AtomicBoolean interrupted = new AtomicBoolean();
4242
TestObserver<Long> to = Single.timer(1, TimeUnit.MILLISECONDS, s)
4343
.map(new Function<Long, Long>() {

Diff for: src/test/java/io/reactivex/rxjava3/internal/schedulers/AbstractDirectTaskTest.java

+8-8
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public class AbstractDirectTaskTest extends RxJavaTest {
2727

2828
@Test
2929
public void cancelSetFuture() {
30-
AbstractDirectTask task = new AbstractDirectTask(Functions.EMPTY_RUNNABLE) {
30+
AbstractDirectTask task = new AbstractDirectTask(Functions.EMPTY_RUNNABLE, true) {
3131
private static final long serialVersionUID = 208585707945686116L;
3232
};
3333
final Boolean[] interrupted = { null };
@@ -58,7 +58,7 @@ public boolean cancel(boolean mayInterruptIfRunning) {
5858

5959
@Test
6060
public void cancelSetFutureCurrentThread() {
61-
AbstractDirectTask task = new AbstractDirectTask(Functions.EMPTY_RUNNABLE) {
61+
AbstractDirectTask task = new AbstractDirectTask(Functions.EMPTY_RUNNABLE, true) {
6262
private static final long serialVersionUID = 208585707945686116L;
6363
};
6464
final Boolean[] interrupted = { null };
@@ -91,7 +91,7 @@ public boolean cancel(boolean mayInterruptIfRunning) {
9191

9292
@Test
9393
public void setFutureCancel() {
94-
AbstractDirectTask task = new AbstractDirectTask(Functions.EMPTY_RUNNABLE) {
94+
AbstractDirectTask task = new AbstractDirectTask(Functions.EMPTY_RUNNABLE, true) {
9595
private static final long serialVersionUID = 208585707945686116L;
9696
};
9797
final Boolean[] interrupted = { null };
@@ -119,7 +119,7 @@ public boolean cancel(boolean mayInterruptIfRunning) {
119119

120120
@Test
121121
public void setFutureCancelSameThread() {
122-
AbstractDirectTask task = new AbstractDirectTask(Functions.EMPTY_RUNNABLE) {
122+
AbstractDirectTask task = new AbstractDirectTask(Functions.EMPTY_RUNNABLE, true) {
123123
private static final long serialVersionUID = 208585707945686116L;
124124
};
125125
final Boolean[] interrupted = { null };
@@ -148,7 +148,7 @@ public boolean cancel(boolean mayInterruptIfRunning) {
148148

149149
@Test
150150
public void finished() {
151-
AbstractDirectTask task = new AbstractDirectTask(Functions.EMPTY_RUNNABLE) {
151+
AbstractDirectTask task = new AbstractDirectTask(Functions.EMPTY_RUNNABLE, true) {
152152
private static final long serialVersionUID = 208585707945686116L;
153153
};
154154
final Boolean[] interrupted = { null };
@@ -177,7 +177,7 @@ public boolean cancel(boolean mayInterruptIfRunning) {
177177

178178
@Test
179179
public void finishedCancel() {
180-
AbstractDirectTask task = new AbstractDirectTask(Functions.EMPTY_RUNNABLE) {
180+
AbstractDirectTask task = new AbstractDirectTask(Functions.EMPTY_RUNNABLE, true) {
181181
private static final long serialVersionUID = 208585707945686116L;
182182
};
183183
final Boolean[] interrupted = { null };
@@ -211,7 +211,7 @@ public boolean cancel(boolean mayInterruptIfRunning) {
211211
@Test
212212
public void disposeSetFutureRace() {
213213
for (int i = 0; i < TestHelper.RACE_DEFAULT_LOOPS; i++) {
214-
final AbstractDirectTask task = new AbstractDirectTask(Functions.EMPTY_RUNNABLE) {
214+
final AbstractDirectTask task = new AbstractDirectTask(Functions.EMPTY_RUNNABLE, true) {
215215
private static final long serialVersionUID = 208585707945686116L;
216216
};
217217

@@ -246,7 +246,7 @@ static class TestDirectTask extends AbstractDirectTask {
246246
private static final long serialVersionUID = 587679821055711738L;
247247

248248
TestDirectTask() {
249-
super(Functions.EMPTY_RUNNABLE);
249+
super(Functions.EMPTY_RUNNABLE, true);
250250
}
251251
}
252252

Diff for: src/test/java/io/reactivex/rxjava3/internal/schedulers/ScheduledDirectPeriodicTaskTest.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public void runnableThrows() {
3535
public void run() {
3636
throw new TestException();
3737
}
38-
});
38+
}, true);
3939

4040
try {
4141
task.run();

0 commit comments

Comments
 (0)