1 //===-- StreamFile.h --------------------------------------------*- C++ -*-===// 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 #ifndef LLDB_HOST_STREAMFILE_H 10 #define LLDB_HOST_STREAMFILE_H 11 12 #include "lldb/Host/File.h" 13 #include "lldb/Utility/Stream.h" 14 #include "lldb/lldb-defines.h" 15 #include "lldb/lldb-enumerations.h" 16 #include "lldb/lldb-forward.h" 17 18 #include <cstdint> 19 #include <cstdio> 20 #include <memory> 21 #include <mutex> 22 23 namespace lldb_private { 24 25 class StreamFile : public Stream { 26 public: 27 StreamFile(uint32_t flags, uint32_t addr_size, lldb::ByteOrder byte_order); 28 29 StreamFile(int fd, bool transfer_ownership); 30 31 StreamFile(const char *path, File::OpenOptions options, 32 uint32_t permissions = lldb::eFilePermissionsFileDefault); 33 34 StreamFile(FILE *fh, bool transfer_ownership); 35 StreamFile(std::shared_ptr<File> file)36 StreamFile(std::shared_ptr<File> file) : m_file_sp(file) { assert(file); }; 37 38 ~StreamFile() override; 39 GetFile()40 File &GetFile() { return *m_file_sp; } 41 GetFile()42 const File &GetFile() const { return *m_file_sp; } 43 GetFileSP()44 std::shared_ptr<File> GetFileSP() { return m_file_sp; } 45 46 void Flush() override; 47 48 protected: 49 // Classes that inherit from StreamFile can see and modify these 50 std::shared_ptr<File> m_file_sp; // never NULL 51 size_t WriteImpl(const void *s, size_t length) override; 52 53 private: 54 StreamFile(const StreamFile &) = delete; 55 const StreamFile &operator=(const StreamFile &) = delete; 56 }; 57 58 class LockableStreamFile; 59 class LockedStreamFile : public StreamFile { 60 public: ~LockedStreamFile()61 ~LockedStreamFile() { Flush(); } 62 LockedStreamFile(LockedStreamFile && other)63 LockedStreamFile(LockedStreamFile &&other) 64 : StreamFile(other.m_file_sp), m_lock(std::move(other.m_lock)) {} 65 66 private: LockedStreamFile(std::shared_ptr<File> file,std::recursive_mutex & mutex)67 LockedStreamFile(std::shared_ptr<File> file, std::recursive_mutex &mutex) 68 : StreamFile(file), m_lock(mutex) {} 69 70 friend class LockableStreamFile; 71 72 std::unique_lock<std::recursive_mutex> m_lock; 73 }; 74 75 class LockableStreamFile { 76 public: 77 using Mutex = std::recursive_mutex; 78 LockableStreamFile(std::shared_ptr<StreamFile> stream_file_sp,Mutex & mutex)79 LockableStreamFile(std::shared_ptr<StreamFile> stream_file_sp, Mutex &mutex) 80 : m_file_sp(stream_file_sp->GetFileSP()), m_mutex(mutex) {} LockableStreamFile(StreamFile & stream_file,Mutex & mutex)81 LockableStreamFile(StreamFile &stream_file, Mutex &mutex) 82 : m_file_sp(stream_file.GetFileSP()), m_mutex(mutex) {} LockableStreamFile(FILE * fh,bool transfer_ownership,Mutex & mutex)83 LockableStreamFile(FILE *fh, bool transfer_ownership, Mutex &mutex) 84 : m_file_sp(std::make_shared<NativeFile>(fh, transfer_ownership)), 85 m_mutex(mutex) {} LockableStreamFile(std::shared_ptr<File> file_sp,Mutex & mutex)86 LockableStreamFile(std::shared_ptr<File> file_sp, Mutex &mutex) 87 : m_file_sp(file_sp), m_mutex(mutex) {} 88 Lock()89 LockedStreamFile Lock() { return LockedStreamFile(m_file_sp, m_mutex); } 90 91 /// Unsafe accessors to get the underlying File without a lock. Exists for 92 /// legacy reasons. 93 /// @{ GetUnlockedFile()94 File &GetUnlockedFile() { return *m_file_sp; } GetUnlockedFileSP()95 std::shared_ptr<File> GetUnlockedFileSP() { return m_file_sp; } 96 /// @} 97 98 protected: 99 std::shared_ptr<File> m_file_sp; 100 Mutex &m_mutex; 101 102 private: 103 LockableStreamFile(const LockableStreamFile &) = delete; 104 const LockableStreamFile &operator=(const LockableStreamFile &) = delete; 105 }; 106 107 } // namespace lldb_private 108 109 #endif // LLDB_HOST_STREAMFILE_H 110