1 //===-- LockFileWindows.cpp -------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "lldb/Host/windows/LockFileWindows.h"
11 
12 #include <io.h>
13 
14 using namespace lldb;
15 using namespace lldb_private;
16 
17 namespace {
18 
19 Error fileLock(HANDLE file_handle, DWORD flags, const uint64_t start,
20                const uint64_t len) {
21   if (start != 0)
22     return Error("Non-zero start lock regions are not supported");
23 
24   OVERLAPPED overlapped = {};
25 
26   if (!::LockFileEx(file_handle, flags, 0, len, 0, &overlapped) &&
27       ::GetLastError() != ERROR_IO_PENDING)
28     return Error(::GetLastError(), eErrorTypeWin32);
29 
30   DWORD bytes;
31   if (!::GetOverlappedResult(file_handle, &overlapped, &bytes, TRUE))
32     return Error(::GetLastError(), eErrorTypeWin32);
33 
34   return Error();
35 }
36 
37 } // namespace
38 
39 LockFileWindows::LockFileWindows(int fd)
40     : LockFileBase(fd), m_file(reinterpret_cast<HANDLE>(_get_osfhandle(fd))) {}
41 
42 LockFileWindows::~LockFileWindows() { Unlock(); }
43 
44 bool LockFileWindows::IsValidFile() const {
45   return LockFileBase::IsValidFile() && m_file != INVALID_HANDLE_VALUE;
46 }
47 
48 Error LockFileWindows::DoWriteLock(const uint64_t start, const uint64_t len) {
49   return fileLock(m_file, LOCKFILE_EXCLUSIVE_LOCK, start, len);
50 }
51 
52 Error LockFileWindows::DoTryWriteLock(const uint64_t start,
53                                       const uint64_t len) {
54   return fileLock(m_file, LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY,
55                   start, len);
56 }
57 
58 Error LockFileWindows::DoReadLock(const uint64_t start, const uint64_t len) {
59   return fileLock(m_file, 0, start, len);
60 }
61 
62 Error LockFileWindows::DoTryReadLock(const uint64_t start, const uint64_t len) {
63   return fileLock(m_file, LOCKFILE_FAIL_IMMEDIATELY, start, len);
64 }
65 
66 Error LockFileWindows::DoUnlock() {
67   OVERLAPPED overlapped = {};
68 
69   if (!::UnlockFileEx(m_file, 0, m_len, 0, &overlapped) &&
70       ::GetLastError() != ERROR_IO_PENDING)
71     return Error(::GetLastError(), eErrorTypeWin32);
72 
73   DWORD bytes;
74   if (!::GetOverlappedResult(m_file, &overlapped, &bytes, TRUE))
75     return Error(::GetLastError(), eErrorTypeWin32);
76 
77   return Error();
78 }
79