1 //===-- StreamTee.h ------------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef liblldb_StreamTee_h_
11 #define liblldb_StreamTee_h_
15 #include "lldb/Core/Stream.h"
16 #include "lldb/Host/Mutex.h"
18 namespace lldb_private {
20 class StreamTee : public Stream
25 m_streams_mutex (Mutex::eMutexTypeRecursive),
30 StreamTee (lldb::StreamSP &stream_sp):
32 m_streams_mutex (Mutex::eMutexTypeRecursive),
35 // No need to lock mutex during construction
37 m_streams.push_back (stream_sp);
41 StreamTee (lldb::StreamSP &stream_sp, lldb::StreamSP &stream_2_sp) :
43 m_streams_mutex (Mutex::eMutexTypeRecursive),
46 // No need to lock mutex during construction
48 m_streams.push_back (stream_sp);
50 m_streams.push_back (stream_2_sp);
53 StreamTee (const StreamTee &rhs) :
55 m_streams_mutex (Mutex::eMutexTypeRecursive),
56 m_streams() // Don't copy until we lock down "rhs"
58 Mutex::Locker locker (rhs.m_streams_mutex);
59 m_streams = rhs.m_streams;
68 operator = (const StreamTee &rhs)
71 Stream::operator=(rhs);
72 Mutex::Locker lhs_locker (m_streams_mutex);
73 Mutex::Locker rhs_locker (rhs.m_streams_mutex);
74 m_streams = rhs.m_streams;
82 Mutex::Locker locker (m_streams_mutex);
83 collection::iterator pos, end;
84 for (pos = m_streams.begin(), end = m_streams.end(); pos != end; ++pos)
86 // Allow for our collection to contain NULL streams. This allows
87 // the StreamTee to be used with hard coded indexes for clients
88 // that might want N total streams with only a few that are set
90 Stream *strm = pos->get();
97 Write (const void *s, size_t length)
99 Mutex::Locker locker (m_streams_mutex);
100 if (m_streams.empty())
103 size_t min_bytes_written = SIZE_MAX;
104 collection::iterator pos, end;
105 for (pos = m_streams.begin(), end = m_streams.end(); pos != end; ++pos)
107 // Allow for our collection to contain NULL streams. This allows
108 // the StreamTee to be used with hard coded indexes for clients
109 // that might want N total streams with only a few that are set
111 Stream *strm = pos->get();
114 const size_t bytes_written = strm->Write (s, length);
115 if (min_bytes_written > bytes_written)
116 min_bytes_written = bytes_written;
119 if (min_bytes_written == SIZE_MAX)
121 return min_bytes_written;
125 AppendStream (const lldb::StreamSP &stream_sp)
127 size_t new_idx = m_streams.size();
128 Mutex::Locker locker (m_streams_mutex);
129 m_streams.push_back (stream_sp);
134 GetNumStreams () const
138 Mutex::Locker locker (m_streams_mutex);
139 result = m_streams.size();
145 GetStreamAtIndex (uint32_t idx)
147 lldb::StreamSP stream_sp;
148 Mutex::Locker locker (m_streams_mutex);
149 if (idx < m_streams.size())
150 stream_sp = m_streams[idx];
155 SetStreamAtIndex (uint32_t idx, const lldb::StreamSP& stream_sp)
157 Mutex::Locker locker (m_streams_mutex);
158 // Resize our stream vector as necessary to fit as many streams
159 // as needed. This also allows this class to be used with hard
160 // coded indexes that can be used contain many streams, not all
161 // of which are valid.
162 if (idx >= m_streams.size())
163 m_streams.resize(idx + 1);
164 m_streams[idx] = stream_sp;
169 typedef std::vector<lldb::StreamSP> collection;
170 mutable Mutex m_streams_mutex;
171 collection m_streams;
174 } // namespace lldb_private
175 #endif // #ifndef liblldb_StreamTee_h_