11c3bbb01SEd Maste //===-- LockFileBase.cpp ----------------------------------------*- C++ -*-===//
21c3bbb01SEd Maste //
31c3bbb01SEd Maste //                     The LLVM Compiler Infrastructure
41c3bbb01SEd Maste //
51c3bbb01SEd Maste // This file is distributed under the University of Illinois Open Source
61c3bbb01SEd Maste // License. See LICENSE.TXT for details.
71c3bbb01SEd Maste //
81c3bbb01SEd Maste //===----------------------------------------------------------------------===//
91c3bbb01SEd Maste 
101c3bbb01SEd Maste #include "lldb/Host/LockFileBase.h"
111c3bbb01SEd Maste 
121c3bbb01SEd Maste using namespace lldb;
131c3bbb01SEd Maste using namespace lldb_private;
141c3bbb01SEd Maste 
15435933ddSDimitry Andric namespace {
161c3bbb01SEd Maste 
AlreadyLocked()17*5517e702SDimitry Andric Status AlreadyLocked() { return Status("Already locked"); }
18435933ddSDimitry Andric 
NotLocked()19*5517e702SDimitry Andric Status NotLocked() { return Status("Not locked"); }
201c3bbb01SEd Maste }
211c3bbb01SEd Maste 
LockFileBase(int fd)22435933ddSDimitry Andric LockFileBase::LockFileBase(int fd)
23435933ddSDimitry Andric     : m_fd(fd), m_locked(false), m_start(0), m_len(0) {}
24435933ddSDimitry Andric 
IsLocked() const25435933ddSDimitry Andric bool LockFileBase::IsLocked() const { return m_locked; }
26435933ddSDimitry Andric 
WriteLock(const uint64_t start,const uint64_t len)27*5517e702SDimitry Andric Status LockFileBase::WriteLock(const uint64_t start, const uint64_t len) {
28435933ddSDimitry Andric   return DoLock([&](const uint64_t start,
29435933ddSDimitry Andric                     const uint64_t len) { return DoWriteLock(start, len); },
30435933ddSDimitry Andric                 start, len);
311c3bbb01SEd Maste }
321c3bbb01SEd Maste 
TryWriteLock(const uint64_t start,const uint64_t len)33*5517e702SDimitry Andric Status LockFileBase::TryWriteLock(const uint64_t start, const uint64_t len) {
34435933ddSDimitry Andric   return DoLock([&](const uint64_t start,
35435933ddSDimitry Andric                     const uint64_t len) { return DoTryWriteLock(start, len); },
36435933ddSDimitry Andric                 start, len);
371c3bbb01SEd Maste }
381c3bbb01SEd Maste 
ReadLock(const uint64_t start,const uint64_t len)39*5517e702SDimitry Andric Status LockFileBase::ReadLock(const uint64_t start, const uint64_t len) {
40435933ddSDimitry Andric   return DoLock([&](const uint64_t start,
41435933ddSDimitry Andric                     const uint64_t len) { return DoReadLock(start, len); },
42435933ddSDimitry Andric                 start, len);
431c3bbb01SEd Maste }
441c3bbb01SEd Maste 
TryReadLock(const uint64_t start,const uint64_t len)45*5517e702SDimitry Andric Status LockFileBase::TryReadLock(const uint64_t start, const uint64_t len) {
46435933ddSDimitry Andric   return DoLock([&](const uint64_t start,
47435933ddSDimitry Andric                     const uint64_t len) { return DoTryReadLock(start, len); },
48435933ddSDimitry Andric                 start, len);
491c3bbb01SEd Maste }
501c3bbb01SEd Maste 
Unlock()51*5517e702SDimitry Andric Status LockFileBase::Unlock() {
521c3bbb01SEd Maste   if (!IsLocked())
531c3bbb01SEd Maste     return NotLocked();
541c3bbb01SEd Maste 
551c3bbb01SEd Maste   const auto error = DoUnlock();
56435933ddSDimitry Andric   if (error.Success()) {
571c3bbb01SEd Maste     m_locked = false;
581c3bbb01SEd Maste     m_start = 0;
591c3bbb01SEd Maste     m_len = 0;
601c3bbb01SEd Maste   }
611c3bbb01SEd Maste   return error;
621c3bbb01SEd Maste }
631c3bbb01SEd Maste 
IsValidFile() const64435933ddSDimitry Andric bool LockFileBase::IsValidFile() const { return m_fd != -1; }
651c3bbb01SEd Maste 
DoLock(const Locker & locker,const uint64_t start,const uint64_t len)66*5517e702SDimitry Andric Status LockFileBase::DoLock(const Locker &locker, const uint64_t start,
67435933ddSDimitry Andric                             const uint64_t len) {
681c3bbb01SEd Maste   if (!IsValidFile())
69*5517e702SDimitry Andric     return Status("File is invalid");
701c3bbb01SEd Maste 
711c3bbb01SEd Maste   if (IsLocked())
721c3bbb01SEd Maste     return AlreadyLocked();
731c3bbb01SEd Maste 
741c3bbb01SEd Maste   const auto error = locker(start, len);
75435933ddSDimitry Andric   if (error.Success()) {
761c3bbb01SEd Maste     m_locked = true;
771c3bbb01SEd Maste     m_start = start;
781c3bbb01SEd Maste     m_len = len;
791c3bbb01SEd Maste   }
801c3bbb01SEd Maste 
811c3bbb01SEd Maste   return error;
821c3bbb01SEd Maste }
83