180814287SRaphael Isemann //===-- LockFileWindows.cpp -----------------------------------------------===//
2919ef9dcSOleksiy Vyalov //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6919ef9dcSOleksiy Vyalov //
7919ef9dcSOleksiy Vyalov //===----------------------------------------------------------------------===//
8919ef9dcSOleksiy Vyalov 
9919ef9dcSOleksiy Vyalov #include "lldb/Host/windows/LockFileWindows.h"
10919ef9dcSOleksiy Vyalov 
11919ef9dcSOleksiy Vyalov #include <io.h>
12919ef9dcSOleksiy Vyalov 
13919ef9dcSOleksiy Vyalov using namespace lldb;
14919ef9dcSOleksiy Vyalov using namespace lldb_private;
15919ef9dcSOleksiy Vyalov 
fileLock(HANDLE file_handle,DWORD flags,const uint64_t start,const uint64_t len)16*93c1b3caSPavel Labath static Status fileLock(HANDLE file_handle, DWORD flags, const uint64_t start,
17b9c1b51eSKate Stone                        const uint64_t len) {
18919ef9dcSOleksiy Vyalov   if (start != 0)
1997206d57SZachary Turner     return Status("Non-zero start lock regions are not supported");
20919ef9dcSOleksiy Vyalov 
215a8ad459SZachary Turner   OVERLAPPED overlapped = {};
22919ef9dcSOleksiy Vyalov 
23b9c1b51eSKate Stone   if (!::LockFileEx(file_handle, flags, 0, len, 0, &overlapped) &&
24b9c1b51eSKate Stone       ::GetLastError() != ERROR_IO_PENDING)
2597206d57SZachary Turner     return Status(::GetLastError(), eErrorTypeWin32);
26919ef9dcSOleksiy Vyalov 
27919ef9dcSOleksiy Vyalov   DWORD bytes;
28919ef9dcSOleksiy Vyalov   if (!::GetOverlappedResult(file_handle, &overlapped, &bytes, TRUE))
2997206d57SZachary Turner     return Status(::GetLastError(), eErrorTypeWin32);
30919ef9dcSOleksiy Vyalov 
3197206d57SZachary Turner   return Status();
32919ef9dcSOleksiy Vyalov }
33919ef9dcSOleksiy Vyalov 
LockFileWindows(int fd)34919ef9dcSOleksiy Vyalov LockFileWindows::LockFileWindows(int fd)
35b9c1b51eSKate Stone     : LockFileBase(fd), m_file(reinterpret_cast<HANDLE>(_get_osfhandle(fd))) {}
36919ef9dcSOleksiy Vyalov 
~LockFileWindows()37b9c1b51eSKate Stone LockFileWindows::~LockFileWindows() { Unlock(); }
38919ef9dcSOleksiy Vyalov 
IsValidFile() const39b9c1b51eSKate Stone bool LockFileWindows::IsValidFile() const {
40919ef9dcSOleksiy Vyalov   return LockFileBase::IsValidFile() && m_file != INVALID_HANDLE_VALUE;
41919ef9dcSOleksiy Vyalov }
42919ef9dcSOleksiy Vyalov 
DoWriteLock(const uint64_t start,const uint64_t len)4397206d57SZachary Turner Status LockFileWindows::DoWriteLock(const uint64_t start, const uint64_t len) {
44919ef9dcSOleksiy Vyalov   return fileLock(m_file, LOCKFILE_EXCLUSIVE_LOCK, start, len);
45919ef9dcSOleksiy Vyalov }
46919ef9dcSOleksiy Vyalov 
DoTryWriteLock(const uint64_t start,const uint64_t len)4797206d57SZachary Turner Status LockFileWindows::DoTryWriteLock(const uint64_t start,
48b9c1b51eSKate Stone                                        const uint64_t len) {
49b9c1b51eSKate Stone   return fileLock(m_file, LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY,
50b9c1b51eSKate Stone                   start, len);
51919ef9dcSOleksiy Vyalov }
52919ef9dcSOleksiy Vyalov 
DoReadLock(const uint64_t start,const uint64_t len)5397206d57SZachary Turner Status LockFileWindows::DoReadLock(const uint64_t start, const uint64_t len) {
54919ef9dcSOleksiy Vyalov   return fileLock(m_file, 0, start, len);
55919ef9dcSOleksiy Vyalov }
56919ef9dcSOleksiy Vyalov 
DoTryReadLock(const uint64_t start,const uint64_t len)5797206d57SZachary Turner Status LockFileWindows::DoTryReadLock(const uint64_t start,
5897206d57SZachary Turner                                       const uint64_t len) {
59919ef9dcSOleksiy Vyalov   return fileLock(m_file, LOCKFILE_FAIL_IMMEDIATELY, start, len);
60919ef9dcSOleksiy Vyalov }
61919ef9dcSOleksiy Vyalov 
DoUnlock()6297206d57SZachary Turner Status LockFileWindows::DoUnlock() {
635a8ad459SZachary Turner   OVERLAPPED overlapped = {};
64919ef9dcSOleksiy Vyalov 
65b9c1b51eSKate Stone   if (!::UnlockFileEx(m_file, 0, m_len, 0, &overlapped) &&
66b9c1b51eSKate Stone       ::GetLastError() != ERROR_IO_PENDING)
6797206d57SZachary Turner     return Status(::GetLastError(), eErrorTypeWin32);
68919ef9dcSOleksiy Vyalov 
69919ef9dcSOleksiy Vyalov   DWORD bytes;
70919ef9dcSOleksiy Vyalov   if (!::GetOverlappedResult(m_file, &overlapped, &bytes, TRUE))
7197206d57SZachary Turner     return Status(::GetLastError(), eErrorTypeWin32);
72919ef9dcSOleksiy Vyalov 
7397206d57SZachary Turner   return Status();
74919ef9dcSOleksiy Vyalov }
75