Skip to content

Commit 8ecee9a

Browse files
authored
Fix the await condition in OpenConcurrencyLimiter.acquirePermitOrGetAvailableOpenedConnection (#858)
JAVA-4451
1 parent 658917b commit 8ecee9a

File tree

3 files changed

+16
-7
lines changed

3 files changed

+16
-7
lines changed

config/spotbugs/exclude.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,4 +228,11 @@
228228
<Field name="permits"/>
229229
<Bug pattern="VO_VOLATILE_INCREMENT"/>
230230
</Match>
231+
232+
<!-- Non-short-circuit operators are used intentionally. -->
233+
<Match>
234+
<Class name="com.mongodb.internal.connection.DefaultConnectionPool$OpenConcurrencyLimiter"/>
235+
<Method name="acquirePermitOrGetAvailableOpenedConnection"/>
236+
<Bug pattern="NS_NON_SHORT_CIRCUIT"/>
237+
</Match>
231238
</FindBugsFilter>

driver-core/src/main/com/mongodb/internal/connection/DefaultConnectionPool.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -992,12 +992,10 @@ private PooledConnection acquirePermitOrGetAvailableOpenedConnection(final boole
992992
expressedDesireToGetAvailableConnection = true;
993993
}
994994
long remainingNanos = timeout.remainingOrInfinite(NANOSECONDS);
995-
while (permits == 0) {
996-
stateAndGeneration.throwIfClosedOrPaused();
997-
availableConnection = tryGetAvailable ? tryGetAvailableConnection() : null;
998-
if (availableConnection != null) {
999-
break;
1000-
}
995+
while (permits == 0
996+
// the absence of short-circuiting is of importance
997+
& !stateAndGeneration.throwIfClosedOrPaused()
998+
& (availableConnection = tryGetAvailable ? tryGetAvailableConnection() : null) == null) {
1001999
if (Timeout.expired(remainingNanos)) {
10021000
throw createTimeoutException(timeout);
10031001
}
@@ -1523,11 +1521,14 @@ boolean close() {
15231521
}
15241522

15251523
/**
1524+
* @return {@code false} which means that the method did not throw.
1525+
* The method returns to allow using it conveniently as part of a condition check when waiting on a {@link Condition}.
1526+
* Short-circuiting operators {@code &&} and {@code ||} must not be used with this method to ensure that it is called.
15261527
* @throws MongoServerUnavailableException If and only if {@linkplain #close() closed}.
15271528
* @throws MongoConnectionPoolClearedException If and only if {@linkplain #pauseAndIncrementGeneration(Throwable) paused}
15281529
* and not {@linkplain #close() closed}.
15291530
*/
1530-
void throwIfClosedOrPaused() {
1531+
boolean throwIfClosedOrPaused() {
15311532
if (closed.get()) {
15321533
throw pool.poolClosedException();
15331534
}
@@ -1541,6 +1542,7 @@ void throwIfClosedOrPaused() {
15411542
lock.readLock().unlock();
15421543
}
15431544
}
1545+
return false;
15441546
}
15451547
}
15461548
}

0 commit comments

Comments
 (0)