Duh - the mdb_env_copy() FD should have FD_CLOEXEC, since the
point was the user can't get at it.  Fixed after an off-list
discussion.  OTOH MDB_env.me_fd should not: mdb_env_get_fd()
exposes it, so CLOEXEC would break existing programs.

Another issue is with fork() without exec().  This breaks LMDB:
   if (fork() == 0) pthread_exit(NULL);
because the child's me_txkey destructor releases the reader slot.

This can happen if a single-threaded LMDB process forks a multi-
threaded child, which is one way to deal with threads vs. fork().

pthread_atfork() is the official way to deal with that.  I'm a bit
wary of it since there is no way to unregister an atfork handler.
I wonder what happens if the LMDB module was dynamically loaded
and then gets unloaded.  A simpler way is in any case to check
if (reader->mr_pid == getpid()) in mdb_env_reader_dest().

I suppose there could be an mdb_env_fork_cleanup() function which
at least closes the FDs, and takes an arg to say whether to free
memory too (safe if parent was single-threaded).

Reply via email to