https://bugs.openldap.org/show_bug.cgi?id=10095
--- Comment #2 from Peter Zhu peter@peterzhu.ca --- Thank you for the quick reply. I considered doing the try to acquire write lock, acquire read lock, then try to acquire write lock approach. But I think there's still an issue if two or more processes (e.g. p1 and p2) attempt to connect to the database. The issue looks like the following:
p0: Opens connection to database using mdb_env_create and mdb_env_open.
...some things happen in between...
p0: Begins closing the database using mdb_env_close: p0: Calls mdb_env_close0: p0: Acquires write lock on the file lock using mdb_env_excl_lock. p0: Calls pthread_mutex_destroy on the mutexes.
SWITCH TO p1 and p2
p1, p2: Begins opening the database using mdb_env_create. Then calls mdb_env_open, in mdb_env_open: p1, p2: Calls mdb_env_setup_locks: p1, p2: Calls mdb_env_excl_lock, but it's unable to acquire a write file lock due to p0 holding the write file lock. It waits on acquiring a read file lock.
SWITCH TO p0
p0: Calls close on the file descriptor which releases the write file lock.
SWITCH TO p1, p2
p1, p2: Acquires the read file lock. p1, p2: Fails to acquire the write file lock due to both p1 and p2 holding a read file lock. p1, p2: Does NOT call pthread_mutex_init since it did not acquire a write file lock.
...some things happen in between...
p1, p2: Try to lock the mutex using pthread_mutex_lock. This call fails with a EINVAL due to locking a destroyed mutex.