Index: webrtc/modules/audio_processing/swapped_nonblocking_queue.h |
diff --git a/webrtc/modules/audio_processing/swapped_nonblocking_queue.h b/webrtc/modules/audio_processing/swapped_nonblocking_queue.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..adac158e973b7ab3d5849af73770dcfc002a43bb |
--- /dev/null |
+++ b/webrtc/modules/audio_processing/swapped_nonblocking_queue.h |
@@ -0,0 +1,107 @@ |
+/* |
+ * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. |
+ * |
+ * Use of this source code is governed by a BSD-style license |
+ * that can be found in the LICENSE file in the root of the source |
+ * tree. An additional intellectual property rights grant can be found |
+ * in the file PATENTS. All contributing project authors may |
+ * be found in the AUTHORS file in the root of the source tree. |
+ */ |
+ |
+#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_SWAPPED_NONBLOCKING_QUEUE_H_ |
+#define WEBRTC_MODULES_AUDIO_PROCESSING_SWAPPED_NONBLOCKING_QUEUE_H_ |
+ |
+#include <vector> |
+ |
+#include "webrtc/base/checks.h" |
+#include "webrtc/base/criticalsection.h" |
+ |
+namespace webrtc { |
+ |
+// This class is to be used as a one-way queue where data is |
kwiberg-webrtc
2015/10/10 10:16:56
"is to be used as a" -> "is"
peah-webrtc
2015/10/12 13:01:06
Sorry, I don't follow that. Please elaborate furth
kwiberg-webrtc
2015/10/12 14:05:48
Just replace the left-hand side string with the ri
peah-webrtc
2015/10/13 11:56:11
Ah :-). Of course, I thought it was something more
peah-webrtc
2015/10/13 11:56:11
Done.
|
+// written from one end and read from the other end. |
+// The read and write operations are protected by a common lock. |
kwiberg-webrtc
2015/10/10 10:16:56
At this level, it's probably better to just say th
peah-webrtc
2015/10/12 13:01:07
Done.
hlundin-webrtc
2015/10/13 06:37:57
+1. Spare the implementation details.
peah-webrtc
2015/10/13 11:56:11
Done.
|
+// The queueable objects must all implement a swap() method. |
kwiberg-webrtc
2015/10/10 10:16:55
That shouldn't be necessary. As long as the usual
peah-webrtc
2015/10/12 13:01:08
I changed the comment a bit. Could you please veri
kwiberg-webrtc
2015/10/12 14:05:48
Looks good.
peah-webrtc
2015/10/13 11:56:11
Acknowledged.
|
+template <typename T> |
+class SwappedNonBlockingQueue { |
kwiberg-webrtc
2015/10/10 10:16:56
It's a swapping queue, not a swappable one. "Nonbl
The Sun (google.com)
2015/10/10 14:00:54
SwapQueue is a great term! Nonblocking or not.
peah-webrtc
2015/10/12 13:01:07
Totally agree! I changed it to swap_queue and skip
kwiberg-webrtc
2015/10/12 14:05:48
Acknowledged.
|
+ public: |
+ explicit SwappedNonBlockingQueue<T>(size_t initial_size) { |
kwiberg-webrtc
2015/10/10 10:16:56
No need to repeat the <T> here.
peah-webrtc
2015/10/12 13:01:08
Done.
|
+ queue_.resize(initial_size); |
kwiberg-webrtc
2015/10/10 10:16:56
std::vector has a constructor that does this. And
peah-webrtc
2015/10/12 13:01:08
Done.
|
+ Reset(); |
kwiberg-webrtc
2015/10/10 10:16:56
This takes a lock, and just sets two members to ze
peah-webrtc
2015/10/12 13:01:07
Done.
hlundin-webrtc
2015/10/13 06:37:57
OTOH, calling Reset() here makes it more obvious t
peah-webrtc
2015/10/13 11:56:11
That was partly my initial intention as well, and
|
+ } |
+ |
+ explicit SwappedNonBlockingQueue<T>(size_t initial_size, const T& initializer) |
the sun
2015/10/09 12:09:54
Remove "explicit".
"initial_size" -> "max_size" o
peah-webrtc
2015/10/12 13:01:08
Done.
|
+ : SwappedNonBlockingQueue<T>(initial_size) { |
+ // Fill the queue with elements identical to initializer |
+ for (typename std::vector<T>::iterator it = queue_.begin(); |
the sun
2015/10/09 12:09:55
for (auto it = ... ?
peah-webrtc
2015/10/12 13:01:07
Done.
|
+ it != queue_.end(); ++it) |
the sun
2015/10/09 12:09:54
Always use braces, please.
peah-webrtc
2015/10/12 13:01:08
Done.
hlundin-webrtc
2015/10/13 06:37:57
I agree, but I know that braces here would get pus
peah-webrtc
2015/10/13 11:56:11
Acknowledged.
|
+ *it = initializer; |
+ } |
kwiberg-webrtc
2015/10/10 10:16:55
std::vector has a constructor for this too.
peah-webrtc
2015/10/12 13:01:07
I removed this one and instead added the one below
kwiberg-webrtc
2015/10/12 14:05:48
No, I count three constructors in the new patch se
peah-webrtc
2015/10/13 11:56:11
Will have a look at that
|
+ |
kwiberg-webrtc
2015/10/10 10:16:56
The constructors are the complicated part of this.
peah-webrtc
2015/10/12 13:01:07
Sounds good! I took the implementation of this one
peah-webrtc
2015/10/12 13:01:07
Done.
|
+ // Resets the queue to have zero content. |
+ void Reset() { |
the sun
2015/10/09 12:09:54
Really needed?
kwiberg-webrtc
2015/10/10 10:16:56
+1. Also, consider calling it clear() or Clear();
peah-webrtc
2015/10/12 13:01:08
I think it is needed as it provides lower cost res
|
+ rtc::CritScope cs(&crit_queue_); |
+ last_write_index_ = 0; |
+ last_read_index_ = 0; |
+ } |
+ |
+ // Inserts a chunk of data into the queue in a thread safe manner. |
+ // The input is replaced by an undefined chunk of type T. |
the sun
2015/10/09 12:09:54
replaced by -> swapped with
peah-webrtc
2015/10/12 13:01:08
Done.
|
+ // Returns false if the queue is full, and true if not. |
kwiberg-webrtc
2015/10/10 10:16:55
It's not an arbitrary value; it's either one which
peah-webrtc
2015/10/12 13:01:07
Makes sense! I revised the comments of the class a
peah-webrtc
2015/10/12 13:01:07
I added some documentation. Please let me know if
kwiberg-webrtc
2015/10/12 14:05:48
Acknowledged.
hlundin-webrtc
2015/10/13 06:37:57
Clarify that false if returned if the queue is ful
peah-webrtc
2015/10/13 11:56:11
Good point! I added some more documentation regard
|
+ bool Insert(T* const input) { |
kwiberg-webrtc
2015/10/10 10:16:56
Better drop the const here, or people will confuse
peah-webrtc
2015/10/12 13:01:07
Done.
peah-webrtc
2015/10/12 13:01:07
Done.
|
+ rtc::CritScope cs(&crit_queue_); |
+ |
+ // Early return if the queue is full. |
+ size_t next_write_index_ = |
the sun
2015/10/09 12:09:54
No trailing underscore on local variables.
Can yo
peah-webrtc
2015/10/12 13:01:07
I removed those functions because with the current
peah-webrtc
2015/10/12 13:01:07
Did this, but a bit differently. I also kept the s
|
+ (last_write_index_ < (queue_.size() - 1) ? last_write_index_ + 1 : 0); |
+ if (next_write_index_ == last_read_index_) |
+ return false; |
kwiberg-webrtc
2015/10/10 10:16:56
Hmm. This means you'll keep at most size() - 1 ele
peah-webrtc
2015/10/12 13:01:08
Good point. I added the num_elements_ idea, but ke
peah-webrtc
2015/10/12 13:01:08
I added the num_elements_ as member which simplifi
|
+ |
+ last_write_index_ = next_write_index_; |
+ input->swap(queue_[last_write_index_]); |
kwiberg-webrtc
2015/10/10 10:16:56
See http://en.cppreference.com/w/cpp/concept/Swapp
peah-webrtc
2015/10/12 13:01:07
Thanks!!!! Does this look as what you intended?
kwiberg-webrtc
2015/10/12 14:05:48
Yes.
peah-webrtc
2015/10/13 11:56:11
Acknowledged.
|
+ |
+ return true; |
+ } |
+ |
+ // Removes a chunk of data from the queue in a thread safe manner. |
+ // Returns false if the queue is empty, and true if not. |
hlundin-webrtc
2015/10/13 06:37:57
Again, clarify that false is returned if the queue
peah-webrtc
2015/10/13 11:56:11
Good point! I added some more documentation regard
|
+ bool Remove(T* const output) { |
+ rtc::CritScope cs(&crit_queue_); |
+ |
+ // Early return for empty queue. |
+ if (last_read_index_ == last_write_index_) |
+ return false; |
+ |
+ last_read_index_ = |
the sun
2015/10/09 12:09:55
Use modulo instead of conditional
kwiberg-webrtc
2015/10/10 10:16:56
I'd also have used a conditional, because mod can
peah-webrtc
2015/10/12 13:01:07
Great investigation! Cool!!! I'll keep the conditi
|
+ (last_read_index_ < (queue_.size() - 1) ? last_read_index_ + 1 : 0); |
+ output->swap(queue_[last_read_index_]); |
+ |
+ return true; |
+ } |
+ |
+ size_t EmptyQueue() { |
the sun
2015/10/09 12:09:55
1. Is this really needed in the API?
should retur
kwiberg-webrtc
2015/10/10 10:16:56
+1 to what Fredrik said. The best thing would be i
peah-webrtc
2015/10/12 13:01:07
Agree, I removed the function.
peah-webrtc
2015/10/12 13:01:08
Done.
|
+ rtc::CritScope cs(&crit_queue_); |
+ if (last_read_index_ == last_write_index_) |
+ return false; |
+ } |
+ |
+ size_t FullQueue() { |
the sun
2015/10/09 12:09:54
1. Is this really needed in the API?
bool, const,
kwiberg-webrtc
2015/10/10 10:16:56
+1
peah-webrtc
2015/10/12 13:01:08
Agree, I removed the function.
peah-webrtc
2015/10/12 13:01:08
Done.
|
+ rtc::CritScope cs(&crit_queue_); |
+ size_t next_write_index_ = |
the sun
2015/10/09 12:09:54
Move to internal CheckIfFull() utility
peah-webrtc
2015/10/12 13:01:08
I removed that functionality, as it with the curre
|
+ (last_write_index_ < (queue_.size() - 1) ? last_write_index_ + 1 : 0); |
+ if (next_write_index_ == last_read_index_) |
+ return false; |
+ } |
+ |
+ private: |
+ std::vector<T> queue_; |
kwiberg-webrtc
2015/10/10 10:16:56
GUARDED_BY?
peah-webrtc
2015/10/12 13:01:08
Done.
|
+ size_t last_write_index_ GUARDED_BY(crit_queue_); |
+ size_t last_read_index_ GUARDED_BY(crit_queue_); |
+ rtc::CriticalSection crit_queue_; |
the sun
2015/10/09 12:09:54
Make mutable
kwiberg-webrtc
2015/10/10 10:16:55
This class is unusable if it's const, so I don't s
The Sun (google.com)
2015/10/10 14:00:54
That's to make it possible for IsEmpty and IsFull
kwiberg-webrtc
2015/10/10 17:48:40
Yeah, OK. No caller is going to make use of that,
peah-webrtc
2015/10/12 13:01:08
Agree to both of you! I removed the IsEmpty and Is
|
+ |
+ RTC_DISALLOW_COPY_AND_ASSIGN(SwappedNonBlockingQueue); |
+}; |
+ |
+} // namespace webrtc |
+ |
+#endif // WEBRTC_MODULES_AUDIO_PROCESSING_SWAPPED_NONBLOCKING_QUEUE_H_ |