ilya-biryukov updated this revision to Diff 176381.
ilya-biryukov marked an inline comment as done.
ilya-biryukov added a comment.
This revision is now accepted and ready to land.

- Keep using memory-mapped files for PCHs
- Move once


Repository:
  rCTE Clang Tools Extra

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D55139/new/

https://reviews.llvm.org/D55139

Files:
  clangd/CMakeLists.txt
  clangd/FSProvider.cpp
  clangd/FSProvider.h

Index: clangd/FSProvider.h
===================================================================
--- clangd/FSProvider.h
+++ clangd/FSProvider.h
@@ -33,9 +33,7 @@
 public:
   // FIXME: returns the single real FS instance, which is not threadsafe.
   llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>
-  getFileSystem() const override {
-    return llvm::vfs::getRealFileSystem();
-  }
+  getFileSystem() const override;
 };
 
 } // namespace clangd
Index: clangd/FSProvider.cpp
===================================================================
--- /dev/null
+++ clangd/FSProvider.cpp
@@ -0,0 +1,85 @@
+//===--- FSProvider.cpp - VFS provider for ClangdServer -------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "FSProvider.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/VirtualFileSystem.h"
+#include <memory>
+
+using namespace llvm;
+
+namespace clang {
+namespace clangd {
+
+namespace {
+/// Always opens files in the underlying filesystem as "volatile", meaning they
+/// won't be memory-mapped. This avoid locking the files on Windows.
+class VolatileFSProvider : public llvm::vfs::ProxyFileSystem {
+public:
+  explicit VolatileFSProvider(llvm::IntrusiveRefCntPtr<FileSystem> FS)
+      : ProxyFileSystem(std::move(FS)) {}
+
+  llvm::ErrorOr<std::unique_ptr<vfs::File>>
+  openFileForRead(const Twine &InPath) override {
+    SmallString<128> Path;
+    InPath.toVector(Path);
+
+    auto File = getUnderlyingFS().openFileForRead(Path);
+    if (!File)
+      return File;
+    // Try to guess preamble files, they can be memory-mapped even on Windows as
+    // clangd has exclusive access to those.
+    StringRef FileName = llvm::sys::path::filename(Path);
+    if (FileName.startswith("preamble-") && FileName.endswith(".pch"))
+      return File;
+    return std::unique_ptr<VolatileFile>(
+        new VolatileFile(std::move(*File)));
+  }
+
+private:
+  class VolatileFile : public vfs::File {
+  public:
+    VolatileFile(std::unique_ptr<vfs::File> Wrapped)
+        : Wrapped(std::move(Wrapped)) {
+      assert(this->Wrapped);
+    }
+
+    virtual llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
+    getBuffer(const Twine &Name, int64_t FileSize, bool RequiresNullTerminator,
+              bool /*IsVolatile*/) override {
+      return Wrapped->getBuffer(Name, FileSize, RequiresNullTerminator,
+                                /*IsVolatile=*/true);
+    }
+
+    llvm::ErrorOr<vfs::Status> status() override { return Wrapped->status(); }
+    llvm::ErrorOr<std::string> getName() override { return Wrapped->getName(); }
+    std::error_code close() override { return Wrapped->close(); }
+
+  private:
+    std::unique_ptr<File> Wrapped;
+  };
+};
+} // namespace
+
+llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>
+clang::clangd::RealFileSystemProvider::getFileSystem() const {
+// Avoid using memory-mapped files on Windows, they cause file locking issues.
+// FIXME: Try to use a similar approach in Sema instead of relying on
+//        error-prone propagation of the 'isVolatile' flag through all layers.
+#ifdef _WIN32
+  return new VolatileFSProvider(vfs::getRealFileSystem());
+#else
+  return vfs::getRealFileSystem();
+#endif
+}
+} // namespace clangd
+} // namespace clang
Index: clangd/CMakeLists.txt
===================================================================
--- clangd/CMakeLists.txt
+++ clangd/CMakeLists.txt
@@ -23,6 +23,7 @@
   FindSymbols.cpp
   FileDistance.cpp
   FS.cpp
+  FSProvider.cpp
   FuzzyMatch.cpp
   GlobalCompilationDatabase.cpp
   Headers.cpp
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to