clayton.stangeland@gmail.com wrote:
Full_Name: Clayton Stangeland Version: gitorious mdb last commit Feb 19, 2014 e2bdd44624a525d4847c22d7ebf1ea4d154ed734 OS: Windows 7 URL: ftp://ftp.openldap.org/incoming/ Submission from: (NULL) (192.94.73.31)
There is a bug in lightning mdb in mdb.c when running Windows. When creating an environment to the same file in multiple threads, an error can occur on the OpenMutex call and some of the creations will fail.
In mdb_env_setup_locks, mdb_env_excl_lock is called. If it acquires an exclusive lock CreateMutex is called. env->me_rmutex = CreateMutex(&mdb_all_sa, FALSE, env->me_txns->mti_rmname);
If not OpenMutex is called. env->me_rmutex = OpenMutex(SYNCHRONIZE, FALSE, env->me_txns->mti_rmname);
The OpenMutex call can fail if there is a thread context switch between the time the exclusive lock is acquired and the time CreateMutex is called, because the mutex to open has not actually been created yet. To be clear OpenMutex in another thread gets run before CreateMutex in the first thread.
The solution is to replace the OpenMutex calls with CreateMutex. It will either open the mutex if it exists or create it if it does not. Setting the bInitialOwner flag to FALSE as is already done is the recommended way to use CreateMutex in this situation.
There is already a note about multiple processes/threads opening the same environment at the same time. In short, don't do this.
Even if the code is changed as you describe, if such a race condition can occur, then it also means that the check for mti_magic != MDB_MAGIC can also fail, so the fix is ineffective.