Commit cf3f515a authored by Zach Trudo's avatar Zach Trudo Committed by Commit Bot

Add SharedQueue<T>::Swap

SharedQueue was missing Swap from the possible queue commands. Added it.

Bug: chromium:1078512
Change-Id: I507027bf3d77eebe0369050cbf46f58a088df03f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2353404Reviewed-by: default avatarLeonid Baraz <lbaraz@chromium.org>
Commit-Queue: Zach Trudo <zatrudo@google.com>
Cr-Commit-Position: refs/heads/master@{#797867}
parent 42196d50
...@@ -46,6 +46,16 @@ class SharedQueue : public base::RefCountedThreadSafe<SharedQueue<QueueType>> { ...@@ -46,6 +46,16 @@ class SharedQueue : public base::RefCountedThreadSafe<SharedQueue<QueueType>> {
base::BindOnce(&SharedQueue::OnPop, this, std::move(get_pop_cb))); base::BindOnce(&SharedQueue::OnPop, this, std::move(get_pop_cb)));
} }
// Swap will schedule a swap of the |queue_| contents with the provided
// |new_queue|, and send the old contents to the |swap_queue_cb|.
void Swap(base::queue<QueueType> new_queue,
base::OnceCallback<void(base::queue<QueueType>)> swap_queue_cb) {
sequenced_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&SharedQueue::OnSwap, this, std::move(new_queue),
std::move(swap_queue_cb)));
}
protected: protected:
virtual ~SharedQueue() = default; virtual ~SharedQueue() = default;
...@@ -72,6 +82,12 @@ class SharedQueue : public base::RefCountedThreadSafe<SharedQueue<QueueType>> { ...@@ -72,6 +82,12 @@ class SharedQueue : public base::RefCountedThreadSafe<SharedQueue<QueueType>> {
std::move(cb).Run(std::move(item)); std::move(cb).Run(std::move(item));
} }
void OnSwap(base::queue<QueueType> new_queue,
base::OnceCallback<void(base::queue<QueueType>)> swap_queue_cb) {
queue_.swap(new_queue);
std::move(swap_queue_cb).Run(std::move(new_queue));
}
// Used to monitor if the callback is in use or not. // Used to monitor if the callback is in use or not.
base::queue<QueueType> queue_; base::queue<QueueType> queue_;
......
...@@ -37,6 +37,11 @@ class QueueTester { ...@@ -37,6 +37,11 @@ class QueueTester {
base::BindOnce(&QueueTester::PopInternal, base::Unretained(this))); base::BindOnce(&QueueTester::PopInternal, base::Unretained(this)));
} }
void Swap() {
queue_->Swap(base::queue<int>(),
base::BindOnce(&QueueTester::OnSwap, base::Unretained(this)));
}
void PushPop(int value) { void PushPop(int value) {
queue_->Push(value, base::BindOnce(&QueueTester::OnPushPopComplete, queue_->Push(value, base::BindOnce(&QueueTester::OnPushPopComplete,
base::Unretained(this))); base::Unretained(this)));
...@@ -48,6 +53,7 @@ class QueueTester { ...@@ -48,6 +53,7 @@ class QueueTester {
} }
StatusOr<int> pop_result() { return pop_result_; } StatusOr<int> pop_result() { return pop_result_; }
base::queue<int>* swap_result() { return &swap_result_; }
private: private:
void OnPushPopComplete() { Pop(); } void OnPushPopComplete() { Pop(); }
...@@ -59,13 +65,22 @@ class QueueTester { ...@@ -59,13 +65,22 @@ class QueueTester {
void OnPopComplete(StatusOr<int> pop_result) { void OnPopComplete(StatusOr<int> pop_result) {
pop_result_ = pop_result; pop_result_ = pop_result;
completed_.Signal(); Signal();
}
void OnSwap(base::queue<int> swap_result) {
swap_result_ = swap_result;
Signal();
} }
void Signal() { completed_.Signal(); }
scoped_refptr<SharedQueue<int>> queue_; scoped_refptr<SharedQueue<int>> queue_;
scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner_; scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner_;
base::WaitableEvent completed_; base::WaitableEvent completed_;
StatusOr<int> pop_result_; StatusOr<int> pop_result_;
base::queue<int> swap_result_;
}; };
TEST(SharedQueueTest, SuccessfulPushPop) { TEST(SharedQueueTest, SuccessfulPushPop) {
...@@ -107,5 +122,38 @@ TEST(SharedQueueTest, PushOrderMaintained) { ...@@ -107,5 +122,38 @@ TEST(SharedQueueTest, PushOrderMaintained) {
} }
} }
TEST(SharedQueueTest, SwapSuccessful) {
base::test::TaskEnvironment task_envrionment{
base::test::TaskEnvironment::TimeSource::MOCK_TIME};
std::vector<int> kExpectedValues = {1, 1, 2, 3, 5, 8, 13, 21};
auto queue = SharedQueue<int>::Create();
QueueTester queue_tester(queue);
for (auto value : kExpectedValues) {
queue_tester.Push(value);
}
queue_tester.Swap();
queue_tester.Wait();
auto* swapped_queue = queue_tester.swap_result();
for (auto value : kExpectedValues) {
EXPECT_EQ(swapped_queue->front(), value);
swapped_queue->pop();
}
// Test to ensure the SharedQueue is empty.
queue_tester.Pop();
queue_tester.Wait();
auto pop_result = queue_tester.pop_result();
EXPECT_FALSE(pop_result.ok());
EXPECT_EQ(pop_result.status().error_code(), error::OUT_OF_RANGE);
}
} // namespace } // namespace
} // namespace reporting } // namespace reporting
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment