ilya-biryukov created this revision. ilya-biryukov added reviewers: hokein, kadircet. Herald added subscribers: arphaman, jkorous, MaskRay, ioeric, mgorny.
Memory-mapping files on Windows leads to them being locked and prevents editors from saving changes to those files on disk. This is fine for the compiler, but not acceptable for an interactive tool like clangd. Therefore, we choose to avoid using memory-mapped files on Windows. Repository: rCTE Clang Tools Extra 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,74 @@ +//===--- 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/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 &Path) override { + auto File = getUnderlyingFS().openFileForRead(Path); + if (!File) + return File; + return std::unique_ptr<VolatileFile>( + new VolatileFile(std::move(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