diff options
author | Chris Wilson <chris+github@qwirx.com> | 2015-04-13 17:59:30 +0000 |
---|---|---|
committer | Chris Wilson <chris+github@qwirx.com> | 2015-04-13 17:59:30 +0000 |
commit | 324243fa90e199012a81bf08b232a9d523ce1fbf (patch) | |
tree | 53672f78e6aa533d02d111a045bfd50de7af8c49 /lib/common/NamedLock.cpp | |
parent | f735627dd3e7c9ef6773afac671b7bf7ec4bf16c (diff) |
Fix file locking on Windows.
NamedLock simply didn't work before. This may cause test failures, but the
tests are already failing on Windows, and must be fixed.
Diffstat (limited to 'lib/common/NamedLock.cpp')
-rw-r--r-- | lib/common/NamedLock.cpp | 39 |
1 files changed, 35 insertions, 4 deletions
diff --git a/lib/common/NamedLock.cpp b/lib/common/NamedLock.cpp index 3c2c99dd..fadf4df3 100644 --- a/lib/common/NamedLock.cpp +++ b/lib/common/NamedLock.cpp @@ -73,6 +73,8 @@ bool NamedLock::TryAndGetLock(const std::string& rFilename, int mode) THROW_EXCEPTION(CommonException, NamedLockAlreadyLockingSomething) } + mFileName = rFilename; + // See if the lock can be got #if HAVE_DECL_O_EXLOCK int fd = ::open(rFilename.c_str(), @@ -94,11 +96,28 @@ bool NamedLock::TryAndGetLock(const std::string& rFilename, int mode) return false; #else - int fd = ::open(rFilename.c_str(), O_WRONLY | O_CREAT | O_TRUNC, mode); + int flags = O_WRONLY | O_CREAT | O_TRUNC; + +# if !HAVE_DECL_F_SETLK && !defined HAVE_FLOCK + // We have no other way to get a lock, so all we can do is fail if + // the file already exists, and take the risk of stale locks. + flags |= O_EXCL; +# endif + + int fd = ::open(rFilename.c_str(), flags, mode); if(fd == -1) { - THROW_SYS_FILE_ERROR("Failed to open lockfile", rFilename, - CommonException, OSFileError); + if(errno == EEXIST && (flags & O_EXCL)) + { + // Lockfile already exists, and we tried to open it + // exclusively, which means we failed to lock it. + return false; + } + else + { + THROW_SYS_FILE_ERROR("Failed to open lockfile", + rFilename, CommonException, OSFileError); + } } #ifdef HAVE_FLOCK @@ -162,8 +181,20 @@ void NamedLock::ReleaseLock() // Close the file if(::close(mFileDescriptor) != 0) { - THROW_EXCEPTION(CommonException, OSFileError) + THROW_EMU_ERROR( + BOX_FILE_MESSAGE(mFileName, "Failed to close lockfile"), + CommonException, OSFileError); } + + // Delete the file + if(::unlink(mFileName.c_str()) != 0) + { + THROW_EMU_ERROR( + BOX_FILE_MESSAGE(mFileName, + "Failed to delete lockfile"), + CommonException, OSFileError); + } + // Mark as unlocked mFileDescriptor = -1; } |