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

Side by Side Diff: test/Thread.cpp

Issue 10026001: Cross-platform thread primitives (Closed)
Patch Set: Created March 29, 2013, 5:26 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« src/Thread.cpp ('K') | « src/Thread.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 #include <gtest/gtest.h>
2 #include <queue>
3
4 #include "../src/Thread.h"
5
6 namespace
7 {
8 #ifndef WIN32
9 void Sleep(const int millis)
10 {
11 usleep(millis * 1000);
12 }
13 #endif
14
15 class Mock : public AdblockPlus::Thread
16 {
17 public:
18 int timesCalled;
19
20 Mock() : timesCalled(0)
21 {
22 }
23
24 void Run()
25 {
26 timesCalled++;
Wladimir Palant 2013/04/03 13:14:47 This statement isn't thread-safe, you need a mutex
Felix Dahlke 2013/04/03 16:27:59 I thought that's pretty unlikely here, but fair en
27 }
28 };
29
30 class LockingMock : public AdblockPlus::Thread
31 {
32 public:
33 bool working;
34
35 LockingMock(AdblockPlus::Thread::Mutex& mutex, const int millisToSleep)
36 : mutex(mutex), millisToSleep(millisToSleep)
37 {
38 }
39
40 void Run()
41 {
42 mutex.Lock();
43 working = true;
44 Sleep(millisToSleep);
45 working = false;
46 mutex.Unlock();
47 }
48
49 private:
50 AdblockPlus::Thread::Mutex& mutex;
51 int millisToSleep;
52 };
53
54 class Enqueuer : public AdblockPlus::Thread
55 {
56 public:
57 Enqueuer(std::queue<int>& queue, AdblockPlus::Thread::Mutex& mutex,
58 AdblockPlus::Thread::Condition& notEmpty)
59 : queue(queue), mutex(mutex), notEmpty(notEmpty)
60 {
61 }
62
63 void Run()
64 {
65 Sleep(5);
66 mutex.Lock();
67 queue.push(1);
68 Sleep(10);
69 notEmpty.Signal();
70 mutex.Unlock();
71 }
72
73 private:
74 std::queue<int>& queue;
75 AdblockPlus::Thread::Mutex& mutex;
76 AdblockPlus::Thread::Condition& notEmpty;
77 };
78
79 class Dequeuer : public AdblockPlus::Thread
80 {
81 public:
82 Dequeuer(std::queue<int>& queue, AdblockPlus::Thread::Mutex& mutex,
83 AdblockPlus::Thread::Condition& notEmpty)
84 : queue(queue), mutex(mutex), notEmpty(notEmpty)
85 {
86 }
87
88 void Run()
89 {
90 mutex.Lock();
91 if (!queue.size())
92 notEmpty.Wait(mutex);
93 queue.pop();
94 mutex.Unlock();
95 }
96
97 private:
98 std::queue<int>& queue;
99 AdblockPlus::Thread::Mutex& mutex;
100 AdblockPlus::Thread::Condition& notEmpty;
101 };
102 }
103
104 TEST(ThreadTest, Run)
105 {
106 Mock mock;
107 ASSERT_EQ(0, mock.timesCalled);
108 mock.Start();
109 ASSERT_EQ(0, mock.timesCalled);
Wladimir Palant 2013/04/03 13:14:47 This is a race condition - by the time you check t
Felix Dahlke 2013/04/03 16:27:59 Yes indeed, made it a bit more robust. It's still
110 mock.Join();
111 ASSERT_EQ(1, mock.timesCalled);
112 }
113
114 TEST(ThreadTest, Mutex)
115 {
116 AdblockPlus::Thread::Mutex mutex;
117 LockingMock mock1(mutex, 10);
118 LockingMock mock2(mutex, 20);
119 mock1.Start();
120 mock2.Start();
121 Sleep(5);
122 ASSERT_TRUE(mock1.working);
123 ASSERT_FALSE(mock2.working);
Wladimir Palant 2013/04/03 13:14:47 Please note that Sleep() (both the Windows and the
Felix Dahlke 2013/04/03 16:27:59 Agreed, much more robust that way.
124 Sleep(10);
125 ASSERT_TRUE(mock2.working);
126 ASSERT_FALSE(mock1.working);
127 mock1.Join();
128 mock2.Join();
129 }
130
131 TEST(ThreadTest, ConditionVariable)
132 {
133 std::queue<int> queue;
134 AdblockPlus::Thread::Mutex mutex;
135 AdblockPlus::Thread::Condition notEmpty;
136 Enqueuer enqueuer(queue, mutex, notEmpty);
137 Dequeuer dequeuer(queue, mutex, notEmpty);
138 enqueuer.Start();
139 dequeuer.Start();
140 Sleep(10);
141 ASSERT_EQ(1, queue.size());
Wladimir Palant 2013/04/03 13:14:47 Same flaw here as above.
Felix Dahlke 2013/04/03 16:27:59 Fixed as well.
142 Sleep(15);
143 ASSERT_EQ(0, queue.size());
144 enqueuer.Join();
145 dequeuer.Join();
146 }
OLDNEW
« src/Thread.cpp ('K') | « src/Thread.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld