|
1 /* |
|
2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 #include <unistd.h> |
|
18 |
|
19 #include <memory> |
|
20 #include <string.h> |
|
21 |
|
22 #include "itk.h" |
|
23 |
|
24 #include "cpixsynctools.h" |
|
25 |
|
26 |
|
27 void testMutex(Itk::TestMgr * ) |
|
28 { |
|
29 using namespace Cpt; |
|
30 |
|
31 Mutex |
|
32 mutex; |
|
33 |
|
34 SyncRegion |
|
35 sr(mutex); |
|
36 } |
|
37 |
|
38 |
|
39 void testRecursiveMutex(Itk::TestMgr * ) |
|
40 { |
|
41 using namespace Cpt; |
|
42 |
|
43 Mutex |
|
44 mutex(true); |
|
45 |
|
46 SyncRegion |
|
47 sr1(mutex); |
|
48 |
|
49 SyncRegion |
|
50 sr2(mutex); |
|
51 } |
|
52 |
|
53 |
|
54 void testMultiSyncRegion(Itk::TestMgr * ) |
|
55 { |
|
56 using namespace Cpt; |
|
57 |
|
58 Mutex |
|
59 mutex1, |
|
60 mutex2(true), |
|
61 mutex3; |
|
62 |
|
63 { |
|
64 MultiSyncRegion |
|
65 msr(4); |
|
66 |
|
67 msr.lock(mutex1); |
|
68 msr.lock(mutex2); |
|
69 msr.lock(mutex3); |
|
70 msr.lock(mutex2); |
|
71 } |
|
72 |
|
73 SyncRegion |
|
74 sr(mutex1); |
|
75 |
|
76 SyncRegion |
|
77 sr1(mutex2); |
|
78 |
|
79 SyncRegion |
|
80 sr2(mutex3); |
|
81 } |
|
82 |
|
83 |
|
84 void testSyncExc(Itk::TestMgr * mgr) |
|
85 { |
|
86 pthread_mutex_t |
|
87 mutex; |
|
88 |
|
89 // kept uninitialized on purpose! |
|
90 |
|
91 try |
|
92 { |
|
93 Cpt::Impl::SyncRegion_::lockMutex(&mutex); |
|
94 |
|
95 ITK_EXPECT(mgr, |
|
96 false, |
|
97 "Locking uninitalized mutex should have failed"); |
|
98 } |
|
99 catch (std::exception & exc) |
|
100 { |
|
101 printf("Locking unitialized mutex have failed (as should): %s\n", |
|
102 exc.what()); |
|
103 } |
|
104 |
|
105 try |
|
106 { |
|
107 Cpt::Impl::SyncRegion_::unlockMutex(&mutex); |
|
108 |
|
109 ITK_EXPECT(mgr, |
|
110 false, |
|
111 "Unlocking uninitalized mutex should have failed"); |
|
112 } |
|
113 catch (std::exception & exc) |
|
114 { |
|
115 printf("Unlocking unitialized mutex have failed (as should): %s\n", |
|
116 exc.what()); |
|
117 } |
|
118 |
|
119 Cpt::Impl::SyncRegion_::initMutex(&mutex); |
|
120 |
|
121 try |
|
122 { |
|
123 Cpt::Impl::SyncRegion_::unlockMutex(&mutex); |
|
124 |
|
125 // TODO this should be ITK_EXPECT - why does NOT it fail? |
|
126 printf("Unlocking initialized but non-locked mutex should have failed\n"); |
|
127 } |
|
128 catch (std::exception & exc) |
|
129 { |
|
130 printf("Unlocking initialized but non-locked mutex have failed (as should): %s\n", |
|
131 exc.what()); |
|
132 } |
|
133 |
|
134 try |
|
135 { |
|
136 { |
|
137 Cpt::Impl::SyncRegion_ |
|
138 sr(&mutex); |
|
139 } |
|
140 |
|
141 printf("Locked and unlocked mutex"); |
|
142 } |
|
143 catch (std::exception & exc) |
|
144 { |
|
145 ITK_EXPECT(mgr, |
|
146 false, |
|
147 "Failed to lock and unlock mutex: %s", |
|
148 exc.what()); |
|
149 } |
|
150 |
|
151 Cpt::Impl::SyncRegion_::destroyMutex(&mutex); |
|
152 } |
|
153 |
|
154 |
|
155 /** |
|
156 * Test "SyncExc2" tries to create a situation where a thread that |
|
157 * does not own the lock tries to unlock the mutex (should fail). |
|
158 */ |
|
159 struct StupidUnlock |
|
160 { |
|
161 pthread_mutex_t * mutex_; |
|
162 Itk::TestMgr * mgr_; |
|
163 }; |
|
164 |
|
165 |
|
166 void * StupidThreadFunc(void * param) |
|
167 { |
|
168 printf("# SyncExc2 / StupidThread BEGIN.\n"); |
|
169 |
|
170 StupidUnlock |
|
171 * p = reinterpret_cast<StupidUnlock*>(param); |
|
172 |
|
173 try |
|
174 { |
|
175 Cpt::Impl::SyncRegion_::unlockMutex(p->mutex_); |
|
176 |
|
177 // TODO this should be ITK_EXPECT - why does NOT it fail? |
|
178 printf("# Unlocking mutex that is locked by another thread should fail (imho) - but it succeeds on both winscw and arm.\n"); |
|
179 } |
|
180 catch (std::exception & exc) |
|
181 { |
|
182 printf("# Unlocking mutex owned by another thread have failed (as should): %s\n", |
|
183 exc.what()); |
|
184 } |
|
185 |
|
186 printf("# SyncExc2 / StupidThread END.\n"); |
|
187 |
|
188 return NULL; |
|
189 } |
|
190 |
|
191 |
|
192 void testSyncExc2(Itk::TestMgr * mgr) |
|
193 { |
|
194 pthread_mutex_t |
|
195 mutex; |
|
196 |
|
197 Cpt::Impl::SyncRegion_::initMutex(&mutex); |
|
198 |
|
199 { |
|
200 Cpt::Impl::SyncRegion_ |
|
201 sr(&mutex); |
|
202 |
|
203 // here we create a thread that will try to unlock the mutex |
|
204 // held by this thread - it should fail |
|
205 StupidUnlock |
|
206 stupidUnlock = { |
|
207 &mutex, |
|
208 mgr |
|
209 }; |
|
210 |
|
211 pthread_t |
|
212 stupidThread; |
|
213 |
|
214 int |
|
215 result = pthread_create(&stupidThread, |
|
216 NULL, |
|
217 &StupidThreadFunc, |
|
218 &stupidUnlock); |
|
219 |
|
220 ITK_ASSERT(mgr, |
|
221 result == 0, |
|
222 "Could not start stupid thread: %d", |
|
223 result); |
|
224 |
|
225 printf("Sleep(1) ...\n"); |
|
226 |
|
227 sleep(1); |
|
228 |
|
229 printf("... awake(1)\n"); |
|
230 |
|
231 result = pthread_join(stupidThread, |
|
232 NULL); |
|
233 |
|
234 printf("has joined stupid thread, unlocking mutex\n"); |
|
235 } |
|
236 |
|
237 Cpt::Impl::SyncRegion_::destroyMutex(&mutex); |
|
238 |
|
239 printf("SyncExc2 test done.\n"); |
|
240 } |
|
241 |
|
242 |
|
243 |
|
244 Itk::TesterBase * CreateMutexTests() |
|
245 { |
|
246 using namespace Itk; |
|
247 |
|
248 SuiteTester |
|
249 * mutexTests = new SuiteTester("mutex"); |
|
250 |
|
251 #define TEST "mutex" |
|
252 mutexTests->add(TEST, |
|
253 testMutex); |
|
254 #undef TEST |
|
255 |
|
256 #define TEST "recursivemutex" |
|
257 mutexTests->add(TEST, |
|
258 testRecursiveMutex); |
|
259 #undef TEST |
|
260 |
|
261 #define TEST "multisyncregion" |
|
262 mutexTests->add(TEST, |
|
263 testMultiSyncRegion); |
|
264 #undef TEST |
|
265 |
|
266 #define TEST "syncexc" |
|
267 mutexTests->add(TEST, |
|
268 testSyncExc, |
|
269 TEST); |
|
270 #undef TEST |
|
271 |
|
272 #define TEST "syncexc2" |
|
273 mutexTests->add(TEST, |
|
274 testSyncExc2, |
|
275 TEST); |
|
276 #undef TEST |
|
277 |
|
278 |
|
279 // ... add more tests to suite |
|
280 |
|
281 return mutexTests; |
|
282 |
|
283 } |