| Index: test/Thread.cpp |
| =================================================================== |
| --- a/test/Thread.cpp |
| +++ b/test/Thread.cpp |
| @@ -1,5 +1,6 @@ |
| #include <gtest/gtest.h> |
| #include <queue> |
| +#include <vector> |
| #include "../src/Thread.h" |
| @@ -16,6 +17,7 @@ |
| { |
| public: |
| int timesCalled; |
| + AdblockPlus::Thread::Mutex mutex; |
| Mock() : timesCalled(0) |
| { |
| @@ -23,7 +25,10 @@ |
| void Run() |
| { |
| + Sleep(5); |
| + mutex.Lock(); |
| timesCalled++; |
| + mutex.Unlock(); |
| } |
| }; |
| @@ -32,71 +37,69 @@ |
| public: |
| bool working; |
| - LockingMock(AdblockPlus::Thread::Mutex& mutex, const int millisToSleep) |
| - : mutex(mutex), millisToSleep(millisToSleep) |
| + LockingMock(const std::string& name, std::vector<std::string>& log, |
| + AdblockPlus::Thread::Mutex& logMutex) |
| + : name(name), log(log), logMutex(logMutex) |
| { |
| } |
| void Run() |
| { |
| - mutex.Lock(); |
| - working = true; |
| - Sleep(millisToSleep); |
| - working = false; |
| - mutex.Unlock(); |
| + logMutex.Lock(); |
| + log.push_back(name); |
| + logMutex.Unlock(); |
| } |
| private: |
| - AdblockPlus::Thread::Mutex& mutex; |
| - int millisToSleep; |
| + const std::string name; |
| + std::vector<std::string>& log; |
| + AdblockPlus::Thread::Mutex& logMutex; |
| }; |
| class Enqueuer : public AdblockPlus::Thread |
| { |
| public: |
| - Enqueuer(std::queue<int>& queue, AdblockPlus::Thread::Mutex& mutex, |
| + Enqueuer(std::queue<int>& queue, AdblockPlus::Thread::Mutex& queueMutex, |
| AdblockPlus::Thread::Condition& notEmpty) |
| - : queue(queue), mutex(mutex), notEmpty(notEmpty) |
| + : queue(queue), queueMutex(queueMutex), notEmpty(notEmpty) |
| { |
| } |
| void Run() |
| { |
| - Sleep(5); |
| - mutex.Lock(); |
| + queueMutex.Lock(); |
| queue.push(1); |
| - Sleep(10); |
| notEmpty.Signal(); |
| - mutex.Unlock(); |
| + queueMutex.Unlock(); |
| } |
| private: |
| std::queue<int>& queue; |
| - AdblockPlus::Thread::Mutex& mutex; |
| + AdblockPlus::Thread::Mutex& queueMutex; |
| AdblockPlus::Thread::Condition& notEmpty; |
| }; |
| class Dequeuer : public AdblockPlus::Thread |
| { |
| public: |
| - Dequeuer(std::queue<int>& queue, AdblockPlus::Thread::Mutex& mutex, |
| + Dequeuer(std::queue<int>& queue, AdblockPlus::Thread::Mutex& queueMutex, |
| AdblockPlus::Thread::Condition& notEmpty) |
| - : queue(queue), mutex(mutex), notEmpty(notEmpty) |
| + : queue(queue), queueMutex(queueMutex), notEmpty(notEmpty) |
| { |
| } |
| void Run() |
| { |
| - mutex.Lock(); |
| + queueMutex.Lock(); |
| if (!queue.size()) |
| - notEmpty.Wait(mutex); |
| + notEmpty.Wait(queueMutex); |
| queue.pop(); |
| - mutex.Unlock(); |
| + queueMutex.Unlock(); |
| } |
| private: |
| std::queue<int>& queue; |
| - AdblockPlus::Thread::Mutex& mutex; |
| + AdblockPlus::Thread::Mutex& queueMutex; |
| AdblockPlus::Thread::Condition& notEmpty; |
| }; |
| } |
| @@ -106,41 +109,39 @@ |
| Mock mock; |
| ASSERT_EQ(0, mock.timesCalled); |
| mock.Start(); |
| + mock.mutex.Lock(); |
| ASSERT_EQ(0, mock.timesCalled); |
| + mock.mutex.Unlock(); |
| mock.Join(); |
| ASSERT_EQ(1, mock.timesCalled); |
| } |
| TEST(ThreadTest, Mutex) |
| { |
| - AdblockPlus::Thread::Mutex mutex; |
| - LockingMock mock1(mutex, 10); |
| - LockingMock mock2(mutex, 20); |
| + std::vector<std::string> log; |
| + AdblockPlus::Thread::Mutex logMutex; |
| + LockingMock mock1("mock1", log, logMutex); |
| + LockingMock mock2("mock2", log, logMutex); |
| mock1.Start(); |
| + Sleep(5); |
| mock2.Start(); |
| - Sleep(5); |
| - ASSERT_TRUE(mock1.working); |
| - ASSERT_FALSE(mock2.working); |
| - Sleep(10); |
| - ASSERT_TRUE(mock2.working); |
| - ASSERT_FALSE(mock1.working); |
| mock1.Join(); |
| mock2.Join(); |
| + ASSERT_EQ("mock1", log[0]); |
| + ASSERT_EQ("mock2", log[1]); |
| } |
| TEST(ThreadTest, ConditionVariable) |
| { |
| std::queue<int> queue; |
| - AdblockPlus::Thread::Mutex mutex; |
| + AdblockPlus::Thread::Mutex queueMutex; |
| AdblockPlus::Thread::Condition notEmpty; |
| - Enqueuer enqueuer(queue, mutex, notEmpty); |
| - Dequeuer dequeuer(queue, mutex, notEmpty); |
| + Dequeuer dequeuer(queue, queueMutex, notEmpty); |
| + Enqueuer enqueuer(queue, queueMutex, notEmpty); |
| + dequeuer.Start(); |
| + Sleep(5); |
| enqueuer.Start(); |
| - dequeuer.Start(); |
| - Sleep(10); |
| - ASSERT_EQ(1u, queue.size()); |
| - Sleep(15); |
| - ASSERT_EQ(0u, queue.size()); |
| enqueuer.Join(); |
| dequeuer.Join(); |
| + ASSERT_EQ(0, queue.size()); |
| } |