Skip to content

Commit cbf4f00

Browse files
committed
refactor the ThreadLocal approach
1 parent 1284d59 commit cbf4f00

File tree

1 file changed

+17
-27
lines changed

1 file changed

+17
-27
lines changed

driver-core/src/main/com/mongodb/internal/async/function/AsyncCallbackLoop.java

Lines changed: 17 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public AsyncCallbackLoop(final LoopState state, final AsyncCallbackRunnable body
5151

5252
@Override
5353
public void run(final SingleResultCallback<Void> callback) {
54-
body.run(false, new ReusableLoopCallback(callback));
54+
body.run(false, callback);
5555
}
5656

5757
private static final class Body {
@@ -82,7 +82,7 @@ private Body(final LoopState state, final AsyncCallbackRunnable body) {
8282
*
8383
* <p>If another iteration is needed, it is initiated from the callback passed to
8484
* {@link #body}{@code .}{@link AsyncCallbackRunnable#run(SingleResultCallback) run}
85-
* by invoking {@link #run(boolean, ReusableLoopCallback)}.
85+
* by invoking {@link #run(boolean, SingleResultCallback<Void>)}.
8686
* Completing the initiated iteration is {@linkplain SingleResultCallback#onResult(Object, Throwable) invoking} the callback.
8787
* Thus, it is guaranteed that all iterations are executed sequentially with each other
8888
* (that is, completion of one iteration happens-before initiation of the next one)
@@ -109,7 +109,7 @@ private Body(final LoopState state, final AsyncCallbackRunnable body) {
109109
* <li>therefore, we would not have an iteration that is executed synchronously but in a different thread.</li>
110110
* </ul>
111111
*/
112-
boolean run(final boolean trampolining, final ReusableLoopCallback callback) {
112+
boolean run(final boolean trampolining, final SingleResultCallback<Void> afterLoopCallback) {
113113
// The `trampoliningResult` variable must be used only if the initiated iteration is executed synchronously with
114114
// the current method, which must be detected separately.
115115
//
@@ -122,7 +122,7 @@ boolean run(final boolean trampolining, final ReusableLoopCallback callback) {
122122
boolean[] trampoliningResult = {false};
123123
sameThreadDetector.set(SameThreadDetectionStatus.PROBING);
124124
body.run((r, t) -> {
125-
if (callback.onResult(state, r, t)) {
125+
if (completeIfNeeded(afterLoopCallback, r, t)) {
126126
// If we are trampolining, then here we bounce up, trampolining completes and so is the whole loop;
127127
// otherwise, the whole loop simply completes.
128128
return;
@@ -139,9 +139,10 @@ boolean run(final boolean trampolining, final ReusableLoopCallback callback) {
139139
sameThreadDetector.remove();
140140
}
141141
}
142+
// trampolining
142143
boolean anotherIterationNeeded;
143-
do { // trampolining
144-
anotherIterationNeeded = run(true, callback);
144+
do {
145+
anotherIterationNeeded = run(true, afterLoopCallback);
145146
} while (anotherIterationNeeded);
146147
});
147148
try {
@@ -150,39 +151,28 @@ boolean run(final boolean trampolining, final ReusableLoopCallback callback) {
150151
sameThreadDetector.remove();
151152
}
152153
}
153-
}
154-
155-
/**
156-
* This callback is allowed to be {@linkplain #onResult(LoopState, Void, Throwable) completed} more than once.
157-
*/
158-
@NotThreadSafe
159-
private static final class ReusableLoopCallback {
160-
private final SingleResultCallback<Void> wrapped;
161-
162-
ReusableLoopCallback(final SingleResultCallback<Void> callback) {
163-
wrapped = callback;
164-
}
165154

166155
/**
167-
* @return {@code true} iff the {@linkplain ReusableLoopCallback#ReusableLoopCallback(SingleResultCallback) wrapped}
168-
* {@link SingleResultCallback} is {@linkplain SingleResultCallback#onResult(Object, Throwable) completed}.
156+
* @return {@code true} iff the {@code afterLoopCallback} was
157+
* {@linkplain SingleResultCallback#onResult(Object, Throwable) completed}.
169158
*/
170-
public boolean onResult(final LoopState state, @Nullable final Void result, @Nullable final Throwable t) {
159+
private boolean completeIfNeeded(final SingleResultCallback<Void> afterLoopCallback,
160+
@Nullable final Void result, @Nullable final Throwable t) {
171161
if (t != null) {
172-
wrapped.onResult(null, t);
162+
afterLoopCallback.onResult(null, t);
173163
return true;
174164
} else {
175-
boolean continueLooping;
165+
boolean anotherIterationNeeded;
176166
try {
177-
continueLooping = state.advance();
167+
anotherIterationNeeded = state.advance();
178168
} catch (Throwable e) {
179-
wrapped.onResult(null, e);
169+
afterLoopCallback.onResult(null, e);
180170
return true;
181171
}
182-
if (continueLooping) {
172+
if (anotherIterationNeeded) {
183173
return false;
184174
} else {
185-
wrapped.onResult(result, null);
175+
afterLoopCallback.onResult(result, null);
186176
return true;
187177
}
188178
}

0 commit comments

Comments
 (0)