https://bugs.openldap.org/show_bug.cgi?id=9486
--- Comment #5 from igfoo@github.com --- Thanks for the suggestion! I'll think about whether we can make something like that work for us.
But wouldn't another option be to wrap all calls to mdb_env_open and mdb_env_close with a lock/unlock function, like below?
And if that works, then couldn't mdb_env_open/mdb_env_close do it themselves, if I added | MDB_SAFE_PARALLEL_OPEN_CLOSE to the flags?
(a real solution would need better error handling, and perhaps a different locking mechanism on different platforms, but this should give the idea)
int fd = lock(); e = mdb_env_open(env, db_file, MDB_NOSUBDIR | MDB_NOSYNC, 0644); unlock(fd); [...] fd = lock(); mdb_env_close(env); unlock(fd);
int lock(void) { int r; int fd = open("test.env-lock", O_WRONLY | O_CREAT, 0666); if(fd == -1) { printf("%s: lock failed to open file: %d.\n", me, errno); exit(1); } struct flock lock_info; memset((void *)&lock_info, 0, sizeof(lock_info)); lock_info.l_type = F_WRLCK; lock_info.l_whence = SEEK_SET; lock_info.l_start = 0; lock_info.l_len = 1; while((r = fcntl(fd, F_SETLKW, &lock_info)) && errno == EINTR) ; if(r) { printf("%s: lock failed to lock file: %d.\n", me, errno); exit(1); } return fd; }
void unlock(int fd) { int r; struct flock lock_info; memset((void *)&lock_info, 0, sizeof(lock_info)); lock_info.l_type = F_WRLCK; lock_info.l_whence = SEEK_SET; lock_info.l_start = 0; lock_info.l_len = 1; while((r = fcntl(fd, F_UNLCK, &lock_info)) && errno == EINTR) ; if(r) { printf("%s: unlock failed to unlock file: %d.\n", me, errno); exit(1); } r = close(fd); if(r == -1) { printf("%s: unlock failed to close file: %d.\n", me, errno); exit(1); } }