[Lldb-commits] [lldb] r236736 - Use file locks to synchronize access to ModuleCache.

Oleksiy Vyalov ovyalov at google.com
Thu May 7 08:28:49 PDT 2015


Author: ovyalov
Date: Thu May  7 10:28:49 2015
New Revision: 236736

URL: http://llvm.org/viewvc/llvm-project?rev=236736&view=rev
Log:
Use file locks to synchronize access to ModuleCache.

http://reviews.llvm.org/D9056

Added:
    lldb/trunk/include/lldb/Host/LockFile.h
    lldb/trunk/include/lldb/Host/LockFileBase.h
    lldb/trunk/include/lldb/Host/posix/LockFilePosix.h
    lldb/trunk/include/lldb/Host/windows/LockFileWindows.h
    lldb/trunk/source/Host/common/LockFileBase.cpp
    lldb/trunk/source/Host/posix/LockFilePosix.cpp
    lldb/trunk/source/Host/windows/LockFileWindows.cpp
Modified:
    lldb/trunk/lldb.xcodeproj/project.pbxproj
    lldb/trunk/source/Host/CMakeLists.txt
    lldb/trunk/source/Target/Platform.cpp
    lldb/trunk/source/Utility/ModuleCache.cpp
    lldb/trunk/source/Utility/ModuleCache.h

Added: lldb/trunk/include/lldb/Host/LockFile.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/LockFile.h?rev=236736&view=auto
==============================================================================
--- lldb/trunk/include/lldb/Host/LockFile.h (added)
+++ lldb/trunk/include/lldb/Host/LockFile.h Thu May  7 10:28:49 2015
@@ -0,0 +1,27 @@
+//===-- LockFile.h ----------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Host_LockFile_h_
+#define liblldb_Host_LockFile_h_
+
+#if defined(_WIN32)
+#include "lldb/Host/windows/LockFileWindows.h"
+namespace lldb_private
+{
+typedef LockFileWindows LockFile;
+}
+#else
+#include "lldb/Host/posix/LockFilePosix.h"
+namespace lldb_private
+{
+typedef LockFilePosix LockFile;
+}
+#endif
+
+#endif // liblldb_Host_LockFile_h_

Added: lldb/trunk/include/lldb/Host/LockFileBase.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/LockFileBase.h?rev=236736&view=auto
==============================================================================
--- lldb/trunk/include/lldb/Host/LockFileBase.h (added)
+++ lldb/trunk/include/lldb/Host/LockFileBase.h Thu May  7 10:28:49 2015
@@ -0,0 +1,73 @@
+//===-- LockFileBase.h ------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Host_LockFileBase_h_
+#define liblldb_Host_LockFileBase_h_
+
+#include "lldb/Core/Error.h"
+
+#include <functional>
+
+namespace lldb_private
+{
+
+class LockFileBase
+{
+public:
+    virtual ~LockFileBase () = default;
+
+    bool
+    IsLocked () const;
+
+    Error
+    WriteLock (const uint64_t start, const uint64_t len);
+    Error
+    TryWriteLock (const uint64_t start, const uint64_t len);
+
+    Error
+    ReadLock (const uint64_t start, const uint64_t len);
+    Error
+    TryReadLock (const uint64_t start, const uint64_t len);
+
+    Error
+    Unlock ();
+
+protected:
+    using Locker = std::function<Error (const uint64_t, const uint64_t)>;
+
+    LockFileBase (int fd);
+
+    virtual bool
+    IsValidFile () const;
+
+    virtual Error
+    DoWriteLock (const uint64_t start, const uint64_t len) = 0;
+    virtual Error
+    DoTryWriteLock (const uint64_t start, const uint64_t len) = 0;
+
+    virtual Error
+    DoReadLock (const uint64_t start, const uint64_t len) = 0;
+    virtual Error
+    DoTryReadLock (const uint64_t start, const uint64_t len) = 0;
+
+    virtual Error
+    DoUnlock () = 0;
+
+    Error
+    DoLock (const Locker &locker, const uint64_t start, const uint64_t len);
+
+    int m_fd;  // not owned.
+    bool m_locked;
+    uint64_t m_start;
+    uint64_t m_len;
+};
+
+}
+
+#endif

