Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Delta Between Two Patch Sets: test/Thread.cpp

Issue 10026001: Cross-platform thread primitives (Closed)
Left Patch Set: Renamed thread to nativeThread, made the tests more robust Created April 3, 2013, 4:23 p.m.
Right Patch Set: Improve mutex test Created April 4, 2013, 7:27 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « no previous file | no next file » | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
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 9 #ifndef WIN32
10 void Sleep(const int millis) 10 void Sleep(const int millis)
11 { 11 {
12 usleep(millis * 1000); 12 usleep(millis * 1000);
13 } 13 }
14 #endif 14 #endif
15 15
16 class Mock : public AdblockPlus::Thread 16 class Mock : public AdblockPlus::Thread
17 { 17 {
18 public: 18 public:
19 int timesCalled; 19 int timesCalled;
20 AdblockPlus::Thread::Mutex mutex; 20 AdblockPlus::Mutex mutex;
21 21
22 Mock() : timesCalled(0) 22 Mock() : timesCalled(0)
23 { 23 {
24 } 24 }
25 25
26 void Run() 26 void Run()
27 { 27 {
28 Sleep(5); 28 Sleep(5);
29 mutex.Lock(); 29 mutex.Lock();
30 timesCalled++; 30 timesCalled++;
31 mutex.Unlock(); 31 mutex.Unlock();
32 } 32 }
33 }; 33 };
34 34
35 class LockingMock : public AdblockPlus::Thread 35 class LockingMock : public AdblockPlus::Thread
36 { 36 {
37 public: 37 public:
38 bool working; 38 bool working;
39 39
40 LockingMock(const std::string& name, std::vector<std::string>& log, 40 LockingMock(std::vector<std::string>& log, AdblockPlus::Mutex& logMutex)
41 AdblockPlus::Thread::Mutex& logMutex) 41 : log(log), logMutex(logMutex)
42 : name(name), log(log), logMutex(logMutex)
43 { 42 {
44 } 43 }
45 44
46 void Run() 45 void Run()
47 { 46 {
48 logMutex.Lock(); 47 logMutex.Lock();
49 log.push_back(name); 48 log.push_back("started");
49 Sleep(5);
50 log.push_back("ended");
50 logMutex.Unlock(); 51 logMutex.Unlock();
51 } 52 }
52 53
53 private: 54 private:
54 const std::string name; 55 const std::string name;
55 std::vector<std::string>& log; 56 std::vector<std::string>& log;
56 AdblockPlus::Thread::Mutex& logMutex; 57 AdblockPlus::Mutex& logMutex;
57 }; 58 };
58 59
59 class Enqueuer : public AdblockPlus::Thread 60 class Enqueuer : public AdblockPlus::Thread
60 { 61 {
61 public: 62 public:
62 Enqueuer(std::queue<int>& queue, AdblockPlus::Thread::Mutex& queueMutex, 63 Enqueuer(std::queue<int>& queue, AdblockPlus::Mutex& queueMutex,
63 AdblockPlus::Thread::Condition& notEmpty) 64 AdblockPlus::ConditionVariable& notEmpty)
64 : queue(queue), queueMutex(queueMutex), notEmpty(notEmpty) 65 : queue(queue), queueMutex(queueMutex), notEmpty(notEmpty)
65 { 66 {
66 } 67 }
67 68
68 void Run() 69 void Run()
69 { 70 {
70 queueMutex.Lock(); 71 queueMutex.Lock();
71 queue.push(1); 72 queue.push(1);
72 notEmpty.Signal(); 73 notEmpty.Signal();
73 queueMutex.Unlock(); 74 queueMutex.Unlock();
74 } 75 }
75 76
76 private: 77 private:
77 std::queue<int>& queue; 78 std::queue<int>& queue;
78 AdblockPlus::Thread::Mutex& queueMutex; 79 AdblockPlus::Mutex& queueMutex;
79 AdblockPlus::Thread::Condition& notEmpty; 80 AdblockPlus::ConditionVariable& notEmpty;
80 }; 81 };
81 82
82 class Dequeuer : public AdblockPlus::Thread 83 class Dequeuer : public AdblockPlus::Thread
83 { 84 {
84 public: 85 public:
85 Dequeuer(std::queue<int>& queue, AdblockPlus::Thread::Mutex& queueMutex, 86 Dequeuer(std::queue<int>& queue, AdblockPlus::Mutex& queueMutex,
86 AdblockPlus::Thread::Condition& notEmpty) 87 AdblockPlus::ConditionVariable& notEmpty)
87 : queue(queue), queueMutex(queueMutex), notEmpty(notEmpty) 88 : queue(queue), queueMutex(queueMutex), notEmpty(notEmpty)
88 { 89 {
89 } 90 }
90 91
91 void Run() 92 void Run()
92 { 93 {
93 queueMutex.Lock(); 94 queueMutex.Lock();
94 if (!queue.size()) 95 if (!queue.size())
95 notEmpty.Wait(queueMutex); 96 notEmpty.Wait(queueMutex);
96 queue.pop(); 97 queue.pop();
97 queueMutex.Unlock(); 98 queueMutex.Unlock();
98 } 99 }
99 100
100 private: 101 private:
101 std::queue<int>& queue; 102 std::queue<int>& queue;
102 AdblockPlus::Thread::Mutex& queueMutex; 103 AdblockPlus::Mutex& queueMutex;
103 AdblockPlus::Thread::Condition& notEmpty; 104 AdblockPlus::ConditionVariable& notEmpty;
104 }; 105 };
105 } 106 }
106 107
107 TEST(ThreadTest, Run) 108 TEST(ThreadTest, Run)
108 { 109 {
109 Mock mock; 110 Mock mock;
110 ASSERT_EQ(0, mock.timesCalled); 111 ASSERT_EQ(0, mock.timesCalled);
111 mock.Start(); 112 mock.Start();
112 mock.mutex.Lock(); 113 mock.mutex.Lock();
113 ASSERT_EQ(0, mock.timesCalled); 114 ASSERT_EQ(0, mock.timesCalled);
114 mock.mutex.Unlock(); 115 mock.mutex.Unlock();
115 mock.Join(); 116 mock.Join();
116 ASSERT_EQ(1, mock.timesCalled); 117 ASSERT_EQ(1, mock.timesCalled);
117 } 118 }
118 119
119 TEST(ThreadTest, Mutex) 120 TEST(ThreadTest, Mutex)
120 { 121 {
121 std::vector<std::string> log; 122 std::vector<std::string> log;
122 AdblockPlus::Thread::Mutex logMutex; 123 AdblockPlus::Mutex logMutex;
123 LockingMock mock1("mock1", log, logMutex); 124 LockingMock mock1(log, logMutex);
124 LockingMock mock2("mock2", log, logMutex); 125 LockingMock mock2(log, logMutex);
125 mock1.Start(); 126 mock1.Start();
126 Sleep(5);
127 mock2.Start(); 127 mock2.Start();
128 mock1.Join(); 128 mock1.Join();
129 mock2.Join(); 129 mock2.Join();
130 ASSERT_EQ("mock1", log[0]); 130 ASSERT_EQ("started", log[0]);
131 ASSERT_EQ("mock2", log[1]); 131 ASSERT_EQ("ended", log[1]);
132 ASSERT_EQ("started", log[2]);
133 ASSERT_EQ("ended", log[3]);
132 } 134 }
133 135
134 TEST(ThreadTest, ConditionVariable) 136 TEST(ThreadTest, ConditionVariable)
135 { 137 {
136 std::queue<int> queue; 138 std::queue<int> queue;
137 AdblockPlus::Thread::Mutex queueMutex; 139 AdblockPlus::Mutex queueMutex;
138 AdblockPlus::Thread::Condition notEmpty; 140 AdblockPlus::ConditionVariable notEmpty;
139 Dequeuer dequeuer(queue, queueMutex, notEmpty); 141 Dequeuer dequeuer(queue, queueMutex, notEmpty);
140 Enqueuer enqueuer(queue, queueMutex, notEmpty); 142 Enqueuer enqueuer(queue, queueMutex, notEmpty);
141 dequeuer.Start(); 143 dequeuer.Start();
142 Sleep(5); 144 Sleep(5);
143 enqueuer.Start(); 145 enqueuer.Start();
144 enqueuer.Join(); 146 enqueuer.Join();
145 dequeuer.Join(); 147 dequeuer.Join();
146 ASSERT_EQ(0, queue.size()); 148 ASSERT_EQ(0, queue.size());
147 } 149 }
LEFTRIGHT
« no previous file | no next file » | Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Toggle Comments ('s')

Powered by Google App Engine
This is Rietveld