Skip to content

Commit 5cf64ba

Browse files
committed
Protect AsyncChangeStreamBatchCursor against multiple calls to close
JAVA-3407
1 parent 9acf101 commit 5cf64ba

File tree

2 files changed

+20
-5
lines changed

2 files changed

+20
-5
lines changed

driver-core/src/main/com/mongodb/operation/AsyncChangeStreamBatchCursor.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,10 @@ public void apply(final AsyncAggregateResponseBatchCursor<RawBsonDocument> curso
8383

8484
@Override
8585
public void close() {
86-
wrapped.close();
87-
binding.release();
86+
if (!isClosed()) {
87+
wrapped.close();
88+
binding.release();
89+
}
8890
}
8991

9092
@Override

driver-core/src/test/unit/com/mongodb/operation/AsyncChangeStreamBatchCursorSpecification.groovy

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class AsyncChangeStreamBatchCursorSpecification extends Specification {
2525
def 'should call the underlying AsyncQueryBatchCursor'() {
2626
given:
2727
def changeStreamOpertation = Stub(ChangeStreamOperation)
28-
def binding = Stub(AsyncReadBinding)
28+
def binding = Mock(AsyncReadBinding)
2929
def wrapped = Mock(AsyncQueryBatchCursor)
3030
def callback = Stub(SingleResultCallback)
3131
def cursor = new AsyncChangeStreamBatchCursor(changeStreamOpertation, wrapped, binding, null)
@@ -46,13 +46,26 @@ class AsyncChangeStreamBatchCursorSpecification extends Specification {
4646
cursor.next(callback)
4747

4848
then:
49-
1 * wrapped.next(_) >> { it[0].onResult([], null) }
49+
1 * wrapped.next(_) >> { it[0].onResult(null, null) }
5050

5151
when:
5252
cursor.close()
5353

5454
then:
55+
1 * wrapped.isClosed() >> {
56+
false
57+
}
5558
1 * wrapped.close()
56-
}
59+
1 * binding.release()
60+
61+
when:
62+
cursor.close()
5763

64+
then:
65+
1 * wrapped.isClosed() >> {
66+
true
67+
}
68+
0 * wrapped.close()
69+
0 * binding.release()
70+
}
5871
}

0 commit comments

Comments
 (0)