1//
2// ConditionTest.cpp
3//
4// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
5// and Contributors.
6//
7// SPDX-License-Identifier: BSL-1.0
8//
9
10
11#include "ConditionTest.h"
12#include "Poco/CppUnit/TestCaller.h"
13#include "Poco/CppUnit/TestSuite.h"
14#include "Poco/Thread.h"
15#include "Poco/Runnable.h"
16#include "Poco/Condition.h"
17#include "Poco/Mutex.h"
18#include "Poco/Exception.h"
19
20
21using Poco::Thread;
22using Poco::Runnable;
23using Poco::Condition;
24using Poco::Mutex;
25using Poco::TimeoutException;
26
27
28namespace
29{
30 class WaitRunnable: public Runnable
31 {
32 public:
33 WaitRunnable(Condition& cond, Mutex& mutex):
34 _ran(false),
35 _cond(cond),
36 _mutex(mutex)
37 {
38 }
39
40 void run()
41 {
42 _mutex.lock();
43 _cond.wait(_mutex);
44 _mutex.unlock();
45 _ran = true;
46 }
47
48 bool ran() const
49 {
50 return _ran;
51 }
52
53 private:
54 bool _ran;
55 Condition& _cond;
56 Mutex& _mutex;
57 };
58
59 class TryWaitRunnable: public Runnable
60 {
61 public:
62 TryWaitRunnable(Condition& cond, Mutex& mutex):
63 _ran(false),
64 _cond(cond),
65 _mutex(mutex)
66 {
67 }
68
69 void run()
70 {
71 _mutex.lock();
72 if (_cond.tryWait(_mutex, 10000))
73 {
74 _ran = true;
75 }
76 _mutex.unlock();
77 }
78
79 bool ran() const
80 {
81 return _ran;
82 }
83
84 private:
85 bool _ran;
86 Condition& _cond;
87 Mutex& _mutex;
88 };
89
90}
91
92
93ConditionTest::ConditionTest(const std::string& rName): CppUnit::TestCase(rName)
94{
95}
96
97
98ConditionTest::~ConditionTest()
99{
100}
101
102
103void ConditionTest::testSignal()
104{
105 Condition cond;
106 Mutex mtx;
107 WaitRunnable r1(cond, mtx);
108 WaitRunnable r2(cond, mtx);
109
110 Thread t1;
111 Thread t2;
112
113 t1.start(r1);
114 Thread::sleep(200);
115 t2.start(r2);
116
117 assertTrue (!r1.ran());
118 assertTrue (!r2.ran());
119
120 cond.signal();
121
122 t1.join();
123 assertTrue (r1.ran());
124
125 assertTrue (!t2.tryJoin(200));
126
127 cond.signal();
128
129 t2.join();
130
131 assertTrue (r2.ran());
132}
133
134
135void ConditionTest::testBroadcast()
136{
137 Condition cond;
138 Mutex mtx;
139 WaitRunnable r1(cond, mtx);
140 WaitRunnable r2(cond, mtx);
141 TryWaitRunnable r3(cond, mtx);
142
143 Thread t1;
144 Thread t2;
145 Thread t3;
146
147 t1.start(r1);
148 Thread::sleep(200);
149 t2.start(r2);
150 Thread::sleep(200);
151 t3.start(r3);
152
153 assertTrue (!r1.ran());
154 assertTrue (!r2.ran());
155 assertTrue (!r3.ran());
156
157 cond.signal();
158 t1.join();
159
160 assertTrue (r1.ran());
161 assertTrue (!t2.tryJoin(500));
162 assertTrue (!t3.tryJoin(500));
163
164 cond.broadcast();
165
166 t2.join();
167 t3.join();
168
169 assertTrue (r2.ran());
170 assertTrue (r3.ran());
171}
172
173
174void ConditionTest::setUp()
175{
176}
177
178
179void ConditionTest::tearDown()
180{
181}
182
183
184CppUnit::Test* ConditionTest::suite()
185{
186 CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("ConditionTest");
187
188 CppUnit_addTest(pSuite, ConditionTest, testSignal);
189 CppUnit_addTest(pSuite, ConditionTest, testBroadcast);
190
191 return pSuite;
192}
193