Skip to content

Add concurrent close-during-read regression tests (#279) - #294

Closed
bernardladenthin wants to merge 1 commit into
lmdbjava:gh-279-env-close-protectionfrom
bernardladenthin:test/gh-279-concurrent-close
Closed

Add concurrent close-during-read regression tests (#279)#294
bernardladenthin wants to merge 1 commit into
lmdbjava:gh-279-env-close-protectionfrom
bernardladenthin:test/gh-279-concurrent-close

Conversation

@bernardladenthin

Copy link
Copy Markdown

Targets your gh-279-env-close-protection branch (#293) — additive, tests only, no production changes.

While comparing our two approaches I noticed a coverage gap worth filling regardless of which implementation lands: nothing currently exercises Env.close() racing in-flight reads on other threads through the real Env/Txn/Cursor wiring. RefCounterTest stresses the counter thoroughly but against a mock Object env (no native LMDB), and the EnvTest safeClose tests (closeWithOpenReadTxn, etc.) are single-threaded. So a wiring regression — e.g. acquiring the ref counter after mdb_txn_begin instead of before — would leave every existing test green while reintroducing the mdb_txn_renew0 SIGSEGV from #253/#279.

This adds two tests to EnvTest, written to your fail-fast semantics:

  • closeDuringConcurrentReads_isRejectedWhileReadersLiveAndSurvives — 16 threads hammer txnRead()/Dbi.get while another races close().
  • closeDuringConcurrentCursorReads_isRejectedWhileCursorsLiveAndSurvives — same, with a Cursor per txn, covering the new cursor tracking.

Each holds one resource on the test thread so the EnvInUseException is deterministic, then asserts close() never unmaps while readers are live, readers only ever observe AlreadyClosedException, and the env closes cleanly once readers stop. On master these crash the JVM; on your branch they pass. Ported from my #289 stress test.

Note: I left RefCounterTest.java untouched even though it currently trips fmt:check on your branch (unrelated to this change) — didn't want to add noise here.

🤖 Generated with Claude Code

Cover the intermittent close-during-read SIGSEGV (lmdbjava#253/lmdbjava#279) end-to-end
against native LMDB with safe close enabled. The existing RefCounter tests
stress the counter in isolation (mock env) and the EnvTest safeClose tests
are single-threaded, so neither exercises Env.close() racing in-flight reads
on other threads through the real Env/Txn/Cursor wiring.

Two tests hammer txnRead()/Dbi.get (and a cursor variant) from many threads
while another thread races Env.close(); a resource held on the test thread
makes the fail-fast EnvInUseException deterministic, and the assertions prove
close() never unmaps while readers are live, readers only ever see
AlreadyClosedException, and the env closes cleanly once readers stop.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T9DLq5CoaZA9eB6fbgrW4d
@at055612

Copy link
Copy Markdown
Collaborator

Thanks @bernardladenthin. I have manually added your tests in to save dealing with the conflicts

@at055612 at055612 closed this Aug 10, 2026
@bernardladenthin
bernardladenthin deleted the test/gh-279-concurrent-close branch August 10, 2026 15:55
@bernardladenthin

Copy link
Copy Markdown
Author

@at055612 Ty! Perfect!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants