Go to the documentation of this file.00001
00012
00013
00014
00015
00016
00017 #ifndef Condition_cpp
00018 #define Condition_cpp
00019
00020 #include <cppunit/ui/text/TestRunner.h>
00021 #include <cppunit/TextOutputter.h>
00022 #include <cppunit/extensions/TestFactoryRegistry.h>
00023 #include <cppunit/extensions/HelperMacros.h>
00024 #include <cppunit/TestAssert.h>
00025
00026 #include <coil/Condition.h>
00027 #include <coil/Mutex.h>
00028 #include <coil/Guard.h>
00029 #include <coil/Task.h>
00030 #include <coil/Async.h>
00031 #include <coil/Time.h>
00032 #include <coil/TimeValue.h>
00033
00034 typedef coil::Guard<coil::Mutex> Guard;
00035
00036 class A
00037 {
00038 public:
00039 A(coil::Condition<coil::Mutex>& cond, coil::Mutex& mutex)
00040 : m_cond(cond), m_mutex(mutex) {}
00041 void signal(int usec)
00042 {
00043 coil::usleep(usec);
00044 m_mutex.lock();
00045 m_cond.signal();
00046 m_mutex.unlock();
00047 }
00048 coil::Condition<coil::Mutex>& m_cond;
00049 coil::Mutex& m_mutex;
00050 };
00051
00056 namespace Condition
00057 {
00058
00062 class ConditionCheckTask : public coil::Task
00063 {
00064 public:
00065 ConditionCheckTask() : id(0) { }
00066 ConditionCheckTask(coil::Mutex & aMutex,
00067 coil::Condition<coil::Mutex> & aCondition, int anId)
00068 : mutex(&aMutex), cond(&aCondition), id(anId)
00069 {
00070
00071 }
00072
00073 virtual ~ConditionCheckTask()
00074 {
00075 };
00076
00077 virtual int svc()
00078 {
00079 Guard guard(*mutex);
00080
00081 cond->wait();
00082 ConditionStatus += id;
00083
00084 return ConditionStatus;
00085 }
00089 static void resteStatus() { ConditionStatus = 0; }
00093 static int getStatus() { return ConditionStatus; }
00094 private:
00095
00096 coil::Mutex * mutex;
00097 coil::Condition<coil::Mutex> * cond;
00098 int id;
00099 static int ConditionStatus;
00100 };
00101
00102 int ConditionCheckTask::ConditionStatus(0);
00103
00104
00105 class ConditionTests
00106 : public CppUnit::TestFixture
00107 {
00108 CPPUNIT_TEST_SUITE(ConditionTests);
00109 CPPUNIT_TEST(test_Condition_wait_and_signal);
00110 CPPUNIT_TEST(test_Condition_wait_and_broadcast);
00111 CPPUNIT_TEST(test_Condition_wait_with_time);
00112 CPPUNIT_TEST_SUITE_END();
00113
00114 private:
00115 coil::Mutex * mu;
00116
00117 public:
00121 ConditionTests()
00122 {
00123 }
00124
00128 ~ConditionTests()
00129 {
00130 }
00131
00132
00136 virtual void setUp()
00137 {
00138 mu = new coil::Mutex;
00139 }
00140
00144 virtual void tearDown()
00145 {
00146 delete mu;
00147 }
00148
00149
00150
00154 void test_Condition_wait_and_signal()
00155 {
00156 coil::Mutex mu1;
00157 coil::Condition<coil::Mutex> cond1(mu1);
00158 coil::Mutex mu2;
00159 coil::Condition<coil::Mutex> cond2(mu2);
00160 int id1(0x02);
00161 int id2(0x08);
00162
00163 ConditionCheckTask::resteStatus();
00164 ConditionCheckTask cct1(mu1, cond1, id1);
00165 ConditionCheckTask cct2(mu1, cond1, id2);
00166
00167 cct1.activate();
00168 cct2.activate();
00169
00170 coil::usleep(10000);
00171
00172 CPPUNIT_ASSERT_EQUAL(0x00, ConditionCheckTask::getStatus());
00173
00174 {
00175 Guard guard(mu1);
00176
00177 cond1.signal();
00178
00179 }
00180
00181 coil::usleep(10000);
00182
00183 CPPUNIT_ASSERT_EQUAL(id1, ConditionCheckTask::getStatus());
00184
00185 {
00186 Guard guard(mu1);
00187
00188 cond1.signal();
00189
00190 }
00191
00192 coil::usleep(10000);
00193
00194 CPPUNIT_ASSERT_EQUAL(id1 + id2, ConditionCheckTask::getStatus());
00195
00196
00197
00198 }
00199
00203 void test_Condition_wait_and_broadcast()
00204 {
00205 coil::Condition<coil::Mutex> cd(*mu);
00206 coil::Mutex mu2;
00207 coil::Condition<coil::Mutex> cond2(mu2);
00208
00209 ConditionCheckTask::resteStatus();
00210 ConditionCheckTask cct6(*mu, cd, 0x20);
00211 ConditionCheckTask cct5(*mu, cd, 0x10);
00212 ConditionCheckTask cct4(*mu, cd, 0x08);
00213 ConditionCheckTask cct3(*mu, cd, 0x04);
00214 ConditionCheckTask cct2(*mu, cd, 0x02);
00215 ConditionCheckTask cct1(*mu, cd, 0x01);
00216
00217 cct6.activate();
00218 cct5.activate();
00219 cct4.activate();
00220 cct3.activate();
00221 cct2.activate();
00222 cct1.activate();
00223
00224 CPPUNIT_ASSERT_EQUAL(0, ConditionCheckTask::getStatus());
00225
00226 {
00227 Guard guard(mu2);
00228
00229 cond2.wait(1);
00230
00231 }
00232
00233 {
00234 Guard guard(*mu);
00235
00236 cd.broadcast();
00237
00238 }
00239
00240 {
00241 Guard guard(mu2);
00242
00243 cond2.wait(1);
00244
00245 }
00246
00247 CPPUNIT_ASSERT_EQUAL(0x3f, ConditionCheckTask::getStatus());
00248
00249 CPPUNIT_ASSERT(true);
00250 }
00251
00255 void test_Condition_wait_with_time()
00256 {
00257 int waitSec(2);
00258 coil::Condition<coil::Mutex> cd(*mu);
00259
00260 bool result;
00261 {
00262 Guard guard(*mu);
00263
00264 result = cd.wait(waitSec);
00265
00266 }
00267
00268
00269
00270
00271 CPPUNIT_ASSERT(!result);
00272
00273
00274 A a(cd, *mu);
00275 coil::Async*
00276 invoker(coil::AsyncInvoker(&a,
00277 std::bind2nd(std::mem_fun(&A::signal),
00278 1000000)));
00279 invoker->invoke();
00280 {
00281 Guard guard(*mu);
00282
00283 result = cd.wait(waitSec);
00284
00285 }
00286 invoker->wait();
00287
00288
00289
00290
00291 CPPUNIT_ASSERT(result);
00292 }
00293
00294 };
00295 };
00296
00297
00298
00299
00300 CPPUNIT_TEST_SUITE_REGISTRATION(Condition::ConditionTests);
00301
00302 #ifdef LOCAL_MAIN
00303 int main(int argc, char* argv[])
00304 {
00305 CppUnit::TextUi::TestRunner runner;
00306 runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
00307 CppUnit::Outputter* outputter =
00308 new CppUnit::TextOutputter(&runner.result(), std::cout);
00309 runner.setOutputter(outputter);
00310 bool retcode = runner.run();
00311 return !retcode;
00312 }
00313 #endif // MAIN
00314 #endif // Condition_cpp