1 /*
2  *  Copyright 2015 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 #include "rtc_base/buffer_queue.h"
12 
13 #include <stdint.h>
14 #include <string.h>
15 
16 #include <algorithm>
17 
18 namespace rtc {
19 
BufferQueue(size_t capacity,size_t default_size)20 BufferQueue::BufferQueue(size_t capacity, size_t default_size)
21     : capacity_(capacity), default_size_(default_size) {}
22 
~BufferQueue()23 BufferQueue::~BufferQueue() {
24   webrtc::MutexLock lock(&mutex_);
25 
26   for (Buffer* buffer : queue_) {
27     delete buffer;
28   }
29   for (Buffer* buffer : free_list_) {
30     delete buffer;
31   }
32 }
33 
size() const34 size_t BufferQueue::size() const {
35   webrtc::MutexLock lock(&mutex_);
36   return queue_.size();
37 }
38 
Clear()39 void BufferQueue::Clear() {
40   webrtc::MutexLock lock(&mutex_);
41   while (!queue_.empty()) {
42     free_list_.push_back(queue_.front());
43     queue_.pop_front();
44   }
45 }
46 
ReadFront(void * buffer,size_t bytes,size_t * bytes_read)47 bool BufferQueue::ReadFront(void* buffer, size_t bytes, size_t* bytes_read) {
48   webrtc::MutexLock lock(&mutex_);
49   if (queue_.empty()) {
50     return false;
51   }
52 
53   bool was_writable = queue_.size() < capacity_;
54   Buffer* packet = queue_.front();
55   queue_.pop_front();
56 
57   bytes = std::min(bytes, packet->size());
58   memcpy(buffer, packet->data(), bytes);
59   if (bytes_read) {
60     *bytes_read = bytes;
61   }
62   free_list_.push_back(packet);
63   if (!was_writable) {
64     NotifyWritableForTest();
65   }
66   return true;
67 }
68 
WriteBack(const void * buffer,size_t bytes,size_t * bytes_written)69 bool BufferQueue::WriteBack(const void* buffer,
70                             size_t bytes,
71                             size_t* bytes_written) {
72   webrtc::MutexLock lock(&mutex_);
73   if (queue_.size() == capacity_) {
74     return false;
75   }
76 
77   bool was_readable = !queue_.empty();
78   Buffer* packet;
79   if (!free_list_.empty()) {
80     packet = free_list_.back();
81     free_list_.pop_back();
82   } else {
83     packet = new Buffer(bytes, default_size_);
84   }
85 
86   packet->SetData(static_cast<const uint8_t*>(buffer), bytes);
87   if (bytes_written) {
88     *bytes_written = bytes;
89   }
90   queue_.push_back(packet);
91   if (!was_readable) {
92     NotifyReadableForTest();
93   }
94   return true;
95 }
96 
97 }  // namespace rtc
98