Gábor Melis wrote: > Hello > > I'm writing a Common Lisp wrapper for LMDB, starting where the > previous efforts left off. I have a number of questions related to > safety and the color of the smoke after a disaster.
You should consider any misuses as you describe here as fatal, resulting in irreparably corrupted DBs. > > 1. lmdb.h says that "A parent transaction and its cursors may not > issue any other operations than mdb_txn_commit and mdb_txn_abort > while it has active child transactions." > > What I observe is that when a cursor associated with the parent > transaction is used in the child, there are no errors and the > cursor behaves (my test only involved mdb_cursor_put and > MDB_SET_KEY) as if it belonged to the child. > > Is this to be expected in general or my tests are insufficient and > something really bad can happen? If this is a disaster waiting to > happen, I need to add checks to the cursor code. Sounds like your test case was lucky. > > 2. mdb_txns are calloc()ed and free()d. In the case where a thread > performs some operation (e.g. put, get, del) involving an already > freed mdb_txn pointer, what kind of nastiness can happen? Can the > database be corrupted? The C standard says any references to freed memory result in undefined behavior. Nobody can give you a more specific answer than that. > > 3. Same question about mdb_cursors. > > 4. Async unwind safety. This is a bit like a thread being destroyed in > the middle of an lmdb function call. > > Context: In some Common Lisp implementations (SBCL), Posix > interrupts like SIGINT are used during development. If the > developer presses C-c the lisp debugger will start where the signal > handler was invoked, which may be in the middle of some mdb_* call. > Depending on the actions taken, the stack (both the lisp and the C > stack) may be unwound to some earlier frame. Another example is > async timeouts (SBCL's WITH-TIMEOUT) can also unwind the stack. I > understand that async unwinds are unsafe in general. > > There is a way to defer handling of interrupts, which I already use > to protect allocations (mdb_txn_begin, mdb_txn_commit and similar), > but it has a small performance cost and I hesitate to apply it to > performance hotspots (e.g. put, get, del and most cursor ops). Are > [some of] these functions safe in face of async unwinds? What kind > of problem may arise? In a default build, read txns are always safe. No guarantees on an interrupted write txn. > > Cheers, > Gábor Melis > -- -- Howard Chu CTO, Symas Corp. http://www.symas.com Director, Highland Sun http://highlandsun.com/hyc/ Chief Architect, OpenLDAP http://www.openldap.org/project/
