Skip to content

Commit

Permalink
Fix a strange race condition with interop delegates
Browse files Browse the repository at this point in the history
  • Loading branch information
halgari committed May 6, 2024
1 parent a125cde commit 4d02eaa
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 10 deletions.
11 changes: 1 addition & 10 deletions src/NexusMods.MnemonicDB.Storage/DatomStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -136,16 +136,7 @@ public async Task<StoreResult> Transact(IndexSegment datoms, HashSet<ITxFunction
/// <inheritdoc />
public async Task<StoreResult> Sync()
{
var pending = new PendingTransaction
{
Data = new IndexSegment(),
TxFunctions = null,
DatabaseFactory = null
};
if (!_txChannel.Writer.TryWrite(pending))
throw new InvalidOperationException("Failed to write to the transaction channel");

return await pending.CompletionSource.Task;
return await Transact(new IndexSegment());
}

public IObservable<(TxId TxId, ISnapshot Snapshot)> TxLog => _updatesSubject;
Expand Down
14 changes: 14 additions & 0 deletions src/NexusMods.MnemonicDB.Storage/RocksDbBackend/IndexStore.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using DynamicData;
using NexusMods.MnemonicDB.Abstractions;
using NexusMods.MnemonicDB.Abstractions.DatomComparators;
using NexusMods.MnemonicDB.Abstractions.DatomIterators;
Expand All @@ -21,6 +23,15 @@ public class IndexStore<TComparator> : IRocksDBIndexStore
private IntPtr _namePtr;
private ColumnFamilyOptions _options = null!;

/// <summary>
/// This is a bit of a hack, but we throw all our interop delegates in here, and then they
/// live for the entire life of the application. It seems that RocksDB will occasionally call
/// delegates after we think we've disposed of the handles. It really doesn't matter as these
/// things will never amount to more than a few dozen objects.
/// </summary>
/// <returns></returns>
private static List<object> _roots = new ();

public IndexStore(string handleName, IndexType type, AttributeRegistry registry)
{
Type = type;
Expand All @@ -47,6 +58,9 @@ public void SetupColumnFamily(IIndex index, ColumnFamilies columnFamilies)
}
};

// Save these as roots so they never get GC'd
_roots.Add((_nameDelegate, _destructorDelegate, _comparatorDelegate));

_comparator =
Native.Instance.rocksdb_comparator_create(IntPtr.Zero, _destructorDelegate, _comparatorDelegate,
_nameDelegate);
Expand Down

0 comments on commit 4d02eaa

Please sign in to comment.