Skip to content

Commit e069cfc

Browse files
authored
Ensure MongoClient#close only actions on first call
JAVA-4215
1 parent b8d52c6 commit e069cfc

File tree

3 files changed

+32
-17
lines changed

3 files changed

+32
-17
lines changed

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

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
import java.util.concurrent.ExecutorService;
5050
import java.util.concurrent.Executors;
5151
import java.util.concurrent.ScheduledExecutorService;
52+
import java.util.concurrent.atomic.AtomicBoolean;
5253
import java.util.stream.Collectors;
5354

5455
import static com.mongodb.internal.connection.ServerAddressHelper.createServerAddress;
@@ -119,6 +120,7 @@ public class MongoClient implements Closeable {
119120
private final ConcurrentLinkedQueue<ServerCursorAndNamespace> orphanedCursors = new ConcurrentLinkedQueue<>();
120121
private final ExecutorService cursorCleaningService;
121122
private final MongoClientImpl delegate;
123+
private final AtomicBoolean closed;
122124

123125
/**
124126
* Gets the default codec registry. It includes the following providers:
@@ -232,6 +234,7 @@ private MongoClient(final MongoClientSettings settings,
232234
delegate = new MongoClientImpl(settings, wrapMongoDriverInformation(mongoDriverInformation));
233235
this.options = options != null ? options : MongoClientOptions.builder(settings).build();
234236
cursorCleaningService = this.options.isCursorFinalizerEnabled() ? createCursorCleaningService() : null;
237+
this.closed = new AtomicBoolean();
235238
}
236239

237240
private static MongoDriverInformation wrapMongoDriverInformation(@Nullable final MongoDriverInformation mongoDriverInformation) {
@@ -764,9 +767,11 @@ public void dropDatabase(final String dbName) {
764767
* databases obtained from it can no longer be used.
765768
*/
766769
public void close() {
767-
delegate.close();
768-
if (cursorCleaningService != null) {
769-
cursorCleaningService.shutdownNow();
770+
if (!closed.getAndSet(true)) {
771+
delegate.close();
772+
if (cursorCleaningService != null) {
773+
cursorCleaningService.shutdownNow();
774+
}
770775
}
771776
}
772777

driver-reactive-streams/src/main/com/mongodb/reactivestreams/client/internal/MongoClientImpl.java

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import java.io.IOException;
4545
import java.util.Collections;
4646
import java.util.List;
47+
import java.util.concurrent.atomic.AtomicBoolean;
4748

4849
import static com.mongodb.assertions.Assertions.notNull;
4950
import static org.bson.internal.CodecRegistryHelper.createRegistry;
@@ -65,6 +66,7 @@ public final class MongoClientImpl implements MongoClient {
6566
private final ClientSessionHelper clientSessionHelper;
6667
private final MongoOperationPublisher<Document> mongoOperationPublisher;
6768
private final Crypt crypt;
69+
private final AtomicBoolean closed;
6870

6971
public MongoClientImpl(final MongoClientSettings settings, final Cluster cluster, @Nullable final Closeable externalResourceCloser) {
7072
this(settings, cluster, null, externalResourceCloser);
@@ -96,6 +98,7 @@ private MongoClientImpl(final MongoClientSettings settings, final Cluster cluste
9698
settings.getReadConcern(), settings.getWriteConcern(),
9799
settings.getRetryWrites(), settings.getRetryReads(),
98100
settings.getUuidRepresentation(), this.executor);
101+
this.closed = new AtomicBoolean();
99102
}
100103

101104
Cluster getCluster() {
@@ -126,16 +129,18 @@ public MongoDatabase getDatabase(final String name) {
126129

127130
@Override
128131
public void close() {
129-
if (crypt != null) {
130-
crypt.close();
131-
}
132-
serverSessionPool.close();
133-
cluster.close();
134-
if (externalResourceCloser != null) {
135-
try {
136-
externalResourceCloser.close();
137-
} catch (IOException e) {
138-
LOGGER.warn("Exception closing resource", e);
132+
if (!closed.getAndSet(true)) {
133+
if (crypt != null) {
134+
crypt.close();
135+
}
136+
serverSessionPool.close();
137+
cluster.close();
138+
if (externalResourceCloser != null) {
139+
try {
140+
externalResourceCloser.close();
141+
} catch (IOException e) {
142+
LOGGER.warn("Exception closing resource", e);
143+
}
139144
}
140145
}
141146
}

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

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
import org.bson.codecs.configuration.CodecRegistry;
4747

4848
import java.util.List;
49+
import java.util.concurrent.atomic.AtomicBoolean;
4950

5051
import static com.mongodb.MongoException.TRANSIENT_TRANSACTION_ERROR_LABEL;
5152
import static com.mongodb.MongoException.UNKNOWN_TRANSACTION_COMMIT_RESULT_LABEL;
@@ -64,6 +65,7 @@ final class MongoClientDelegate {
6465
@Nullable
6566
private final ServerApi serverApi;
6667
private final CodecRegistry codecRegistry;
68+
private final AtomicBoolean closed;
6769

6870
MongoClientDelegate(final Cluster cluster, final CodecRegistry codecRegistry,
6971
final Object originator, @Nullable final OperationExecutor operationExecutor,
@@ -75,6 +77,7 @@ final class MongoClientDelegate {
7577
this.operationExecutor = operationExecutor == null ? new DelegateOperationExecutor() : operationExecutor;
7678
this.crypt = crypt;
7779
this.serverApi = serverApi;
80+
this.closed = new AtomicBoolean();
7881
}
7982

8083
public OperationExecutor getOperationExecutor() {
@@ -109,11 +112,13 @@ public ClientSession createClientSession(final ClientSessionOptions options, fin
109112
}
110113

111114
public void close() {
112-
if (crypt != null) {
113-
crypt.close();
115+
if (!closed.getAndSet(true)) {
116+
if (crypt != null) {
117+
crypt.close();
118+
}
119+
serverSessionPool.close();
120+
cluster.close();
114121
}
115-
serverSessionPool.close();
116-
cluster.close();
117122
}
118123

119124
public Cluster getCluster() {

0 commit comments

Comments
 (0)