Skip to content

Commit 912e2f8

Browse files
committed
CSHARP-2188: Decrease likelihood of session leaks.
1 parent 5ba8320 commit 912e2f8

File tree

5 files changed

+184
-152
lines changed

5 files changed

+184
-152
lines changed

src/MongoDB.Driver.Core/Core/Operations/AsyncCursor.cs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public class AsyncCursor<TDocument> : IAsyncCursor<TDocument>
4646
// fields
4747
private readonly int? _batchSize;
4848
private readonly CollectionNamespace _collectionNamespace;
49-
private readonly IChannelSource _channelSource;
49+
private IChannelSource _channelSource;
5050
private int _count;
5151
private IReadOnlyList<TDocument> _currentBatch;
5252
private long _cursorId;
@@ -103,12 +103,7 @@ public AsyncCursor(
103103
}
104104
_count = _firstBatch.Count;
105105

106-
// if we aren't going to need the channel source we can go ahead and Dispose it now
107-
if (_cursorId == 0 && _channelSource != null)
108-
{
109-
_channelSource.Dispose();
110-
_channelSource = null;
111-
}
106+
DisposeChannelSourceIfNoLongerNeeded();
112107
}
113108

114109
// properties
@@ -277,6 +272,15 @@ protected virtual void Dispose(bool disposing)
277272
_disposed = true;
278273
}
279274

275+
private void DisposeChannelSourceIfNoLongerNeeded()
276+
{
277+
if (_channelSource != null && _cursorId == 0)
278+
{
279+
_channelSource.Dispose();
280+
_channelSource = null;
281+
}
282+
}
283+
280284
private CursorBatch<TDocument> GetNextBatch(CancellationToken cancellationToken)
281285
{
282286
using (EventContext.BeginOperation(_operationId))
@@ -374,6 +378,8 @@ private void SaveBatch(CursorBatch<TDocument> batch)
374378

375379
_currentBatch = documents;
376380
_cursorId = batch.CursorId;
381+
382+
DisposeChannelSourceIfNoLongerNeeded();
377383
}
378384

379385
private void ThrowIfDisposed()

tests/MongoDB.Bson.TestHelpers/MongoDB.Bson.TestHelpers.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@
8787
<Compile Include="EqualityComparers\ReferenceEqualsEqualityComparer.cs" />
8888
<Compile Include="IO\NullBsonStream.cs" />
8989
<Compile Include="Properties\AssemblyInfo.cs" />
90+
<Compile Include="Reflector.cs" />
9091
<Compile Include="UnicodeHelper.cs" />
9192
<Compile Include="XunitExtensions\AssertionException.cs" />
9293
<Compile Include="XunitExtensions\RequireEnvironment.cs" />
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/* Copyright 2018-present MongoDB Inc.
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
using System.Linq;
17+
using System.Reflection;
18+
19+
namespace MongoDB.Bson.TestHelpers
20+
{
21+
public static class Reflector
22+
{
23+
public static object GetFieldValue(object obj, string name)
24+
{
25+
var fieldInfo = obj.GetType().GetField(name, BindingFlags.NonPublic | BindingFlags.Instance);
26+
return fieldInfo.GetValue(obj);
27+
}
28+
29+
public static object Invoke(object obj, string name)
30+
{
31+
var methodInfo = obj.GetType().GetMethods(BindingFlags.NonPublic | BindingFlags.Instance)
32+
.Where(m => m.Name == name && m.GetParameters().Length == 0)
33+
.Single();
34+
return methodInfo.Invoke(obj, new object[] { });
35+
}
36+
}
37+
}

tests/MongoDB.Driver.Core.Tests/Core/Bindings/ChannelSourceHandleTests.cs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
using System.Reflection;
1818
using System.Threading;
1919
using FluentAssertions;
20+
using MongoDB.Bson.TestHelpers;
2021
using MongoDB.Bson.TestHelpers.XunitExtensions;
2122
using MongoDB.Driver.Core.Bindings;
2223
using MongoDB.Driver.Core.Misc;
@@ -155,10 +156,8 @@ public void Disposing_of_last_handle_should_dispose_of_connectioSource()
155156

156157
internal static class ChannelSourceHandleReflector
157158
{
158-
public static ReferenceCounted<IChannelSource> _reference(this ChannelSourceHandle obj)
159-
{
160-
var fieldInfo = typeof(ChannelSourceHandle).GetField("_reference", BindingFlags.NonPublic | BindingFlags.Instance);
161-
return (ReferenceCounted<IChannelSource>)fieldInfo.GetValue(obj);
162-
}
159+
// private fields
160+
public static bool _disposed(this ChannelSourceHandle obj) => (bool)Reflector.GetFieldValue(obj, nameof(_disposed));
161+
public static ReferenceCounted<IChannelSource> _reference(this ChannelSourceHandle obj) => (ReferenceCounted<IChannelSource>)Reflector.GetFieldValue(obj, nameof(_reference));
163162
}
164163
}

0 commit comments

Comments
 (0)