Added: lldb/trunk/include/lldb/Host/posix/LockFilePosix.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/posix/LockFilePosix.h?rev=236736&view=auto
==============================================================================
--- lldb/trunk/include/lldb/Host/posix/LockFilePosix.h (added)
+++ lldb/trunk/include/lldb/Host/posix/LockFilePosix.h Thu May  7 10:28:49 2015
@@ -0,0 +1,42 @@
+//===-- LockFilePosix.h -----------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Host_posix_LockFilePosix_h_
+#define liblldb_Host_posix_LockFilePosix_h_
+
+#include "lldb/Host/LockFileBase.h"
+
+namespace lldb_private {
+
+class LockFilePosix : public LockFileBase
+{
+public:
+    explicit LockFilePosix (int fd);
+    ~LockFilePosix ();
+
+protected:
+    Error
+    DoWriteLock (const uint64_t start, const uint64_t len) override;
+
+    Error
+    DoTryWriteLock (const uint64_t start, const uint64_t len) override;
+
+    Error
+    DoReadLock (const uint64_t start, const uint64_t len) override;
+
+    Error
+    DoTryReadLock (const uint64_t start, const uint64_t len) override;
+
+    Error
+    DoUnlock () override;
+};
+
+}  // namespace lldb_private
+
+#endif  // liblldb_Host_posix_LockFilePosix_h_

Added: lldb/trunk/include/lldb/Host/windows/LockFileWindows.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/windows/LockFileWindows.h?rev=236736&view=auto
==============================================================================
--- lldb/trunk/include/lldb/Host/windows/LockFileWindows.h (added)
+++ lldb/trunk/include/lldb/Host/windows/LockFileWindows.h Thu May  7 10:28:49 2015
@@ -0,0 +1,49 @@
+//===-- LockFileWindows.h ---------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Host_posix_LockFileWindows_h_
+#define liblldb_Host_posix_LockFileWindows_h_
+
+#include "lldb/Host/LockFileBase.h"
+#include "lldb/Host/windows/windows.h"
+
+namespace lldb_private {
+
+class LockFileWindows : public LockFileBase
+{
+public:
+    explicit LockFileWindows (int fd);
+    ~LockFileWindows ();
+
+protected:
+    Error
+    DoWriteLock (const uint64_t start, const uint64_t len) override;
+
+    Error
+    DoTryWriteLock (const uint64_t start, const uint64_t len) override;
+
+    Error
+    DoReadLock (const uint64_t start, const uint64_t len) override;
+
+    Error
+    DoTryReadLock (const uint64_t start, const uint64_t len) override;
+
+    Error
+    DoUnlock () override;
+
+    bool
+    IsValidFile () const override;
+
+private:
+    HANDLE m_file;
+};
+
+}  // namespace lldb_private
+
+#endif  // liblldb_Host_posix_LockFileWindows_h_

Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=236736&r1=236735&r2=236736&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Thu May  7 10:28:49 2015
@@ -97,6 +97,8 @@
 		254FBB971A81B03100BD6378 /* SBLaunchInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 254FBB961A81B03100BD6378 /* SBLaunchInfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		254FBBA31A9166F100BD6378 /* SBAttachInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 254FBBA21A9166F100BD6378 /* SBAttachInfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		254FBBA51A91670E00BD6378 /* SBAttachInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 254FBBA41A91670E00BD6378 /* SBAttachInfo.cpp */; };
+		255EFF741AFABA720069F277 /* LockFileBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 255EFF731AFABA720069F277 /* LockFileBase.cpp */; };
+		255EFF761AFABA950069F277 /* LockFilePosix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 255EFF751AFABA950069F277 /* LockFilePosix.cpp */; };
 		256CBDB11ADD0E1700BC6CDC /* NativeRegisterContextLinux_arm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 256CBDAB1ADD0DB600BC6CDC /* NativeRegisterContextLinux_arm.cpp */; };
 		256CBDB41ADD0EFD00BC6CDC /* RegisterContextPOSIXCore_arm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 256CBDB21ADD0EFD00BC6CDC /* RegisterContextPOSIXCore_arm.cpp */; };
 		256CBDB51ADD0EFD00BC6CDC /* RegisterContextPOSIXCore_arm.h in Headers */ = {isa = PBXBuildFile; fileRef = 256CBDB31ADD0EFD00BC6CDC /* RegisterContextPOSIXCore_arm.h */; };
