Skip to content

Commit cf7652e

Browse files
authored
Merge pull request #866 from ElteHupkes/fix-insert-nre-761
Fix to #761, preventing returning a disposed command object
2 parents 20aa06f + 3826756 commit cf7652e

File tree

2 files changed

+32
-12
lines changed

2 files changed

+32
-12
lines changed

src/SQLite.cs

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1710,21 +1710,20 @@ PreparedSqlLiteInsertCommand GetInsertCommand (TableMapping map, string extra)
17101710
var key = Tuple.Create (map.MappedType.FullName, extra);
17111711

17121712
lock (_insertCommandMap) {
1713-
_insertCommandMap.TryGetValue (key, out prepCmd);
1713+
if (_insertCommandMap.TryGetValue (key, out prepCmd)) {
1714+
return prepCmd;
1715+
}
17141716
}
17151717

1716-
if (prepCmd == null) {
1717-
prepCmd = CreateInsertCommand (map, extra);
1718-
var added = false;
1719-
lock (_insertCommandMap) {
1720-
if (!_insertCommandMap.ContainsKey (key)) {
1721-
_insertCommandMap.Add (key, prepCmd);
1722-
added = true;
1723-
}
1724-
}
1725-
if (!added) {
1718+
prepCmd = CreateInsertCommand (map, extra);
1719+
1720+
lock (_insertCommandMap) {
1721+
if (_insertCommandMap.TryGetValue (key, out var existing)) {
17261722
prepCmd.Dispose ();
1723+
return existing;
17271724
}
1725+
1726+
_insertCommandMap.Add (key, prepCmd);
17281727
}
17291728

17301729
return prepCmd;

tests/ConcurrencyTest.cs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,28 @@ public void TestLoad()
187187
}
188188
}
189189

190-
190+
/// <summary>
191+
/// Test for issue #761. Because the nature of this test is a race condition,
192+
/// it is not guaranteed to fail if the issue is present. It does appear to
193+
/// fail most of the time, though.
194+
/// </summary>
195+
[Test]
196+
public void TestInsertCommandCreation ()
197+
{
198+
using (var dbConnection =
199+
new DbConnection (SQLiteOpenFlags.FullMutex | SQLiteOpenFlags.ReadWrite | SQLiteOpenFlags.Create)) {
200+
var obj1 = new TestObj ();
201+
var obj2 = new TestObj ();
202+
var taskA = Task.Run (() => {
203+
dbConnection.Insert (obj1);
204+
});
205+
var taskB = Task.Run (() => {
206+
dbConnection.Insert (obj2);
207+
});
208+
209+
Task.WhenAll (taskA, taskB).Wait ();
210+
}
211+
}
191212
}
192213
}
193214

0 commit comments

Comments
 (0)