https://bugs.openldap.org/show_bug.cgi?id=7853
--- Comment #5 from Howard Chu hyc@openldap.org --- (In reply to Howard Chu from comment #4)
(In reply to dw@hmmz.org from comment #0)
Full_Name: David Wilson Version: LMDB 0.9.11 OS: URL: https://raw.githubusercontent.com/dw/py-lmdb/master/misc/readers_mrb_env. patch Submission from: (NULL) (178.238.153.20)
Currently if a user (wilfully or accidentally, say, through composition of third party libs) opens the same LMDB environment twice within a process, and maintains active read transactions at the time one mdb_env_close() is called, all reader slots will be deallocated in all environments due to the logic around line 4253 that unconditionally clears reader slots based on PID.
I'd like to avoid this in py-lmdb, and seems there are a few alternatives to fix it:
- Modify lock.mdb to include MDB_env* address within the process, and update
mdb_env_close() to invalidate only readers associated with the environment being closed. I dislike using the MDB_env* as an opaque publicly visible cookie, but perhaps storing this field might be reused for other things in future.
I was looking at this approach, which initially seems harmless. But unfortunately it does nothing to address the fact the fcntl lock on the lock file will still go away on the first env_close() call. If there are no other processes with the env open, then the next process that opens the env will re-init the lock file, because it doesn't know about the existing process. At that point the existing process is hosed anyway.
Another possibility here is to detect that there were multiple envs for the same PID, and not close the descriptors in that case. This means intentionally leaking a file descriptor, but keeps the locks intact. Still ugly, but not as bad as inviting corruption. And, this would only happen due to a library misuse, so it would still be a rare situation.