resolve cyclic dependency with zstd
[platform/upstream/cmake.git] / Source / cmFileLockWin32.cxx
1 /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2    file Copyright.txt or https://cmake.org/licensing for details.  */
3 #include <windows.h> // CreateFileW
4
5 #include "cmFileLock.h"
6 #include "cmSystemTools.h"
7
8 cmFileLock::cmFileLock()
9 {
10 }
11
12 cmFileLockResult cmFileLock::Release()
13 {
14   if (this->Filename.empty()) {
15     return cmFileLockResult::MakeOk();
16   }
17   const unsigned long len = static_cast<unsigned long>(-1);
18   static OVERLAPPED overlapped;
19   const DWORD reserved = 0;
20   const BOOL unlockResult =
21     UnlockFileEx(File, reserved, len, len, &overlapped);
22
23   this->Filename = "";
24
25   CloseHandle(this->File);
26   this->File = INVALID_HANDLE_VALUE;
27
28   if (unlockResult) {
29     return cmFileLockResult::MakeOk();
30   } else {
31     return cmFileLockResult::MakeSystem();
32   }
33 }
34
35 cmFileLockResult cmFileLock::OpenFile()
36 {
37   const DWORD access = GENERIC_READ | GENERIC_WRITE;
38   const DWORD shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
39   const PSECURITY_ATTRIBUTES security = NULL;
40   const DWORD attr = 0;
41   const HANDLE templ = NULL;
42   this->File = CreateFileW(
43     cmSystemTools::ConvertToWindowsExtendedPath(this->Filename).c_str(),
44     access, shareMode, security, OPEN_EXISTING, attr, templ);
45   if (this->File == INVALID_HANDLE_VALUE) {
46     return cmFileLockResult::MakeSystem();
47   } else {
48     return cmFileLockResult::MakeOk();
49   }
50 }
51
52 cmFileLockResult cmFileLock::LockWithoutTimeout()
53 {
54   if (!this->LockFile(LOCKFILE_EXCLUSIVE_LOCK)) {
55     return cmFileLockResult::MakeSystem();
56   } else {
57     return cmFileLockResult::MakeOk();
58   }
59 }
60
61 cmFileLockResult cmFileLock::LockWithTimeout(unsigned long seconds)
62 {
63   const DWORD flags = LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY;
64   while (true) {
65     const BOOL result = this->LockFile(flags);
66     if (result) {
67       return cmFileLockResult::MakeOk();
68     }
69     const DWORD error = GetLastError();
70     if (error != ERROR_LOCK_VIOLATION) {
71       return cmFileLockResult::MakeSystem();
72     }
73     if (seconds == 0) {
74       return cmFileLockResult::MakeTimeout();
75     }
76     --seconds;
77     cmSystemTools::Delay(1000);
78   }
79 }
80
81 BOOL cmFileLock::LockFile(DWORD flags)
82 {
83   const DWORD reserved = 0;
84   const unsigned long len = static_cast<unsigned long>(-1);
85   static OVERLAPPED overlapped;
86   return LockFileEx(this->File, flags, reserved, len, len, &overlapped);
87 }