Skip to content

Commit 1310d00

Browse files
committed
Only close cursor when it wasn't closed for us.
1 parent 74df69f commit 1310d00

File tree

4 files changed

+48
-5
lines changed

4 files changed

+48
-5
lines changed

src/LightningDB.Tests/CursorTests.cs

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,6 @@ public void CursorShouldPutValues()
6060
_env.RunCursorScenario((tx, _, c) =>
6161
{
6262
PopulateCursorValues(c);
63-
c.Dispose();
64-
//TODO evaluate how not to require this Dispose likely due to #155
6563
var result = tx.Commit();
6664
Assert.Equal(MDBResultCode.Success, result);
6765
});
@@ -362,4 +360,41 @@ public void ShouldDeleteDuplicates()
362360
Assert.Equal(MDBResultCode.NotFound, result);
363361
}, DatabaseOpenFlags.DuplicatesFixed | DatabaseOpenFlags.Create);
364362
}
363+
364+
[Fact]
365+
public void CanPutBatchesViaCursorIssue155()
366+
{
367+
static LightningDatabase OpenDatabase(LightningEnvironment environment)
368+
{
369+
using var tx = environment.BeginTransaction();
370+
var db = tx.OpenDatabase(configuration: new DatabaseConfiguration { Flags = DatabaseOpenFlags.Create });
371+
tx.Commit();
372+
return db;
373+
}
374+
375+
void ReproduceCoreIteration(LightningEnvironment environment, LightningDatabase db)
376+
{
377+
using var tx = environment.BeginTransaction(); //auto-disposed at end of scope
378+
using var cursor = tx.CreateCursor(db); //auto-disposed at end of scope
379+
380+
var guid = Guid.NewGuid().ToString();
381+
var guidBytes = UTF8.GetBytes(guid);
382+
383+
_ = cursor.Put(
384+
guidBytes,
385+
guidBytes,
386+
CursorPutOptions.None
387+
);
388+
389+
tx.Commit().ThrowOnError();
390+
}
391+
392+
using var db = OpenDatabase(_env);
393+
394+
for (var i = 0; i < 5000; i++)
395+
{
396+
ReproduceCoreIteration(_env, db);
397+
}
398+
Assert.True(true, "Code would be unreachable otherwise.");
399+
}
365400
}

src/LightningDB/LightningCursor.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ internal LightningCursor(LightningDatabase db, LightningTransaction txn)
2929
mdb_cursor_open(txn.Handle(), db.Handle(), out _handle).ThrowOnError();
3030

3131
Transaction = txn;
32+
Transaction.ShouldCloseCursor = true;
3233
Transaction.Disposing += Dispose;
3334
}
3435

@@ -503,14 +504,17 @@ public MDBResultCode Renew(LightningTransaction txn)
503504
/// <param name="disposing">True if called from Dispose.</param>
504505
private void Dispose(bool disposing)
505506
{
506-
if (_handle == 0)
507+
if (_handle == default)
507508
return;
508509

509510
if (!disposing)
510511
throw new InvalidOperationException("The LightningCursor was not disposed and cannot be reliably dealt with from the finalizer");
511512

512-
mdb_cursor_close(_handle);
513-
_handle = 0;
513+
if (Transaction.ShouldCloseCursor)
514+
{
515+
mdb_cursor_close(_handle);
516+
}
517+
_handle = default;
514518

515519
Transaction.Disposing -= Dispose;
516520

src/LightningDB/LightningDatabase.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ public Stats DatabaseStats
8686
public MDBResultCode Drop(LightningTransaction transaction)
8787
{
8888
var result = mdb_drop(transaction.Handle(), _handle, true);
89+
_transaction.ShouldCloseCursor = false;
8990
IsOpened = false;
9091
_handle = default;
9192
return result;

src/LightningDB/LightningTransaction.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ private void OnParentStateChanging(LightningTransactionState state)
5959

6060
public event Action Disposing;
6161
private event Action<LightningTransactionState> StateChanging;
62+
63+
internal bool ShouldCloseCursor { get; set; }
6264

6365
/// <summary>
6466
/// Current transaction state.
@@ -295,6 +297,7 @@ public MDBResultCode Renew()
295297
public MDBResultCode Commit()
296298
{
297299
State = LightningTransactionState.Committed;
300+
ShouldCloseCursor = false;
298301
StateChanging?.Invoke(State);
299302
return mdb_txn_commit(_handle);
300303
}

0 commit comments

Comments
 (0)