Skip to content

Commit 9a4cf5e

Browse files
committed
Ensure MongoClient#close only actions on first call
Backport from: e069cfc JAVA-4215
1 parent 4219359 commit 9a4cf5e

File tree

3 files changed

+32
-17
lines changed

3 files changed

+32
-17
lines changed

driver-async/src/main/com/mongodb/async/client/MongoClientImpl.java

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import java.io.IOException;
4040
import java.util.Collections;
4141
import java.util.List;
42+
import java.util.concurrent.atomic.AtomicBoolean;
4243

4344
import static com.mongodb.assertions.Assertions.notNull;
4445
import static com.mongodb.internal.async.ErrorHandlingResultCallback.errorHandlingCallback;
@@ -55,6 +56,7 @@ class MongoClientImpl implements MongoClient {
5556
private final ClientSessionHelper clientSessionHelper;
5657
private final CodecRegistry codecRegistry;
5758
private final Crypt crypt;
59+
private final AtomicBoolean closed;
5860

5961
MongoClientImpl(final MongoClientSettings settings, final Cluster cluster, @Nullable final Closeable externalResourceCloser) {
6062
this(settings, cluster, null, externalResourceCloser);
@@ -79,6 +81,7 @@ private MongoClientImpl(final MongoClientSettings settings, final Cluster cluste
7981
}
8082
this.externalResourceCloser = externalResourceCloser;
8183
this.codecRegistry = createRegistry(settings.getCodecRegistry(), settings.getUuidRepresentation());
84+
this.closed = new AtomicBoolean();
8285
}
8386

8487
@Override
@@ -113,16 +116,18 @@ public MongoDatabase getDatabase(final String name) {
113116

114117
@Override
115118
public void close() {
116-
if (crypt != null) {
117-
crypt.close();
118-
}
119-
serverSessionPool.close();
120-
cluster.close();
121-
if (externalResourceCloser != null) {
122-
try {
123-
externalResourceCloser.close();
124-
} catch (IOException e) {
125-
LOGGER.warn("Exception closing resource", e);
119+
if (!closed.getAndSet(true)) {
120+
if (crypt != null) {
121+
crypt.close();
122+
}
123+
serverSessionPool.close();
124+
cluster.close();
125+
if (externalResourceCloser != null) {
126+
try {
127+
externalResourceCloser.close();
128+
} catch (IOException e) {
129+
LOGGER.warn("Exception closing resource", e);
130+
}
126131
}
127132
}
128133
}

driver-legacy/src/main/com/mongodb/Mongo.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
import java.util.concurrent.ExecutorService;
5858
import java.util.concurrent.Executors;
5959
import java.util.concurrent.ScheduledExecutorService;
60+
import java.util.concurrent.atomic.AtomicBoolean;
6061

6162
import static com.mongodb.ReadPreference.primary;
6263
import static com.mongodb.client.internal.Crypts.createCrypt;
@@ -104,6 +105,7 @@ public class Mongo {
104105
private final ConcurrentLinkedQueue<ServerCursorAndNamespace> orphanedCursors = new ConcurrentLinkedQueue<ServerCursorAndNamespace>();
105106
private final ExecutorService cursorCleaningService;
106107
private final MongoClientDelegate delegate;
108+
private final AtomicBoolean closed;
107109

108110
/**
109111
* Creates a Mongo instance based on a (single) mongodb node (localhost, default port)
@@ -332,6 +334,7 @@ public Mongo(
332334
autoEncryptionSettings == null ? null : createCrypt(asSimpleMongoClient(), autoEncryptionSettings));
333335

334336
cursorCleaningService = options.isCursorFinalizerEnabled() ? createCursorCleaningService() : null;
337+
this.closed = new AtomicBoolean();
335338
}
336339

337340
// bit of a hack, but it works because only MongoClient subclass will ever make use of this
@@ -555,9 +558,11 @@ public void dropDatabase(final String dbName) {
555558
* databases obtained from it can no longer be used.
556559
*/
557560
public void close() {
558-
delegate.close();
559-
if (cursorCleaningService != null) {
560-
cursorCleaningService.shutdownNow();
561+
if (!closed.getAndSet(true)) {
562+
delegate.close();
563+
if (cursorCleaningService != null) {
564+
cursorCleaningService.shutdownNow();
565+
}
561566
}
562567
}
563568

driver-sync/src/main/com/mongodb/client/internal/MongoClientDelegate.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848

4949
import java.util.ArrayList;
5050
import java.util.List;
51+
import java.util.concurrent.atomic.AtomicBoolean;
5152

5253
import static com.mongodb.MongoException.TRANSIENT_TRANSACTION_ERROR_LABEL;
5354
import static com.mongodb.MongoException.UNKNOWN_TRANSACTION_COMMIT_RESULT_LABEL;
@@ -66,6 +67,7 @@ public class MongoClientDelegate {
6667
private final OperationExecutor operationExecutor;
6768
private final Crypt crypt;
6869
private final CodecRegistry codecRegistry;
70+
private final AtomicBoolean closed;
6971

7072
public MongoClientDelegate(final Cluster cluster, final CodecRegistry codecRegistry, final List<MongoCredential> credentialList,
7173
final Object originator, @Nullable final Crypt crypt) {
@@ -82,6 +84,7 @@ public MongoClientDelegate(final Cluster cluster, final CodecRegistry codecRegis
8284
this.originator = originator;
8385
this.operationExecutor = operationExecutor == null ? new DelegateOperationExecutor() : operationExecutor;
8486
this.crypt = crypt;
87+
this.closed = new AtomicBoolean();
8588
}
8689

8790
public OperationExecutor getOperationExecutor() {
@@ -127,11 +130,13 @@ public List<ServerAddress> getServerAddressList() {
127130
}
128131

129132
public void close() {
130-
if (crypt != null) {
131-
crypt.close();
133+
if (!closed.getAndSet(true)) {
134+
if (crypt != null) {
135+
crypt.close();
136+
}
137+
serverSessionPool.close();
138+
cluster.close();
132139
}
133-
serverSessionPool.close();
134-
cluster.close();
135140
}
136141

137142
public Cluster getCluster() {

0 commit comments

Comments
 (0)