1 /* 2 * Copyright 2019 The WebRTC Project Authors. All rights reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #ifndef RTC_BASE_MEMORY_FIFO_BUFFER_H_ 12 #define RTC_BASE_MEMORY_FIFO_BUFFER_H_ 13 14 #include <memory> 15 16 #include "api/task_queue/pending_task_safety_flag.h" 17 #include "rtc_base/stream.h" 18 #include "rtc_base/synchronization/mutex.h" 19 20 namespace rtc { 21 22 // FifoBuffer allows for efficient, thread-safe buffering of data between 23 // writer and reader. 24 class FifoBuffer final : public StreamInterface { 25 public: 26 // Creates a FIFO buffer with the specified capacity. 27 explicit FifoBuffer(size_t length); 28 // Creates a FIFO buffer with the specified capacity and owner 29 FifoBuffer(size_t length, Thread* owner); 30 ~FifoBuffer() override; 31 32 FifoBuffer(const FifoBuffer&) = delete; 33 FifoBuffer& operator=(const FifoBuffer&) = delete; 34 35 // Gets the amount of data currently readable from the buffer. 36 bool GetBuffered(size_t* data_len) const; 37 38 // StreamInterface methods 39 StreamState GetState() const override; 40 StreamResult Read(rtc::ArrayView<uint8_t> buffer, 41 size_t& bytes_read, 42 int& error) override; 43 StreamResult Write(rtc::ArrayView<const uint8_t> buffer, 44 size_t& bytes_written, 45 int& error) override; 46 void Close() override; 47 48 // Seek to a byte offset from the beginning of the stream. Returns false if 49 // the stream does not support seeking, or cannot seek to the specified 50 // position. 51 bool SetPosition(size_t position); 52 53 // Get the byte offset of the current position from the start of the stream. 54 // Returns false if the position is not known. 55 bool GetPosition(size_t* position) const; 56 57 // Seek to the start of the stream. Rewind()58 bool Rewind() { return SetPosition(0); } 59 60 // GetReadData returns a pointer to a buffer which is owned by the stream. 61 // The buffer contains data_len bytes. null is returned if no data is 62 // available, or if the method fails. If the caller processes the data, it 63 // must call ConsumeReadData with the number of processed bytes. GetReadData 64 // does not require a matching call to ConsumeReadData if the data is not 65 // processed. Read and ConsumeReadData invalidate the buffer returned by 66 // GetReadData. 67 const void* GetReadData(size_t* data_len); 68 void ConsumeReadData(size_t used); 69 // GetWriteBuffer returns a pointer to a buffer which is owned by the stream. 70 // The buffer has a capacity of buf_len bytes. null is returned if there is 71 // no buffer available, or if the method fails. The call may write data to 72 // the buffer, and then call ConsumeWriteBuffer with the number of bytes 73 // written. GetWriteBuffer does not require a matching call to 74 // ConsumeWriteData if no data is written. Write and 75 // ConsumeWriteData invalidate the buffer returned by GetWriteBuffer. 76 void* GetWriteBuffer(size_t* buf_len); 77 void ConsumeWriteBuffer(size_t used); 78 79 private: PostEvent(int events,int err)80 void PostEvent(int events, int err) { 81 owner_->PostTask(webrtc::SafeTask( 82 task_safety_.flag(), 83 [this, events, err]() { SignalEvent(this, events, err); })); 84 } 85 86 // Helper method that implements Read. Caller must acquire a lock 87 // when calling this method. 88 StreamResult ReadLocked(void* buffer, size_t bytes, size_t* bytes_read) 89 RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); 90 91 // Helper method that implements Write. Caller must acquire a lock 92 // when calling this method. 93 StreamResult WriteLocked(const void* buffer, 94 size_t bytes, 95 size_t* bytes_written) 96 RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); 97 98 webrtc::ScopedTaskSafety task_safety_; 99 100 // keeps the opened/closed state of the stream 101 StreamState state_ RTC_GUARDED_BY(mutex_); 102 // the allocated buffer 103 std::unique_ptr<char[]> buffer_ RTC_GUARDED_BY(mutex_); 104 // size of the allocated buffer 105 const size_t buffer_length_; 106 // amount of readable data in the buffer 107 size_t data_length_ RTC_GUARDED_BY(mutex_); 108 // offset to the readable data 109 size_t read_position_ RTC_GUARDED_BY(mutex_); 110 // stream callbacks are dispatched on this thread 111 Thread* const owner_; 112 // object lock 113 mutable webrtc::Mutex mutex_; 114 }; 115 116 } // namespace rtc 117 118 #endif // RTC_BASE_MEMORY_FIFO_BUFFER_H_ 119