xref: /haiku/src/tests/kits/support/blocker/DestructionTest2.cpp (revision 52a380120846174213ccce9c4aab0dda17c72083)
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>;