Skip to content

Commit 7727d24

Browse files
committed
fix it so that disposing the RocksDb instance twice does not throw AccessViolationException and crash the process
1 parent 5b4b0bc commit 7727d24

File tree

2 files changed

+59
-4
lines changed

2 files changed

+59
-4
lines changed

RocksDbSharp/RocksDb.cs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ namespace RocksDbSharp
1010
{
1111
public class RocksDb : IDisposable
1212
{
13+
bool disposed;
14+
1315
internal static ReadOptions DefaultReadOptions { get; } = new ReadOptions();
1416
internal static OptionsHandle DefaultOptions { get; } = new DbOptions();
1517
internal static WriteOptions DefaultWriteOptions { get; } = new WriteOptions();
@@ -31,12 +33,21 @@ private RocksDb(IntPtr handle, dynamic optionsReferences, dynamic cfOptionsRefs,
3133

3234
public void Dispose()
3335
{
34-
if (columnFamilies != null)
36+
if (disposed) return;
37+
try
38+
{
39+
if (columnFamilies != null)
40+
{
41+
foreach (var cfh in columnFamilies.Values)
42+
cfh.Dispose();
43+
}
44+
45+
Native.Instance.rocksdb_close(Handle);
46+
}
47+
finally
3548
{
36-
foreach (var cfh in columnFamilies.Values)
37-
cfh.Dispose();
49+
disposed = true;
3850
}
39-
Native.Instance.rocksdb_close(Handle);
4051
}
4152

4253
public static RocksDb Open(OptionsHandle options, string path)
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
using System;
2+
using System.IO;
3+
using RocksDbSharp;
4+
using Xunit;
5+
// ReSharper disable RedundantArgumentDefaultValue
6+
// ReSharper disable ArgumentsStyleLiteral
7+
8+
namespace RocksDbSharpTest
9+
{
10+
public class LifestyleTest
11+
{
12+
[Fact]
13+
public void DoubleDisposableDoesNotThrow()
14+
{
15+
var testdir = Path.Combine(Path.GetTempPath(), "lifestyle_test");
16+
var testdb = Path.Combine(testdir, "main");
17+
var path = Environment.ExpandEnvironmentVariables(testdb);
18+
19+
if (Directory.Exists(testdir))
20+
{
21+
Directory.Delete(testdir, recursive: true);
22+
}
23+
24+
Directory.CreateDirectory(testdir);
25+
26+
var options = new DbOptions().SetCreateIfMissing(true).EnableStatistics();
27+
28+
var db = RocksDb.Open(options, path);
29+
30+
db.Dispose();
31+
32+
// throws AccessViolationException, which on my machine crashed the process so hard that XUnit coulnd't cope...
33+
//
34+
db.Dispose();
35+
//
36+
// got this in Event Viewer though:
37+
//
38+
// Application: dotnet.exe
39+
// CoreCLR Version: 4.6.28619.1
40+
// Description: The process was terminated due to an internal error in the .NET Runtime at IP 00007FFF39BC5AA3 (00007FFF39A20000) with exit code c0000005.
41+
//
42+
}
43+
}
44+
}

0 commit comments

Comments
 (0)