blob: aa3164f09a3b4c12f17481b5dc6570182bf7de25 [file] [log] [blame]
Niels Möller13339482019-03-28 13:30:15 +01001/*
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
Artem Titovc374d112022-06-16 21:27:45 +020016#include "api/task_queue/pending_task_safety_flag.h"
Niels Möller13339482019-03-28 13:30:15 +010017#include "rtc_base/stream.h"
Markus Handell18523c32020-07-08 17:55:58 +020018#include "rtc_base/synchronization/mutex.h"
Niels Möller13339482019-03-28 13:30:15 +010019
20namespace rtc {
21
22// FifoBuffer allows for efficient, thread-safe buffering of data between
23// writer and reader.
24class 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;
Byoungchan Lee14af7622022-01-12 05:24:58 +090031
32 FifoBuffer(const FifoBuffer&) = delete;
33 FifoBuffer& operator=(const FifoBuffer&) = delete;
34
Niels Möller13339482019-03-28 13:30:15 +010035 // Gets the amount of data currently readable from the buffer.
36 bool GetBuffered(size_t* data_len) const;
Niels Möller13339482019-03-28 13:30:15 +010037
38 // StreamInterface methods
39 StreamState GetState() const override;
40 StreamResult Read(void* buffer,
41 size_t bytes,
42 size_t* bytes_read,
43 int* error) override;
44 StreamResult Write(const void* buffer,
45 size_t bytes,
46 size_t* bytes_written,
47 int* error) override;
48 void Close() override;
49
50 // Seek to a byte offset from the beginning of the stream. Returns false if
51 // the stream does not support seeking, or cannot seek to the specified
52 // position.
53 bool SetPosition(size_t position);
54
55 // Get the byte offset of the current position from the start of the stream.
56 // Returns false if the position is not known.
57 bool GetPosition(size_t* position) const;
58
59 // Seek to the start of the stream.
60 bool Rewind() { return SetPosition(0); }
61
62 // GetReadData returns a pointer to a buffer which is owned by the stream.
63 // The buffer contains data_len bytes. null is returned if no data is
64 // available, or if the method fails. If the caller processes the data, it
65 // must call ConsumeReadData with the number of processed bytes. GetReadData
66 // does not require a matching call to ConsumeReadData if the data is not
67 // processed. Read and ConsumeReadData invalidate the buffer returned by
68 // GetReadData.
69 const void* GetReadData(size_t* data_len);
70 void ConsumeReadData(size_t used);
71 // GetWriteBuffer returns a pointer to a buffer which is owned by the stream.
72 // The buffer has a capacity of buf_len bytes. null is returned if there is
73 // no buffer available, or if the method fails. The call may write data to
74 // the buffer, and then call ConsumeWriteBuffer with the number of bytes
75 // written. GetWriteBuffer does not require a matching call to
76 // ConsumeWriteData if no data is written. Write and
77 // ConsumeWriteData invalidate the buffer returned by GetWriteBuffer.
78 void* GetWriteBuffer(size_t* buf_len);
79 void ConsumeWriteBuffer(size_t used);
80
Niels Möller13339482019-03-28 13:30:15 +010081 private:
Tommi04482982020-10-05 12:43:53 +000082 void PostEvent(int events, int err) {
Danil Chapovalov5286dcf2022-07-18 17:04:56 +020083 owner_->PostTask(webrtc::SafeTask(
84 task_safety_.flag(),
85 [this, events, err]() { SignalEvent(this, events, err); }));
Tommi04482982020-10-05 12:43:53 +000086 }
87
Niels Mölleracf4f552021-09-27 11:51:17 +020088 // Helper method that implements Read. Caller must acquire a lock
Niels Möller13339482019-03-28 13:30:15 +010089 // when calling this method.
Niels Mölleracf4f552021-09-27 11:51:17 +020090 StreamResult ReadLocked(void* buffer, size_t bytes, size_t* bytes_read)
Markus Handell18523c32020-07-08 17:55:58 +020091 RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
Niels Möller13339482019-03-28 13:30:15 +010092
Niels Mölleracf4f552021-09-27 11:51:17 +020093 // Helper method that implements Write. Caller must acquire a lock
Niels Möller13339482019-03-28 13:30:15 +010094 // when calling this method.
Niels Mölleracf4f552021-09-27 11:51:17 +020095 StreamResult WriteLocked(const void* buffer,
96 size_t bytes,
97 size_t* bytes_written)
Markus Handell18523c32020-07-08 17:55:58 +020098 RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
Niels Möller13339482019-03-28 13:30:15 +010099
Tommi04482982020-10-05 12:43:53 +0000100 webrtc::ScopedTaskSafety task_safety_;
101
Niels Möller13339482019-03-28 13:30:15 +0100102 // keeps the opened/closed state of the stream
Markus Handell18523c32020-07-08 17:55:58 +0200103 StreamState state_ RTC_GUARDED_BY(mutex_);
Niels Möller13339482019-03-28 13:30:15 +0100104 // the allocated buffer
Markus Handell18523c32020-07-08 17:55:58 +0200105 std::unique_ptr<char[]> buffer_ RTC_GUARDED_BY(mutex_);
Niels Möller13339482019-03-28 13:30:15 +0100106 // size of the allocated buffer
Niels Mölleracf4f552021-09-27 11:51:17 +0200107 const size_t buffer_length_;
Niels Möller13339482019-03-28 13:30:15 +0100108 // amount of readable data in the buffer
Markus Handell18523c32020-07-08 17:55:58 +0200109 size_t data_length_ RTC_GUARDED_BY(mutex_);
Niels Möller13339482019-03-28 13:30:15 +0100110 // offset to the readable data
Markus Handell18523c32020-07-08 17:55:58 +0200111 size_t read_position_ RTC_GUARDED_BY(mutex_);
Niels Möller13339482019-03-28 13:30:15 +0100112 // stream callbacks are dispatched on this thread
Tommi04482982020-10-05 12:43:53 +0000113 Thread* const owner_;
Niels Möller13339482019-03-28 13:30:15 +0100114 // object lock
Markus Handell18523c32020-07-08 17:55:58 +0200115 mutable webrtc::Mutex mutex_;
Niels Möller13339482019-03-28 13:30:15 +0100116};
117
118} // namespace rtc
119
120#endif // RTC_BASE_MEMORY_FIFO_BUFFER_H_