diff options
author | Ruslan Baratov <ruslan_baratov@yahoo.com> | 2014-11-25 22:49:25 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2014-12-03 14:47:44 (GMT) |
commit | e6db4c5a4ede8039ed525e3facebd7e0eb7ec1b7 (patch) | |
tree | f5e6a3dce7b89725f9fa4e5fcafd040114a85466 /Source/cmFileLockWin32.cxx | |
parent | 05d6531c7a8ecfad513a0e76b44b273b70fa919b (diff) | |
download | CMake-e6db4c5a4ede8039ed525e3facebd7e0eb7ec1b7.zip CMake-e6db4c5a4ede8039ed525e3facebd7e0eb7ec1b7.tar.gz CMake-e6db4c5a4ede8039ed525e3facebd7e0eb7ec1b7.tar.bz2 |
file: Add LOCK subcommand to do file and directory locking
Provide options to fail without blocking or to block up to a timeout.
Provide options to specify the scope containing the lock so it can be
released automatically at the end of a function, file, or process.
Extend the RunCMake.file test with cases covering the file(LOCK) command
usage and error cases.
Diffstat (limited to 'Source/cmFileLockWin32.cxx')
-rw-r--r-- | Source/cmFileLockWin32.cxx | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/Source/cmFileLockWin32.cxx b/Source/cmFileLockWin32.cxx new file mode 100644 index 0000000..17231ea --- /dev/null +++ b/Source/cmFileLockWin32.cxx @@ -0,0 +1,126 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2014 Ruslan Baratov + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#include "cmFileLock.h" + +#include <windows.h> // CreateFileW +#include "cmSystemTools.h" + +cmFileLock::cmFileLock(): File(INVALID_HANDLE_VALUE) +{ +} + +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 = ""; + + 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 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 + ); +} |