1dda28197Spatrick //===-- LockFileWindows.cpp -----------------------------------------------===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick
9061da546Spatrick #include "lldb/Host/windows/LockFileWindows.h"
10061da546Spatrick
11061da546Spatrick #include <io.h>
12061da546Spatrick
13061da546Spatrick using namespace lldb;
14061da546Spatrick using namespace lldb_private;
15061da546Spatrick
fileLock(HANDLE file_handle,DWORD flags,const uint64_t start,const uint64_t len)16*f6aab3d8Srobert static Status fileLock(HANDLE file_handle, DWORD flags, const uint64_t start,
17061da546Spatrick const uint64_t len) {
18061da546Spatrick if (start != 0)
19061da546Spatrick return Status("Non-zero start lock regions are not supported");
20061da546Spatrick
21061da546Spatrick OVERLAPPED overlapped = {};
22061da546Spatrick
23061da546Spatrick if (!::LockFileEx(file_handle, flags, 0, len, 0, &overlapped) &&
24061da546Spatrick ::GetLastError() != ERROR_IO_PENDING)
25061da546Spatrick return Status(::GetLastError(), eErrorTypeWin32);
26061da546Spatrick
27061da546Spatrick DWORD bytes;
28061da546Spatrick if (!::GetOverlappedResult(file_handle, &overlapped, &bytes, TRUE))
29061da546Spatrick return Status(::GetLastError(), eErrorTypeWin32);
30061da546Spatrick
31061da546Spatrick return Status();
32061da546Spatrick }
33061da546Spatrick
LockFileWindows(int fd)34061da546Spatrick LockFileWindows::LockFileWindows(int fd)
35061da546Spatrick : LockFileBase(fd), m_file(reinterpret_cast<HANDLE>(_get_osfhandle(fd))) {}
36061da546Spatrick
~LockFileWindows()37061da546Spatrick LockFileWindows::~LockFileWindows() { Unlock(); }
38061da546Spatrick
IsValidFile() const39061da546Spatrick bool LockFileWindows::IsValidFile() const {
40061da546Spatrick return LockFileBase::IsValidFile() && m_file != INVALID_HANDLE_VALUE;
41061da546Spatrick }
42061da546Spatrick
DoWriteLock(const uint64_t start,const uint64_t len)43061da546Spatrick Status LockFileWindows::DoWriteLock(const uint64_t start, const uint64_t len) {
44061da546Spatrick return fileLock(m_file, LOCKFILE_EXCLUSIVE_LOCK, start, len);
45061da546Spatrick }
46061da546Spatrick
DoTryWriteLock(const uint64_t start,const uint64_t len)47061da546Spatrick Status LockFileWindows::DoTryWriteLock(const uint64_t start,
48061da546Spatrick const uint64_t len) {
49061da546Spatrick return fileLock(m_file, LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY,
50061da546Spatrick start, len);
51061da546Spatrick }
52061da546Spatrick
DoReadLock(const uint64_t start,const uint64_t len)53061da546Spatrick Status LockFileWindows::DoReadLock(const uint64_t start, const uint64_t len) {
54061da546Spatrick return fileLock(m_file, 0, start, len);
55061da546Spatrick }
56061da546Spatrick
DoTryReadLock(const uint64_t start,const uint64_t len)57061da546Spatrick Status LockFileWindows::DoTryReadLock(const uint64_t start,
58061da546Spatrick const uint64_t len) {
59061da546Spatrick return fileLock(m_file, LOCKFILE_FAIL_IMMEDIATELY, start, len);
60061da546Spatrick }
61061da546Spatrick
DoUnlock()62061da546Spatrick Status LockFileWindows::DoUnlock() {
63061da546Spatrick OVERLAPPED overlapped = {};
64061da546Spatrick
65061da546Spatrick if (!::UnlockFileEx(m_file, 0, m_len, 0, &overlapped) &&
66061da546Spatrick ::GetLastError() != ERROR_IO_PENDING)
67061da546Spatrick return Status(::GetLastError(), eErrorTypeWin32);
68061da546Spatrick
69061da546Spatrick DWORD bytes;
70061da546Spatrick if (!::GetOverlappedResult(m_file, &overlapped, &bytes, TRUE))
71061da546Spatrick return Status(::GetLastError(), eErrorTypeWin32);
72061da546Spatrick
73061da546Spatrick return Status();
74061da546Spatrick }
75