@@ -1250,6 +1252,11 @@
 		254FBBA21A9166F100BD6378 /* SBAttachInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBAttachInfo.h; path = include/lldb/API/SBAttachInfo.h; sourceTree = "<group>"; };
 		254FBBA41A91670E00BD6378 /* SBAttachInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBAttachInfo.cpp; path = source/API/SBAttachInfo.cpp; sourceTree = "<group>"; };
 		254FBBA61A91672800BD6378 /* SBAttachInfo.i */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c.preprocessed; path = SBAttachInfo.i; sourceTree = "<group>"; };
+		255EFF6F1AFABA320069F277 /* LockFileWindows.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = LockFileWindows.h; path = include/lldb/Host/windows/LockFileWindows.h; sourceTree = "<group>"; };
+		255EFF701AFABA320069F277 /* PipeWindows.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PipeWindows.h; path = include/lldb/Host/windows/PipeWindows.h; sourceTree = "<group>"; };
+		255EFF711AFABA4D0069F277 /* LockFileWindows.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LockFileWindows.cpp; path = source/Host/windows/LockFileWindows.cpp; sourceTree = "<group>"; };
+		255EFF731AFABA720069F277 /* LockFileBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LockFileBase.cpp; sourceTree = "<group>"; };
+		255EFF751AFABA950069F277 /* LockFilePosix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LockFilePosix.cpp; sourceTree = "<group>"; };
 		256CBDAB1ADD0DB600BC6CDC /* NativeRegisterContextLinux_arm.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = NativeRegisterContextLinux_arm.cpp; sourceTree = "<group>"; };
 		256CBDAC1ADD0DB600BC6CDC /* NativeRegisterContextLinux_arm.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NativeRegisterContextLinux_arm.h; sourceTree = "<group>"; };
 		256CBDAD1ADD0DB600BC6CDC /* NativeRegisterContextLinux_arm64.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = NativeRegisterContextLinux_arm64.cpp; sourceTree = "<group>"; };
@@ -4876,6 +4883,7 @@
 		3FDFDDC4199D37BE009756A7 /* posix */ = {
 			isa = PBXGroup;
 			children = (
+				255EFF751AFABA950069F277 /* LockFilePosix.cpp */,
 				AFDFDFD019E34D3400EAE509 /* ConnectionFileDescriptorPosix.cpp */,
 				3FDFDDC5199D37ED009756A7 /* FileSystem.cpp */,
 				3FDFE53019A292F0009756A7 /* HostInfoPosix.cpp */,
@@ -4906,6 +4914,9 @@
 		3FDFE53E19A2940E009756A7 /* windows */ = {
 			isa = PBXGroup;
 			children = (
+				255EFF711AFABA4D0069F277 /* LockFileWindows.cpp */,
+				255EFF6F1AFABA320069F277 /* LockFileWindows.h */,
+				255EFF701AFABA320069F277 /* PipeWindows.h */,
 				3FDFE54719A2946B009756A7 /* AutoHandle.h */,
 				3FDFE53F19A29448009756A7 /* Condition.cpp */,
 				3FDFE54819A2946B009756A7 /* editlinewin.h */,
@@ -5034,6 +5045,7 @@
 		69A01E1A1236C5D400C660B5 /* common */ = {
 			isa = PBXGroup;
 			children = (
+				255EFF731AFABA720069F277 /* LockFileBase.cpp */,
 				250D6AE11A9679270049CC70 /* FileSystem.cpp */,
 				33E5E8411A672A240024ED68 /* StringConvert.cpp */,
 				25420ED11A649D88009ADBCB /* PipeBase.cpp */,
@@ -6009,6 +6021,7 @@
 				2689FFFF13353DB600698AC0 /* BreakpointResolver.cpp in Sources */,
 				25420ECD1A6490B8009ADBCB /* OptionValueChar.cpp in Sources */,
 				2689000113353DB600698AC0 /* BreakpointResolverAddress.cpp in Sources */,
+				255EFF741AFABA720069F277 /* LockFileBase.cpp in Sources */,
 				2689000313353DB600698AC0 /* BreakpointResolverFileLine.cpp in Sources */,
 				AF20F76D1AF18FC700751A6E /* SBLanguageRuntime.cpp in Sources */,
 				26474CA818D0CB070073DEBA /* RegisterContextFreeBSD_i386.cpp in Sources */,
@@ -6435,6 +6448,7 @@
 				94EA27CE17DE91750070F505 /* LibCxxUnorderedMap.cpp in Sources */,
 				266DFE9713FD656E00D0C574 /* OperatingSystem.cpp in Sources */,
 				26954EBE1401EE8B00294D09 /* DynamicRegisterInfo.cpp in Sources */,
+				255EFF761AFABA950069F277 /* LockFilePosix.cpp in Sources */,
 				26274FA714030F79006BA130 /* DynamicLoaderDarwinKernel.cpp in Sources */,
 				94FA3DE01405D50400833217 /* ValueObjectConstResultChild.cpp in Sources */,
 				3FDFED2819BA6D96009756A7 /* HostThread.cpp in Sources */,

Modified: lldb/trunk/source/Host/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/CMakeLists.txt?rev=236736&r1=236735&r2=236736&view=diff
==============================================================================
--- lldb/trunk/source/Host/CMakeLists.txt (original)
+++ lldb/trunk/source/Host/CMakeLists.txt Thu May  7 10:28:49 2015
@@ -15,6 +15,7 @@ add_host_subdirectory(common
   common/HostProcess.cpp
   common/HostThread.cpp
   common/IOObject.cpp
+  common/LockFileBase.cpp
   common/Mutex.cpp
   common/MonitoringProcessLauncher.cpp
   common/NativeBreakpoint.cpp
@@ -58,6 +59,7 @@ if (CMAKE_SYSTEM_NAME MATCHES "Windows")
     windows/HostInfoWindows.cpp
     windows/HostProcessWindows.cpp
     windows/HostThreadWindows.cpp
+    windows/LockFileWindows.cpp
     windows/Mutex.cpp
     windows/PipeWindows.cpp
     windows/ProcessLauncherWindows.cpp
@@ -72,6 +74,7 @@ else()
     posix/HostInfoPosix.cpp
     posix/HostProcessPosix.cpp
     posix/HostThreadPosix.cpp
+    posix/LockFilePosix.cpp
     posix/PipePosix.cpp
     )
 

Added: lldb/trunk/source/Host/common/LockFileBase.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/LockFileBase.cpp?rev=236736&view=auto
==============================================================================
--- lldb/trunk/source/Host/common/LockFileBase.cpp (added)
+++ lldb/trunk/source/Host/common/LockFileBase.cpp Thu May  7 10:28:49 2015
@@ -0,0 +1,124 @@
+//===-- LockFileBase.cpp ----------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Host/LockFileBase.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+namespace
+{
+
+Error
+AlreadyLocked ()
+{
+    return Error ("Already locked");
+}
+
+Error
+NotLocked ()
+{
+    return Error ("Not locked");
+}
+
+}
+
+LockFileBase::LockFileBase (int fd) :
+    m_fd (fd),
+    m_locked (false),
+    m_start (0),
+    m_len (0)
+{
+
+}
+
+bool
+LockFileBase::IsLocked () const
+{
+    return m_locked;
+}
+
+Error
+LockFileBase::WriteLock (const uint64_t start, const uint64_t len)
+{
+    return DoLock ([&] (const uint64_t start, const uint64_t len)
+                   {
+                       return DoWriteLock (start, len);
+                   }, start, len);
+}
+
+Error
+LockFileBase::TryWriteLock (const uint64_t start, const uint64_t len)
+{
+    return DoLock ([&] (const uint64_t start, const uint64_t len)
+                   {
+                        return DoTryWriteLock (start, len);
+                   }, start, len);
+}
+
+Error
+LockFileBase::ReadLock (const uint64_t start, const uint64_t len)
+{
+    return DoLock ([&] (const uint64_t start, const uint64_t len)
+                   {
+                        return DoReadLock (start, len);
+                   }, start, len);
+}
+
+Error
+LockFileBase::TryReadLock (const uint64_t start, const uint64_t len)
+{
+    return DoLock ([&] (const uint64_t start, const uint64_t len)
+                   {
+                       return DoTryReadLock (start, len);
+                   }, start, len);
+
+}
+
+Error
+LockFileBase::Unlock ()
+{
+    if (!IsLocked ())
+        return NotLocked ();
+
+    const auto error = DoUnlock ();
+    if (error.Success ())
+    {
+        m_locked = false;
+        m_start = 0;
+        m_len = 0;
+    }
+    return error;
+}
+
+bool
+LockFileBase::IsValidFile () const
+{
+    return m_fd != -1;
+}
+
+Error
+LockFileBase::DoLock (const Locker &locker, const uint64_t start, const uint64_t len)
+{
+    if (!IsValidFile ())
+        return Error("File is invalid");
+
+    if (IsLocked ())
+        return AlreadyLocked ();
+
+    const auto error = locker (start, len);
+    if (error.Success ())
+    {
+        m_locked = true;
+        m_start = start;
+        m_len = len;
+    }
+
+    return error;
+}

Added: lldb/trunk/source/Host/posix/LockFilePosix.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/posix/LockFilePosix.cpp?rev=236736&view=auto
==============================================================================
--- lldb/trunk/source/Host/posix/LockFilePosix.cpp (added)
+++ lldb/trunk/source/Host/posix/LockFilePosix.cpp Thu May  7 10:28:49 2015
@@ -0,0 +1,77 @@
+//===-- LockFilePosix.cpp ---------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Host/posix/LockFilePosix.h"
+
+#include <fcntl.h>
+
+using namespace lldb;
+using namespace lldb_private;
+
+namespace
+{
+
+Error fileLock (int fd, int cmd, int lock_type, const uint64_t start, const uint64_t len)
+{
+    struct flock fl;
+
+    fl.l_type   = lock_type;
+    fl.l_whence = SEEK_SET;
+    fl.l_start  = start;
+    fl.l_len    = len;
+    fl.l_pid    = ::getpid ();
+
+    Error error;
+    if (::fcntl (fd, cmd, &fl) == -1)
+        error.SetErrorToErrno ();
+
+    return error;
+}
+
+}  // namespace
+
+LockFilePosix::LockFilePosix (int fd)
+    : LockFileBase (fd)
+{
+}
+
+LockFilePosix::~LockFilePosix ()
+{
+    Unlock ();
+}
+
+Error
+LockFilePosix::DoWriteLock (const uint64_t start, const uint64_t len)
+{
+    return fileLock (m_fd, F_SETLKW, F_WRLCK, start, len);
+}
+
+Error
+LockFilePosix::DoTryWriteLock (const uint64_t start, const uint64_t len)
+{
+    return fileLock (m_fd, F_SETLK, F_WRLCK, start, len);
+}
+
+Error
+LockFilePosix::DoReadLock (const uint64_t start, const uint64_t len)
+{
+    return fileLock (m_fd, F_SETLKW, F_RDLCK, start, len);
+}
+
+Error
+LockFilePosix::DoTryReadLock (const uint64_t start, const uint64_t len)
+{
+    return fileLock (m_fd, F_SETLK, F_RDLCK, start, len);
+}
+
+Error
+LockFilePosix::DoUnlock ()
+{
+    return fileLock (m_fd, F_SETLK, F_UNLCK, m_start, m_len);
+}

Added: lldb/trunk/source/Host/windows/LockFileWindows.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/windows/LockFileWindows.cpp?rev=236736&view=auto
==============================================================================
--- lldb/trunk/source/Host/windows/LockFileWindows.cpp (added)
+++ lldb/trunk/source/Host/windows/LockFileWindows.cpp Thu May  7 10:28:49 2015
@@ -0,0 +1,98 @@
+//===-- LockFileWindows.cpp -------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Host/windows/LockFileWindows.h"
+
+#include <io.h>
+
+using namespace lldb;
+using namespace lldb_private;
+
+namespace
+{
+
+Error fileLock (HANDLE file_handle, DWORD flags, const uint64_t start, const uint64_t len)
+{
+    if (start != 0)
+        return Error ("Non-zero start lock regions are not supported");
+
+    OVERLAPPED overlapped = {0};
+
+    if (!::LockFileEx (file_handle, flags, 0, len, 0, &overlapped) && ::GetLastError () != ERROR_IO_PENDING)
+        return Error (::GetLastError (), eErrorTypeWin32);
+
+    DWORD bytes;
+    if (!::GetOverlappedResult (file_handle, &overlapped, &bytes, TRUE))
+        return Error (::GetLastError (), eErrorTypeWin32);
+
+    return Error ();
+}
+
+}  // namespace
+
+LockFileWindows::LockFileWindows (int fd)
+    : LockFileBase (fd),
+      m_file (reinterpret_cast<HANDLE> (_get_osfhandle (fd)))
+{
+}
+
+LockFileWindows::~LockFileWindows ()
+{
+    Unlock ();
+    if (m_file != INVALID_HANDLE_VALUE)
+    {
+        ::CloseHandle (m_file);
+        m_file = INVALID_HANDLE_VALUE;
+    }
+}
+
+bool
+LockFileWindows::IsValidFile () const
+{
+    return LockFileBase::IsValidFile() && m_file != INVALID_HANDLE_VALUE;
+}
+
+Error
+LockFileWindows::DoWriteLock (const uint64_t start, const uint64_t len)
+{
+    return fileLock (m_file, LOCKFILE_EXCLUSIVE_LOCK, start, len);
+}
+
+Error
+LockFileWindows::DoTryWriteLock (const uint64_t start, const uint64_t len)
+{
+    return fileLock (m_file, LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY, start, len);
+}
+
+Error
+LockFileWindows::DoReadLock (const uint64_t start, const uint64_t len)
+{
+    return fileLock (m_file, 0, start, len);
+}
+
+Error
+LockFileWindows::DoTryReadLock (const uint64_t start, const uint64_t len)
+{
+    return fileLock (m_file, LOCKFILE_FAIL_IMMEDIATELY, start, len);
+}
+
+Error
+LockFileWindows::DoUnlock ()
+{
+    OVERLAPPED overlapped = {0};
+
+    if (!::UnlockFileEx (m_file, 0, m_len, 0, &overlapped) && ::GetLastError () != ERROR_IO_PENDING)
+        return Error (::GetLastError (), eErrorTypeWin32);
+
+    DWORD bytes;
+    if (!::GetOverlappedResult (m_file, &overlapped, &bytes, TRUE))
+        return Error (::GetLastError (), eErrorTypeWin32);
+
+    return Error ();
+}

Modified: lldb/trunk/source/Target/Platform.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Platform.cpp?rev=236736&r1=236735&r2=236736&view=diff
==============================================================================
--- lldb/trunk/source/Target/Platform.cpp (original)
+++ lldb/trunk/source/Target/Platform.cpp Thu May  7 10:28:49 2015
@@ -1840,16 +1840,8 @@ Platform::GetCachedSharedModule (const M
         GetModuleCacheRoot (),
         GetCacheHostname (),
         module_spec,
-        [=](const ModuleSpec &module_spec, FileSpec &tmp_download_file_spec)
+        [=](const ModuleSpec &module_spec, const FileSpec &tmp_download_file_spec)
         {
-            // Get temporary file name for a downloaded module.
-            llvm::SmallString<PATH_MAX> tmp_download_file_path;
-            const auto err_code = llvm::sys::fs::createTemporaryFile (
-                "lldb", module_spec.GetUUID ().GetAsString ().c_str (), tmp_download_file_path);
-            if (err_code)
-                return Error ("Failed to create temp file: %s", err_code.message ().c_str ());
-
-            tmp_download_file_spec.SetFile (tmp_download_file_path.c_str (), true);
             return DownloadModuleSlice (module_spec.GetFileSpec (),
                                         module_spec.GetObjectOffset (),
                                         module_spec.GetObjectSize (),

Modified: lldb/trunk/source/Utility/ModuleCache.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Utility/ModuleCache.cpp?rev=236736&r1=236735&r2=236736&view=diff
==============================================================================
--- lldb/trunk/source/Utility/ModuleCache.cpp (original)
+++ lldb/trunk/source/Utility/ModuleCache.cpp Thu May  7 10:28:49 2015
@@ -11,20 +11,24 @@
 
 #include "lldb/Core/Module.h"
 #include "lldb/Core/ModuleSpec.h"
+#include "lldb/Host/File.h"
 #include "lldb/Host/FileSystem.h"
+#include "lldb/Host/LockFile.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/FileUtilities.h"
 
 #include <assert.h>
 
 #include <cstdio>
-#
+
 using namespace lldb;
 using namespace lldb_private;
 
 namespace {
 
 const char* kModulesSubdir = ".cache";
+const char* kLockFileName = ".lock";
+const char* kTempFileName = ".temp";
 
 FileSpec
 JoinPath (const FileSpec &path1, const char* path2)
@@ -58,21 +62,13 @@ ModuleCache::Put (const FileSpec &root_d
                   const FileSpec &tmp_file)
 {
     const auto module_spec_dir = GetModuleDirectory (root_dir_spec, module_spec.GetUUID ());
-    auto error = MakeDirectory (module_spec_dir);
-    if (error.Fail ())
-        return error;
-
     const auto module_file_path = JoinPath (module_spec_dir, module_spec.GetFileSpec ().GetFilename ().AsCString ());
 
     const auto tmp_file_path = tmp_file.GetPath ();
-    const auto err_code = llvm::sys::fs::copy_file (tmp_file_path.c_str (), module_file_path.GetPath ().c_str ());
+    const auto err_code = llvm::sys::fs::rename (tmp_file_path.c_str (), module_file_path.GetPath ().c_str ());
     if (err_code)
-    {
-        error.SetErrorStringWithFormat ("failed to copy file %s to %s: %s",
-                                        tmp_file_path.c_str (),
-                                        module_file_path.GetPath ().c_str (),
-                                        err_code.message ().c_str ());
-    }
+        return Error ("Failed to rename file %s to %s: %s",
+                      tmp_file_path.c_str (), module_file_path.GetPath ().c_str (), err_code.message ().c_str ());
 
     // Create sysroot link to a module.
     const auto sysroot_module_path_spec = GetHostSysRootModulePath (root_dir_spec, hostname, module_spec.GetFileSpec ());
@@ -99,7 +95,9 @@ ModuleCache::Get (const FileSpec &root_d
     const auto module_file_path = JoinPath (module_spec_dir, module_spec.GetFileSpec ().GetFilename ().AsCString ());
 
     if (!module_file_path.Exists ())
-        return Error ("module %s not found", module_file_path.GetPath ().c_str ());
+        return Error ("Module %s not found", module_file_path.GetPath ().c_str ());
+    if (module_file_path.GetByteSize () != module_spec.GetObjectSize ())
+        return Error ("Module %s has invalid file size", module_file_path.GetPath ().c_str ());
 
     // We may have already cached module but downloaded from an another host - in this case let's create a symlink to it.
     const auto sysroot_module_path_spec = GetHostSysRootModulePath (root_dir_spec, hostname, module_spec.GetFileSpec ());
@@ -127,34 +125,42 @@ ModuleCache::GetAndPut (const FileSpec &
                         lldb::ModuleSP &cached_module_sp,
                         bool *did_create_ptr)
 {
+    const auto module_spec_dir = GetModuleDirectory (root_dir_spec, module_spec.GetUUID ());
+    auto error = MakeDirectory (module_spec_dir);
+    if (error.Fail ())
+        return error;
+
+    // Open lock file.
+    const auto lock_file_spec = JoinPath (module_spec_dir, kLockFileName);
+    File lock_file (lock_file_spec, File::eOpenOptionWrite | File::eOpenOptionCanCreate | File::eOpenOptionCloseOnExec);
+    if (!lock_file)
+    {
+        error.SetErrorToErrno ();
+        return Error("Failed to open lock file %s: %s", lock_file_spec.GetPath ().c_str (), error.AsCString ());
+    }
+    LockFile lock (lock_file.GetDescriptor ());
+    error = lock.WriteLock (0, 1);
+    if (error.Fail ())
+        return Error("Failed to lock file %s:%s", lock_file_spec.GetPath ().c_str (), error.AsCString ());
+
     // Check local cache for a module.
-    auto error = Get (root_dir_spec,
-                      hostname,
-                      module_spec,
-                      cached_module_sp,
-                      did_create_ptr);
+    error = Get (root_dir_spec, hostname, module_spec, cached_module_sp, did_create_ptr);
     if (error.Success ())
         return error;
 
-    FileSpec tmp_download_file_spec;
+    const auto tmp_download_file_spec = JoinPath (module_spec_dir, kTempFileName);
     error = downloader (module_spec, tmp_download_file_spec);
     llvm::FileRemover tmp_file_remover (tmp_download_file_spec.GetPath ().c_str ());
     if (error.Fail ())
         return Error("Failed to download module: %s", error.AsCString ());
 
     // Put downloaded file into local module cache.
-    error = Put (root_dir_spec,
-                 hostname,
-                 module_spec,
-                 tmp_download_file_spec);
+    error = Put (root_dir_spec, hostname, module_spec, tmp_download_file_spec);
     if (error.Fail ())
         return Error ("Failed to put module into cache: %s", error.AsCString ());
 
-    return Get (root_dir_spec,
-                hostname,
-                module_spec,
-                cached_module_sp,
-                did_create_ptr);
+    tmp_file_remover.releaseFile ();
+    return Get (root_dir_spec, hostname, module_spec, cached_module_sp, did_create_ptr);
 }
 
 FileSpec

Modified: lldb/trunk/source/Utility/ModuleCache.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Utility/ModuleCache.h?rev=236736&r1=236735&r2=236736&view=diff
==============================================================================
--- lldb/trunk/source/Utility/ModuleCache.h (original)
+++ lldb/trunk/source/Utility/ModuleCache.h Thu May  7 10:28:49 2015
@@ -14,6 +14,7 @@
 #include "lldb/lldb-forward.h"
 
 #include "lldb/Core/Error.h"
+#include "lldb/Host/File.h"
 #include "lldb/Host/FileSpec.h"
 
 #include <functional>
@@ -45,9 +46,18 @@ class UUID;
 class ModuleCache
 {
 public:
-    using Downloader = std::function<Error (const ModuleSpec&, FileSpec&)>;
+    using Downloader = std::function<Error (const ModuleSpec&, const FileSpec&)>;
 
     Error
+    GetAndPut(const FileSpec &root_dir_spec,
+              const char *hostname,
+              const ModuleSpec &module_spec,
+              const Downloader &downloader,
+              lldb::ModuleSP &cached_module_sp,
+              bool *did_create_ptr);
+
+private:
+    Error
     Put (const FileSpec &root_dir_spec,
          const char *hostname,
          const ModuleSpec &module_spec,
@@ -60,15 +70,6 @@ public:
          lldb::ModuleSP &cached_module_sp,
          bool *did_create_ptr);
 
-    Error
-    GetAndPut(const FileSpec &root_dir_spec,
-              const char *hostname,
-              const ModuleSpec &module_spec,
-              const Downloader &downloader,
-              lldb::ModuleSP &cached_module_sp,
-              bool *did_create_ptr);
-
-private:
     static FileSpec
     GetModuleDirectory (const FileSpec &root_dir_spec, const UUID &uuid);
 





More information about the lldb-commits mailing list