diff --git a/MaxMind.Db.Test/ThreadingTest.cs b/MaxMind.Db.Test/ThreadingTest.cs index d72d121..66ddd32 100644 --- a/MaxMind.Db.Test/ThreadingTest.cs +++ b/MaxMind.Db.Test/ThreadingTest.cs @@ -12,9 +12,11 @@ namespace MaxMind.Db.Test public class ThreadingTest { [Test] - public void TestParallelFor() + [TestCase(FileAccessMode.MemoryMapped)] + [TestCase(FileAccessMode.Memory)] + public void TestParallelFor(FileAccessMode mode) { - var reader = new Reader(Path.Combine("..", "..", "TestData", "GeoLite2-City.mmdb"), FileAccessMode.MemoryMapped); + var reader = new Reader(Path.Combine("..", "..", "TestData", "GeoLite2-City.mmdb"), mode); var count = 0; var ipsAndResults = new Dictionary(); var rand = new Random(); @@ -45,12 +47,14 @@ public void TestParallelFor() } [Test] + [TestCase(FileAccessMode.MemoryMapped)] + [TestCase(FileAccessMode.Memory)] [Category("BreaksMono")] - public void TestManyOpens() + public void TestManyOpens(FileAccessMode mode) { Parallel.For(0, 1000, i => { - var reader = new Reader(Path.Combine("..", "..", "TestData", "GeoLite2-City.mmdb"), FileAccessMode.MemoryMapped); + var reader = new Reader(Path.Combine("..", "..", "TestData", "GeoLite2-City.mmdb"), mode); }); } } diff --git a/MaxMind.Db/Reader.cs b/MaxMind.Db/Reader.cs index 7a64394..b286a25 100644 --- a/MaxMind.Db/Reader.cs +++ b/MaxMind.Db/Reader.cs @@ -65,7 +65,7 @@ private int IPV4Start } } - private static readonly Object _mmapLocker = new Object(); + private static readonly Object _fileLocker = new Object(); private readonly ThreadLocal _stream; @@ -90,7 +90,7 @@ public Reader(string file, FileAccessMode mode) { var fileInfo = new FileInfo(file); var mmfName = fileInfo.FullName.Replace("\\", "-"); - lock (_mmapLocker) + lock (_fileLocker) { try { @@ -109,18 +109,23 @@ public Reader(string file, FileAccessMode mode) } } - _stream = new ThreadLocal(() => + if (mode == FileAccessMode.Memory) { - Stream s; - if (mode == FileAccessMode.Memory) s = new MemoryStream(File.ReadAllBytes(_fileName)); - else + byte[] fileBytes = File.ReadAllBytes(_fileName); + _stream = new ThreadLocal(() => + { + return new MemoryStream(fileBytes, false); + }); + } + else + { + _stream = new ThreadLocal(() => { - var fileLength = (int)new FileInfo(file).Length; - s = _memoryMappedFile.CreateViewStream(0, fileLength, MemoryMappedFileAccess.Read); - } - return s; - }); + var fileLength = (int)new FileInfo(file).Length; + return _memoryMappedFile.CreateViewStream(0, fileLength, MemoryMappedFileAccess.Read); + }); + } var start = FindMetadataStart(); var metaDecode = new Decoder(_stream, start);