Skip to content

Commit 611907b

Browse files
feat: added more rigorous tracking of open file streams and shares/accesses
1 parent 2db45c1 commit 611907b

File tree

1 file changed

+10
-15
lines changed

1 file changed

+10
-15
lines changed

src/TestableIO.System.IO.Abstractions.TestingHelpers/MockFileStream.cs

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,13 @@ public NullFileSystemStream() : base(Null, ".", true)
3232

3333
private readonly IMockFileDataAccessor mockFileDataAccessor;
3434
private readonly string path;
35+
private readonly Guid guid = new();
3536
private readonly FileAccess access = FileAccess.ReadWrite;
3637
private readonly FileShare share = FileShare.Read;
3738
private readonly FileOptions options;
3839
private readonly MockFileData fileData;
3940
private bool disposed;
40-
private static ConcurrentDictionary<string, byte> _fileShareNoneStreams = [];
41+
private static ConcurrentDictionary<string, ConcurrentDictionary<Guid, (FileAccess access, FileShare share)>> _fileHandles = new();
4142

4243
/// <inheritdoc />
4344
public MockFileStream(
@@ -59,11 +60,6 @@ public MockFileStream(
5960
this.path = path;
6061
this.options = options;
6162

62-
if (_fileShareNoneStreams.ContainsKey(path))
63-
{
64-
throw CommonExceptions.ProcessCannotAccessFileInUse(path);
65-
}
66-
6763
if (mockFileDataAccessor.FileExists(path))
6864
{
6965
if (mode.Equals(FileMode.CreateNew))
@@ -107,13 +103,8 @@ public MockFileStream(
107103
mockFileDataAccessor.AddFile(path, fileData);
108104
}
109105

110-
if (share is FileShare.None)
111-
{
112-
if (!_fileShareNoneStreams.TryAdd(path, 0))
113-
{
114-
throw CommonExceptions.ProcessCannotAccessFileInUse(path);
115-
}
116-
}
106+
var fileHandlesEntry = _fileHandles.GetOrAdd(path, _ => new ConcurrentDictionary<Guid, (FileAccess access, FileShare share)>());
107+
fileHandlesEntry[guid] = (access, share);
117108
this.access = access;
118109
this.share = share;
119110
}
@@ -162,9 +153,13 @@ protected override void Dispose(bool disposing)
162153
{
163154
return;
164155
}
165-
if (share is FileShare.None)
156+
if (_fileHandles.TryGetValue(path, out var fileHandlesEntry))
166157
{
167-
_fileShareNoneStreams.TryRemove(path, out _);
158+
fileHandlesEntry.TryRemove(guid, out _);
159+
if (fileHandlesEntry.IsEmpty)
160+
{
161+
_fileHandles.TryRemove(path, out _);
162+
}
168163
}
169164
InternalFlush();
170165
base.Dispose(disposing);

0 commit comments

Comments
 (0)