1*52a38012Sejakowatz /* 2*52a38012Sejakowatz $Id: DestructionTest2.cpp,v 1.1 2002/07/09 12:24:58 ejakowatz Exp $ 3*52a38012Sejakowatz 4*52a38012Sejakowatz This file implements a test class for testing BLocker functionality. 5*52a38012Sejakowatz It tests use cases "Destruction" and "Locking 4". 6*52a38012Sejakowatz 7*52a38012Sejakowatz The test works like the following: 8*52a38012Sejakowatz - the main thread acquires the lock 9*52a38012Sejakowatz - it creates a new thread and sleeps 10*52a38012Sejakowatz - the new thread attempts to acquire the lock but times out 11*52a38012Sejakowatz - the new thread then attempts to acquire the lock again 12*52a38012Sejakowatz - before the new thread times out a second time, the first thread releases 13*52a38012Sejakowatz the lock 14*52a38012Sejakowatz - at this time, the new thread acquires the lock and goes to sleep 15*52a38012Sejakowatz - the first thread attempts to acquire the lock 16*52a38012Sejakowatz - the second thread deletes the lock 17*52a38012Sejakowatz - the first thread is woken up indicating that the lock wasn't acquired. 18*52a38012Sejakowatz 19*52a38012Sejakowatz */ 20*52a38012Sejakowatz 21*52a38012Sejakowatz 22*52a38012Sejakowatz #include "DestructionTest2.h" 23*52a38012Sejakowatz #include "TestSuite.h" 24*52a38012Sejakowatz #include "ThreadedTestCaller.h" 25*52a38012Sejakowatz #include <be/support/Locker.h> 26*52a38012Sejakowatz #include "Locker.h" 27*52a38012Sejakowatz 28*52a38012Sejakowatz // This constant is used to determine the number of microseconds to 29*52a38012Sejakowatz // sleep during major steps of the test. 30*52a38012Sejakowatz 31*52a38012Sejakowatz const bigtime_t SNOOZE_TIME = 200000; 32*52a38012Sejakowatz 33*52a38012Sejakowatz 34*52a38012Sejakowatz /* 35*52a38012Sejakowatz * Method: DestructionTest2<Locker>::DestructionTest2() 36*52a38012Sejakowatz * Descr: This is the only constructor for this test class. 37*52a38012Sejakowatz */ 38*52a38012Sejakowatz 39*52a38012Sejakowatz template<class Locker> 40*52a38012Sejakowatz DestructionTest2<Locker>::DestructionTest2(std::string name, 41*52a38012Sejakowatz bool isBenaphore) : 42*52a38012Sejakowatz LockerTestCase<Locker>(name, isBenaphore) 43*52a38012Sejakowatz { 44*52a38012Sejakowatz } 45*52a38012Sejakowatz 46*52a38012Sejakowatz 47*52a38012Sejakowatz /* 48*52a38012Sejakowatz * Method: DestructionTest2<Locker>::~DestructionTest2() 49*52a38012Sejakowatz * Descr: This is the only destructor for this test class. 50*52a38012Sejakowatz */ 51*52a38012Sejakowatz 52*52a38012Sejakowatz template<class Locker> 53*52a38012Sejakowatz DestructionTest2<Locker>::~DestructionTest2() 54*52a38012Sejakowatz { 55*52a38012Sejakowatz } 56*52a38012Sejakowatz 57*52a38012Sejakowatz 58*52a38012Sejakowatz /* 59*52a38012Sejakowatz * Method: DestructionTest2<Locker>::TestThread1() 60*52a38012Sejakowatz * Descr: This method immediately acquires the lock, sleeps 61*52a38012Sejakowatz * for SNOOZE_TIME and then releases the lock. It sleeps 62*52a38012Sejakowatz * again for SNOOZE_TIME and then tries to re-acquire the 63*52a38012Sejakowatz * lock. By this time, the other thread should have 64*52a38012Sejakowatz * deleted the lock. This acquisition should fail. 65*52a38012Sejakowatz */ 66*52a38012Sejakowatz 67*52a38012Sejakowatz template<class Locker> void DestructionTest2<Locker>::TestThread1(void) 68*52a38012Sejakowatz { 69*52a38012Sejakowatz assert(theLocker->LockWithTimeout(SNOOZE_TIME) == B_OK); 70*52a38012Sejakowatz snooze(SNOOZE_TIME); 71*52a38012Sejakowatz theLocker->Unlock(); 72*52a38012Sejakowatz snooze(SNOOZE_TIME); 73*52a38012Sejakowatz assert(theLocker->LockWithTimeout(SNOOZE_TIME * 10) == B_BAD_SEM_ID); 74*52a38012Sejakowatz } 75*52a38012Sejakowatz 76*52a38012Sejakowatz 77*52a38012Sejakowatz /* 78*52a38012Sejakowatz * Method: DestructionTest2<Locker>::TestThread2() 79*52a38012Sejakowatz * Descr: This method sleeps for SNOOZE_TIME/10 and then attempts to acquire 80*52a38012Sejakowatz * the lock for SNOOZE_TIME/10 seconds. This acquisition will timeout 81*52a38012Sejakowatz * because the other thread is holding the lock. Then it acquires the 82*52a38012Sejakowatz * lock by using a larger timeout. It sleeps again for 2*SNOOZE_TIME and 83*52a38012Sejakowatz * then deletes the lock. This should wake up the other thread. 84*52a38012Sejakowatz */ 85*52a38012Sejakowatz 86*52a38012Sejakowatz template<class Locker> void DestructionTest2<Locker>::TestThread2(void) 87*52a38012Sejakowatz { 88*52a38012Sejakowatz Locker *tmpLock; 89*52a38012Sejakowatz 90*52a38012Sejakowatz snooze(SNOOZE_TIME/10); 91*52a38012Sejakowatz assert(theLocker->LockWithTimeout(SNOOZE_TIME / 10) == B_TIMED_OUT); 92*52a38012Sejakowatz assert(theLocker->LockWithTimeout(SNOOZE_TIME * 10) == B_OK); 93*52a38012Sejakowatz snooze(SNOOZE_TIME); 94*52a38012Sejakowatz snooze(SNOOZE_TIME); 95*52a38012Sejakowatz tmpLock = theLocker; 96*52a38012Sejakowatz theLocker = NULL; 97*52a38012Sejakowatz delete tmpLock; 98*52a38012Sejakowatz } 99*52a38012Sejakowatz 100*52a38012Sejakowatz 101*52a38012Sejakowatz /* 102*52a38012Sejakowatz * Method: DestructionTest2<Locker>::suite() 103*52a38012Sejakowatz * Descr: This static member function returns a test suite for performing 104*52a38012Sejakowatz * all combinations of "DestructionTest2". The test suite contains 105*52a38012Sejakowatz * two instances of the test. One is performed on a benaphore, 106*52a38012Sejakowatz * the other on a semaphore based BLocker. Each individual test 107*52a38012Sejakowatz * is created as a ThreadedTestCase (typedef'd as 108*52a38012Sejakowatz * DestructionTest2Caller) with two independent threads. 109*52a38012Sejakowatz */ 110*52a38012Sejakowatz 111*52a38012Sejakowatz template<class Locker> Test *DestructionTest2<Locker>::suite(void) 112*52a38012Sejakowatz { 113*52a38012Sejakowatz TestSuite *testSuite = new TestSuite("DestructionTest2"); 114*52a38012Sejakowatz 115*52a38012Sejakowatz // Make a benaphore based test object, create a ThreadedTestCase for it and add 116*52a38012Sejakowatz // two threads to it. 117*52a38012Sejakowatz DestructionTest2<Locker> *theTest = new DestructionTest2<Locker>("Benaphore", true); 118*52a38012Sejakowatz DestructionTest2Caller *threadedTest1 = new DestructionTest2Caller("", theTest); 119*52a38012Sejakowatz threadedTest1->addThread(":Thread1", &DestructionTest2<Locker>::TestThread1); 120*52a38012Sejakowatz threadedTest1->addThread(":Thread2", &DestructionTest2<Locker>::TestThread2); 121*52a38012Sejakowatz 122*52a38012Sejakowatz // Make a semaphore based test object, create a ThreadedTestCase for it and add 123*52a38012Sejakowatz // three threads to it. 124*52a38012Sejakowatz theTest = new DestructionTest2<Locker>("Semaphore", false); 125*52a38012Sejakowatz DestructionTest2Caller *threadedTest2 = new DestructionTest2Caller("", theTest); 126*52a38012Sejakowatz threadedTest2->addThread(":Thread1", &DestructionTest2<Locker>::TestThread1); 127*52a38012Sejakowatz threadedTest2->addThread(":Thread2", &DestructionTest2<Locker>::TestThread2); 128*52a38012Sejakowatz 129*52a38012Sejakowatz testSuite->addTest(threadedTest1); 130*52a38012Sejakowatz testSuite->addTest(threadedTest2); 131*52a38012Sejakowatz return(testSuite); 132*52a38012Sejakowatz } 133*52a38012Sejakowatz 134*52a38012Sejakowatz template class DestructionTest2<BLocker>; 135*52a38012Sejakowatz template class DestructionTest2<OpenBeOS::BLocker>;