xref: /freebsd/contrib/llvm-project/lldb/include/lldb/Host/StreamFile.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
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