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