diff options
Diffstat (limited to 'Source/cmFileLockWin32.cxx')
-rw-r--r-- | Source/cmFileLockWin32.cxx | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/Source/cmFileLockWin32.cxx b/Source/cmFileLockWin32.cxx new file mode 100644 index 0000000..a61d360 --- /dev/null +++ b/Source/cmFileLockWin32.cxx @@ -0,0 +1,87 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmFileLock.h" + +#include "cmSystemTools.h" +#include <windows.h> // CreateFileW + +cmFileLock::cmFileLock() +{ +} + +cmFileLockResult cmFileLock::Release() +{ + if (this->Filename.empty()) { + return cmFileLockResult::MakeOk(); + } + const unsigned long len = static_cast<unsigned long>(-1); + static OVERLAPPED overlapped; + const DWORD reserved = 0; + const BOOL unlockResult = + UnlockFileEx(File, reserved, len, len, &overlapped); + + this->Filename = ""; + + CloseHandle(this->File); + this->File = INVALID_HANDLE_VALUE; + + if (unlockResult) { + return cmFileLockResult::MakeOk(); + } else { + return cmFileLockResult::MakeSystem(); + } +} + +cmFileLockResult cmFileLock::OpenFile() +{ + const DWORD access = GENERIC_READ | GENERIC_WRITE; + const DWORD shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; + const PSECURITY_ATTRIBUTES security = NULL; + const DWORD attr = 0; + const HANDLE templ = NULL; + this->File = CreateFileW( + cmSystemTools::ConvertToWindowsExtendedPath(this->Filename).c_str(), + access, shareMode, security, OPEN_EXISTING, attr, templ); + if (this->File == INVALID_HANDLE_VALUE) { + return cmFileLockResult::MakeSystem(); + } else { + return cmFileLockResult::MakeOk(); + } +} + +cmFileLockResult cmFileLock::LockWithoutTimeout() +{ + if (!this->LockFile(LOCKFILE_EXCLUSIVE_LOCK)) { + return cmFileLockResult::MakeSystem(); + } else { + return cmFileLockResult::MakeOk(); + } +} + +cmFileLockResult cmFileLock::LockWithTimeout(unsigned long seconds) +{ + const DWORD flags = LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY; + while (true) { + const BOOL result = this->LockFile(flags); + if (result) { + return cmFileLockResult::MakeOk(); + } + const DWORD error = GetLastError(); + if (error != ERROR_LOCK_VIOLATION) { + return cmFileLockResult::MakeSystem(); + } + if (seconds == 0) { + return cmFileLockResult::MakeTimeout(); + } + --seconds; + cmSystemTools::Delay(1000); + } +} + +BOOL cmFileLock::LockFile(DWORD flags) +{ + const DWORD reserved = 0; + const unsigned long len = static_cast<unsigned long>(-1); + static OVERLAPPED overlapped; + return LockFileEx(this->File, flags, reserved, len, len, &overlapped); +} |