xref: /aosp_15_r20/external/webrtc/rtc_base/memory/fifo_buffer.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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