xref: /haiku/src/tests/kits/app/bmessenger/LockTargetTester.cpp (revision 76a5f3484abd9a293483b45f40455c0b58e6f3f0)
1 //------------------------------------------------------------------------------
2 //	LockTargetTester.cpp
3 //
4 //------------------------------------------------------------------------------
5 
6 // Standard Includes -----------------------------------------------------------
7 #include <stdio.h>
8 
9 // System Includes -------------------------------------------------------------
10 #include <Message.h>
11 #include <OS.h>
12 
13 #include <Handler.h>
14 #include <Looper.h>
15 #include <Messenger.h>
16 
17 // Project Includes ------------------------------------------------------------
18 #include <TestUtils.h>
19 #include <ThreadedTestCaller.h>
20 #include <cppunit/TestSuite.h>
21 
22 // Local Includes --------------------------------------------------------------
23 #include "Helpers.h"
24 #include "LockTargetTester.h"
25 #include "SMTarget.h"
26 
27 // Local Defines ---------------------------------------------------------------
28 
29 // Globals ---------------------------------------------------------------------
30 
31 //------------------------------------------------------------------------------
32 
33 // constructor
LockTargetTester()34 LockTargetTester::LockTargetTester()
35 	: BThreadedTestCase(),
36 	  fHandler(NULL),
37 	  fLooper(NULL)
38 {
39 }
40 
41 // constructor
LockTargetTester(std::string name)42 LockTargetTester::LockTargetTester(std::string name)
43 	: BThreadedTestCase(name),
44 	  fHandler(NULL),
45 	  fLooper(NULL)
46 {
47 }
48 
49 // destructor
~LockTargetTester()50 LockTargetTester::~LockTargetTester()
51 {
52 	if (fLooper) {
53 		fLooper->Lock();
54 		if (fHandler) {
55 			fLooper->RemoveHandler(fHandler);
56 			delete fHandler;
57 		}
58 		fLooper->Quit();
59 	}
60 }
61 
62 /*
63 	bool LockTarget() const
64 	@case 1			this is uninitialized
65 	@results		should return false.
66  */
LockTargetTest1()67 void LockTargetTester::LockTargetTest1()
68 {
69 	BMessenger messenger;
70 	CHK(messenger.LockTarget() == false);
71 }
72 
73 /*
74 	bool LockTarget() const
75 	@case 2			this is initialized to local target with preferred handler,
76 					looper is not locked
77 	@results		should lock the looper and return true.
78  */
LockTargetTest2()79 void LockTargetTester::LockTargetTest2()
80 {
81 	status_t result = B_OK;
82 	BLooper *looper = new BLooper;
83 	looper->Run();
84 	LooperQuitter quitter(looper);
85 	BMessenger messenger(NULL, looper, &result);
86 	CHK(messenger.LockTarget() == true);
87 	CHK(looper->IsLocked() == true);
88 	looper->Unlock();
89 	CHK(looper->IsLocked() == false);
90 }
91 
92 /*
93 	bool LockTarget() const
94 	@case 3			this is initialized to local target with specific handler,
95 					looper is not locked
96 	@results		should lock the looper and return true.
97  */
LockTargetTest3()98 void LockTargetTester::LockTargetTest3()
99 {
100 	// create looper and handler
101 	status_t result = B_OK;
102 	BLooper *looper = new BLooper;
103 	looper->Run();
104 	LooperQuitter quitter(looper);
105 	BHandler *handler = new BHandler;
106 	HandlerDeleter deleter(handler);
107 	CHK(looper->Lock());
108 	looper->AddHandler(handler);
109 	looper->Unlock();
110 	// create the messenger and do the checks
111 	BMessenger messenger(handler, NULL, &result);
112 	CHK(messenger.LockTarget() == true);
113 	CHK(looper->IsLocked() == true);
114 	looper->Unlock();
115 	CHK(looper->IsLocked() == false);
116 }
117 
118 /*
119 	bool LockTarget() const
120 	@case 4			this is initialized to local target with preferred handler,
121 					looper is locked by another thread
122 	@results		should block until the looper is unlocked, lock it and
123 					return true.
124 	@thread A		- locks the looper
125 					- waits 100ms
126 					- unlocks the looper
127  */
LockTargetTest4A()128 void LockTargetTester::LockTargetTest4A()
129 {
130 	CHK(fLooper->Lock() == true);
131 	snooze(100000);
132 	fLooper->Unlock();
133 }
134 
135 /*
136 	bool LockTarget() const
137 	@case 4			this is initialized to local target with preferred handler,
138 					looper is locked by another thread
139 	@results		should block until the looper is unlocked, lock it and
140 					return true.
141 	@thread B		- waits 50ms (until thread A has acquired the looper lock)
142 					- tries to lock the looper via messenger and blocks
143 					- acquires the lock successfully after 50ms
144 					- unlocks the looper
145  */
LockTargetTest4B()146 void LockTargetTester::LockTargetTest4B()
147 {
148 	enum { JITTER = 10000 };	// Maybe critical on slow machines.
149 	snooze(50000);
150 	BMessenger messenger(NULL, fLooper);
151 	bigtime_t time = system_time();
152 	CHK(messenger.LockTarget() == true);
153 	time = system_time() - time - 50000;
154 	CHK(fLooper->IsLocked() == true);
155 	fLooper->Unlock();
156 	CHK(fLooper->IsLocked() == false);
157 	CHK(time > -JITTER && time < JITTER);
158 }
159 
160 /*
161 	bool LockTarget() const
162 	@case 5			this is initialized to local target with specific handler,
163 					looper is locked by another thread
164 	@results		should block until the looper is unlocked, lock it and
165 					return true.
166 	@thread A		- locks the looper
167 					- waits 100ms
168 					- unlocks the looper
169  */
LockTargetTest5A()170 void LockTargetTester::LockTargetTest5A()
171 {
172 	CHK(fLooper->Lock() == true);
173 	snooze(100000);
174 	fLooper->Unlock();
175 }
176 
177 /*
178 	bool LockTarget() const
179 	@case 5			this is initialized to local target with specific handler,
180 					looper is locked by another thread
181 	@results		should block until the looper is unlocked, lock it and
182 					return true.
183 	@thread B		- waits 50ms (until thread A has acquired the looper lock)
184 					- tries to lock the looper via messenger and blocks
185 					- acquires the lock successfully after 50ms
186 					- unlocks the looper
187  */
LockTargetTest5B()188 void LockTargetTester::LockTargetTest5B()
189 {
190 	enum { JITTER = 10000 };	// Maybe critical on slow machines.
191 	snooze(50000);
192 	BMessenger messenger(fHandler, NULL);
193 	bigtime_t time = system_time();
194 	CHK(messenger.LockTarget() == true);
195 	time = system_time() - time - 50000;
196 	CHK(fLooper->IsLocked() == true);
197 	fLooper->Unlock();
198 	CHK(fLooper->IsLocked() == false);
199 	CHK(time > -JITTER && time < JITTER);
200 }
201 
202 /*
203 	bool LockTarget() const
204 	@case 6			this is initialized to remote target with preferred
205 					handler, looper is not locked
206 	@results		should not lock the looper and return false.
207  */
LockTargetTest6()208 void LockTargetTester::LockTargetTest6()
209 {
210 	RemoteSMTarget target(true);
211 	BMessenger messenger(target.Messenger());
212 	CHK(messenger.LockTarget() == false);
213 }
214 
215 /*
216 	bool LockTarget() const
217 	@case 7			this is initialized to remote target with specific handler,
218 					looper is not locked
219 	@results		should not lock the looper and return false.
220  */
LockTargetTest7()221 void LockTargetTester::LockTargetTest7()
222 {
223 	RemoteSMTarget target(false);
224 	BMessenger messenger(target.Messenger());
225 	CHK(messenger.LockTarget() == false);
226 }
227 
228 
Suite()229 Test* LockTargetTester::Suite()
230 {
231 	typedef BThreadedTestCaller<LockTargetTester> TC;
232 
233 	TestSuite* testSuite = new TestSuite;
234 
235 	ADD_TEST4(BMessenger, testSuite, LockTargetTester, LockTargetTest1);
236 	ADD_TEST4(BMessenger, testSuite, LockTargetTester, LockTargetTest2);
237 	ADD_TEST4(BMessenger, testSuite, LockTargetTester, LockTargetTest3);
238 	// test4
239 	LockTargetTester *test4
240 		= new LockTargetTester("LockTargetTest4");
241 	test4->fLooper = new BLooper;
242 	test4->fLooper->Run();
243 	// test4 test caller
244 	TC *caller4 = new TC("BMessenger::LockTargetTest4", test4);
245 	caller4->addThread("A", &LockTargetTester::LockTargetTest4A);
246 	caller4->addThread("B", &LockTargetTester::LockTargetTest4B);
247 	testSuite->addTest(caller4);
248 	// test5
249 	LockTargetTester *test5
250 		= new LockTargetTester("LockTargetTest5");
251 	// create looper and handler
252 	test5->fLooper = new BLooper;
253 	test5->fLooper->Run();
254 	test5->fHandler = new BHandler;
255 	if (test5->fLooper->Lock()) {
256 		test5->fLooper->AddHandler(test5->fHandler);
257 		test5->fLooper->Unlock();
258 	} else
259 		printf("ERROR: Can't init LockTargetTester test5!\n");
260 	// test5 test caller
261 	TC *caller5 = new TC("BMessenger::LockTargetTest5", test5);
262 	caller5->addThread("A", &LockTargetTester::LockTargetTest5A);
263 	caller5->addThread("B", &LockTargetTester::LockTargetTest5B);
264 	testSuite->addTest(caller5);
265 	// tests 6-7
266 	ADD_TEST4(BMessenger, testSuite, LockTargetTester, LockTargetTest6);
267 	ADD_TEST4(BMessenger, testSuite, LockTargetTester, LockTargetTest7);
268 
269 	return testSuite;
270 }
271 
272 
273