| OLD | NEW |
| 1 #include <gtest/gtest.h> | 1 #include <gtest/gtest.h> |
| 2 #include <queue> | 2 #include <queue> |
| 3 #include <vector> | 3 #include <vector> |
| 4 | 4 |
| 5 #include "../src/Thread.h" | 5 #include "../src/Thread.h" |
| 6 | 6 |
| 7 namespace | 7 namespace |
| 8 { | 8 { |
| 9 #ifndef WIN32 | |
| 10 void Sleep(const int millis) | |
| 11 { | |
| 12 usleep(millis * 1000); | |
| 13 } | |
| 14 #endif | |
| 15 | |
| 16 class Mock : public AdblockPlus::Thread | 9 class Mock : public AdblockPlus::Thread |
| 17 { | 10 { |
| 18 public: | 11 public: |
| 19 int timesCalled; | 12 int timesCalled; |
| 20 AdblockPlus::Mutex mutex; | 13 AdblockPlus::Mutex mutex; |
| 21 | 14 |
| 22 Mock() : timesCalled(0) | 15 Mock() : timesCalled(0) |
| 23 { | 16 { |
| 24 } | 17 } |
| 25 | 18 |
| 26 void Run() | 19 void Run() |
| 27 { | 20 { |
| 28 Sleep(5); | 21 AdblockPlus::Sleep(5); |
| 29 mutex.Lock(); | 22 AdblockPlus::Lock lock(mutex); |
| 30 timesCalled++; | 23 timesCalled++; |
| 31 mutex.Unlock(); | |
| 32 } | 24 } |
| 33 }; | 25 }; |
| 34 | 26 |
| 35 class LockingMock : public AdblockPlus::Thread | 27 class LockingMock : public AdblockPlus::Thread |
| 36 { | 28 { |
| 37 public: | 29 public: |
| 38 bool working; | 30 bool working; |
| 39 | 31 |
| 40 LockingMock(const std::string& name, std::vector<std::string>& log, | 32 LockingMock(const std::string& name, std::vector<std::string>& log, |
| 41 AdblockPlus::Mutex& logMutex) | 33 AdblockPlus::Mutex& logMutex) |
| 42 : name(name), log(log), logMutex(logMutex) | 34 : name(name), log(log), logMutex(logMutex) |
| 43 { | 35 { |
| 44 } | 36 } |
| 45 | 37 |
| 46 void Run() | 38 void Run() |
| 47 { | 39 { |
| 48 logMutex.Lock(); | 40 AdblockPlus::Lock lock(logMutex); |
| 49 log.push_back(name); | 41 log.push_back(name); |
| 50 logMutex.Unlock(); | |
| 51 } | 42 } |
| 52 | 43 |
| 53 private: | 44 private: |
| 54 const std::string name; | 45 const std::string name; |
| 55 std::vector<std::string>& log; | 46 std::vector<std::string>& log; |
| 56 AdblockPlus::Mutex& logMutex; | 47 AdblockPlus::Mutex& logMutex; |
| 57 }; | 48 }; |
| 58 | 49 |
| 59 class Enqueuer : public AdblockPlus::Thread | 50 class Enqueuer : public AdblockPlus::Thread |
| 60 { | 51 { |
| 61 public: | 52 public: |
| 62 Enqueuer(std::queue<int>& queue, AdblockPlus::Mutex& queueMutex, | 53 Enqueuer(std::queue<int>& queue, AdblockPlus::Mutex& queueMutex, |
| 63 AdblockPlus::ConditionVariable& notEmpty) | 54 AdblockPlus::ConditionVariable& notEmpty) |
| 64 : queue(queue), queueMutex(queueMutex), notEmpty(notEmpty) | 55 : queue(queue), queueMutex(queueMutex), notEmpty(notEmpty) |
| 65 { | 56 { |
| 66 } | 57 } |
| 67 | 58 |
| 68 void Run() | 59 void Run() |
| 69 { | 60 { |
| 70 queueMutex.Lock(); | 61 AdblockPlus::Lock lock(queueMutex); |
| 71 queue.push(1); | 62 queue.push(1); |
| 72 notEmpty.Signal(); | 63 notEmpty.Signal(); |
| 73 queueMutex.Unlock(); | |
| 74 } | 64 } |
| 75 | 65 |
| 76 private: | 66 private: |
| 77 std::queue<int>& queue; | 67 std::queue<int>& queue; |
| 78 AdblockPlus::Mutex& queueMutex; | 68 AdblockPlus::Mutex& queueMutex; |
| 79 AdblockPlus::ConditionVariable& notEmpty; | 69 AdblockPlus::ConditionVariable& notEmpty; |
| 80 }; | 70 }; |
| 81 | 71 |
| 82 class Dequeuer : public AdblockPlus::Thread | 72 class Dequeuer : public AdblockPlus::Thread |
| 83 { | 73 { |
| 84 public: | 74 public: |
| 85 Dequeuer(std::queue<int>& queue, AdblockPlus::Mutex& queueMutex, | 75 Dequeuer(std::queue<int>& queue, AdblockPlus::Mutex& queueMutex, |
| 86 AdblockPlus::ConditionVariable& notEmpty) | 76 AdblockPlus::ConditionVariable& notEmpty) |
| 87 : queue(queue), queueMutex(queueMutex), notEmpty(notEmpty) | 77 : queue(queue), queueMutex(queueMutex), notEmpty(notEmpty) |
| 88 { | 78 { |
| 89 } | 79 } |
| 90 | 80 |
| 91 void Run() | 81 void Run() |
| 92 { | 82 { |
| 93 queueMutex.Lock(); | 83 AdblockPlus::Lock lock(queueMutex); |
| 94 if (!queue.size()) | 84 if (!queue.size()) |
| 95 notEmpty.Wait(queueMutex); | 85 notEmpty.Wait(queueMutex); |
| 96 queue.pop(); | 86 queue.pop(); |
| 97 queueMutex.Unlock(); | |
| 98 } | 87 } |
| 99 | 88 |
| 100 private: | 89 private: |
| 101 std::queue<int>& queue; | 90 std::queue<int>& queue; |
| 102 AdblockPlus::Mutex& queueMutex; | 91 AdblockPlus::Mutex& queueMutex; |
| 103 AdblockPlus::ConditionVariable& notEmpty; | 92 AdblockPlus::ConditionVariable& notEmpty; |
| 104 }; | 93 }; |
| 105 } | 94 } |
| 106 | 95 |
| 107 TEST(ThreadTest, Run) | 96 TEST(ThreadTest, Run) |
| 108 { | 97 { |
| 109 Mock mock; | 98 Mock mock; |
| 110 ASSERT_EQ(0, mock.timesCalled); | 99 ASSERT_EQ(0, mock.timesCalled); |
| 111 mock.Start(); | 100 mock.Start(); |
| 112 mock.mutex.Lock(); | 101 mock.mutex.Lock(); |
| 113 ASSERT_EQ(0, mock.timesCalled); | 102 ASSERT_EQ(0, mock.timesCalled); |
| 114 mock.mutex.Unlock(); | 103 mock.mutex.Unlock(); |
| 115 mock.Join(); | 104 mock.Join(); |
| 116 ASSERT_EQ(1, mock.timesCalled); | 105 ASSERT_EQ(1, mock.timesCalled); |
| 117 } | 106 } |
| 118 | 107 |
| 119 TEST(ThreadTest, Mutex) | 108 TEST(ThreadTest, Mutex) |
| 120 { | 109 { |
| 121 std::vector<std::string> log; | 110 std::vector<std::string> log; |
| 122 AdblockPlus::Mutex logMutex; | 111 AdblockPlus::Mutex logMutex; |
| 123 LockingMock mock1("mock1", log, logMutex); | 112 LockingMock mock1("mock1", log, logMutex); |
| 124 LockingMock mock2("mock2", log, logMutex); | 113 LockingMock mock2("mock2", log, logMutex); |
| 125 mock1.Start(); | 114 mock1.Start(); |
| 126 Sleep(5); | 115 AdblockPlus::Sleep(5); |
| 127 mock2.Start(); | 116 mock2.Start(); |
| 128 mock1.Join(); | 117 mock1.Join(); |
| 129 mock2.Join(); | 118 mock2.Join(); |
| 130 ASSERT_EQ("mock1", log[0]); | 119 ASSERT_EQ("mock1", log[0]); |
| 131 ASSERT_EQ("mock2", log[1]); | 120 ASSERT_EQ("mock2", log[1]); |
| 132 } | 121 } |
| 133 | 122 |
| 134 TEST(ThreadTest, ConditionVariable) | 123 TEST(ThreadTest, ConditionVariable) |
| 135 { | 124 { |
| 136 std::queue<int> queue; | 125 std::queue<int> queue; |
| 137 AdblockPlus::Mutex queueMutex; | 126 AdblockPlus::Mutex queueMutex; |
| 138 AdblockPlus::ConditionVariable notEmpty; | 127 AdblockPlus::ConditionVariable notEmpty; |
| 139 Dequeuer dequeuer(queue, queueMutex, notEmpty); | 128 Dequeuer dequeuer(queue, queueMutex, notEmpty); |
| 140 Enqueuer enqueuer(queue, queueMutex, notEmpty); | 129 Enqueuer enqueuer(queue, queueMutex, notEmpty); |
| 141 dequeuer.Start(); | 130 dequeuer.Start(); |
| 142 Sleep(5); | 131 AdblockPlus::Sleep(5); |
| 143 enqueuer.Start(); | 132 enqueuer.Start(); |
| 144 enqueuer.Join(); | 133 enqueuer.Join(); |
| 145 dequeuer.Join(); | 134 dequeuer.Join(); |
| 146 ASSERT_EQ(0, queue.size()); | 135 ASSERT_EQ(0, queue.size()); |
| 147 } | 136 } |
| OLD | NEW |