|
1 // Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 // System includes |
|
17 #include <cntdb.h> |
|
18 #include <cntdef.h> |
|
19 #include <cntitem.h> |
|
20 #include <cntfield.h> |
|
21 #include <cntfldst.h> |
|
22 |
|
23 // System includes |
|
24 #include <e32std.h> |
|
25 #include <e32twin.h> |
|
26 #include <e32test.h> |
|
27 #include <cntdbobs.h> |
|
28 |
|
29 // User includes |
|
30 #include "t_utils2.h" |
|
31 |
|
32 // Constant |
|
33 _LIT(KDatabaseFileName, "c:t_owncard.cdb"); |
|
34 _LIT(KSemaphoreNameOne, "One"); |
|
35 _LIT(KSemaphoreNameTwo, "Two"); |
|
36 |
|
37 _LIT(KThreadNameOne, "OneThread"); |
|
38 _LIT(KThreadNameTwo, "TwoThread"); |
|
39 |
|
40 |
|
41 const TInt KDelay = 1000000; |
|
42 |
|
43 static RTest TheTest(_L("t_owncard")); |
|
44 |
|
45 |
|
46 // |
|
47 /* CTestActiveScheduler */ |
|
48 // This class has been nicked from the t_currentdb.h / .cpp files |
|
49 class CTestActiveScheduler : public CActiveScheduler |
|
50 { |
|
51 public: |
|
52 void Error (TInt aError) const; |
|
53 }; |
|
54 void CTestActiveScheduler::Error(TInt aError) const |
|
55 { |
|
56 User::Panic(_L("AScheduler"),aError); |
|
57 } |
|
58 |
|
59 |
|
60 |
|
61 // |
|
62 /* CConcurrentDatabaseAccessBase - Specification */ |
|
63 // Forms the base class for both threads. |
|
64 class CConcurrentDatabaseAccessBase : public CActive |
|
65 { |
|
66 public: // Data Types |
|
67 enum TStage |
|
68 { |
|
69 EOne_Startup, |
|
70 ETwo_FirstCheck, |
|
71 EThree_ChangeOwner, |
|
72 ENOP_One, |
|
73 ENOP_Two, |
|
74 EFour_SecondCheck, |
|
75 EFive_Cleanup, |
|
76 EFinished |
|
77 } ; |
|
78 public: |
|
79 CConcurrentDatabaseAccessBase(); |
|
80 virtual ~CConcurrentDatabaseAccessBase(); |
|
81 |
|
82 virtual void ConstructL(const TDesC& aFilename); |
|
83 |
|
84 void RunTestL(); |
|
85 |
|
86 |
|
87 public: // data |
|
88 RThread iThread; |
|
89 |
|
90 protected: |
|
91 void OpenSemaphore(); |
|
92 void CloseSemaphore(); |
|
93 void SyncronizeSignal(); |
|
94 void SyncronizeWait(); |
|
95 void OpenDatabaseL(); |
|
96 void CloseDatabase(); |
|
97 void CloseTest(); |
|
98 |
|
99 virtual TBool RunTestImplementationL() = 0; |
|
100 |
|
101 protected: // from CActive |
|
102 void DoCancel() {}; |
|
103 void RunL(); |
|
104 TInt RunError(TInt aError); |
|
105 void CallRunLAgain(); |
|
106 TBool NextStage(); |
|
107 |
|
108 |
|
109 protected: |
|
110 CContactDatabase* iDb; |
|
111 TStage iStage; |
|
112 TInt iTestError; |
|
113 |
|
114 private: |
|
115 RSemaphore iSemaphoreSignal; |
|
116 RSemaphore iSemaphoreWait; |
|
117 TBool iSemaphoreOpen; |
|
118 HBufC* iDatabaseName; |
|
119 }; |
|
120 |
|
121 // |
|
122 /* CConcurrentDatabaseAccessBase - Implementation */ |
|
123 CConcurrentDatabaseAccessBase::CConcurrentDatabaseAccessBase() |
|
124 : CActive( /*EPriorityStandard*/ EPriorityIdle ) |
|
125 { |
|
126 iStage = EOne_Startup; |
|
127 } |
|
128 |
|
129 CConcurrentDatabaseAccessBase::~CConcurrentDatabaseAccessBase() |
|
130 { |
|
131 iThread.Close(); |
|
132 CloseSemaphore(); |
|
133 delete iDatabaseName; |
|
134 } |
|
135 |
|
136 void CConcurrentDatabaseAccessBase::ConstructL(const TDesC& aFilename) |
|
137 { |
|
138 iDatabaseName = aFilename.AllocL(); |
|
139 } |
|
140 |
|
141 void CConcurrentDatabaseAccessBase::OpenDatabaseL() |
|
142 { |
|
143 iDb = CContactDatabase::OpenL(*iDatabaseName, CContactDatabase::EMultiThread); |
|
144 } |
|
145 |
|
146 void CConcurrentDatabaseAccessBase::CloseDatabase() |
|
147 { |
|
148 delete iDb; |
|
149 iDb = NULL; |
|
150 } |
|
151 |
|
152 void CConcurrentDatabaseAccessBase::CloseTest() |
|
153 { |
|
154 } |
|
155 |
|
156 void CConcurrentDatabaseAccessBase::CallRunLAgain() |
|
157 { |
|
158 iStatus = KRequestPending; |
|
159 |
|
160 TRequestStatus* ptrStatus = &iStatus; |
|
161 User::RequestComplete( ptrStatus, KErrNone ); |
|
162 SetActive(); |
|
163 } |
|
164 |
|
165 TBool CConcurrentDatabaseAccessBase::NextStage() |
|
166 { |
|
167 TInt stage = static_cast<TInt>( iStage ); |
|
168 stage++; |
|
169 iStage = static_cast<TStage>( stage ); |
|
170 return ( iStage == EFinished ); |
|
171 } |
|
172 |
|
173 void CConcurrentDatabaseAccessBase::RunL() |
|
174 { |
|
175 TBool stopProcessing = EFalse; |
|
176 |
|
177 stopProcessing = RunTestImplementationL(); |
|
178 |
|
179 if (stopProcessing) |
|
180 { |
|
181 CActiveScheduler::Stop(); |
|
182 } |
|
183 } |
|
184 |
|
185 TInt CConcurrentDatabaseAccessBase::RunError(TInt aError) |
|
186 { |
|
187 // propagate the error |
|
188 iTestError = aError; |
|
189 |
|
190 RDebug::Print(_L("Thread failed at test stage %i, with error %i"), iStage, aError); |
|
191 |
|
192 CActiveScheduler::Stop(); |
|
193 return KErrNone; |
|
194 } |
|
195 |
|
196 void CConcurrentDatabaseAccessBase::RunTestL() |
|
197 { |
|
198 // set's up an active scheduler for the thread |
|
199 // and calls the RunTesImplementation function to actually |
|
200 // preform the tests. This function should be implemented in the |
|
201 // child class. |
|
202 CTestActiveScheduler* scheduler = NULL; |
|
203 |
|
204 scheduler = new (ELeave) CTestActiveScheduler; |
|
205 CleanupStack::PushL(scheduler); |
|
206 CActiveScheduler::Install(scheduler); |
|
207 |
|
208 CActiveScheduler::Add( this ); |
|
209 |
|
210 OpenDatabaseL(); |
|
211 |
|
212 CallRunLAgain(); |
|
213 CActiveScheduler::Start(); |
|
214 |
|
215 CloseDatabase(); |
|
216 |
|
217 CleanupStack::PopAndDestroy( scheduler ); |
|
218 |
|
219 // propagate error |
|
220 User::LeaveIfError(iTestError); |
|
221 } |
|
222 |
|
223 void CConcurrentDatabaseAccessBase::OpenSemaphore() |
|
224 { |
|
225 TInt success = KErrNone; |
|
226 |
|
227 success = iSemaphoreSignal.OpenGlobal( KSemaphoreNameOne ); |
|
228 if ( success == KErrNotFound ) |
|
229 { |
|
230 iSemaphoreSignal.CreateGlobal( KSemaphoreNameOne, 0 ); |
|
231 success = KErrNone; |
|
232 } |
|
233 |
|
234 |
|
235 success = iSemaphoreWait.OpenGlobal( KSemaphoreNameTwo ); |
|
236 if ( success == KErrNotFound ) |
|
237 { |
|
238 iSemaphoreWait.CreateGlobal( KSemaphoreNameTwo, 0 ); |
|
239 } |
|
240 |
|
241 iSemaphoreOpen = ETrue; |
|
242 } |
|
243 |
|
244 void CConcurrentDatabaseAccessBase::CloseSemaphore() |
|
245 { |
|
246 if (iSemaphoreOpen) |
|
247 { |
|
248 iSemaphoreSignal.Close(); |
|
249 iSemaphoreWait.Close(); |
|
250 } |
|
251 |
|
252 iSemaphoreOpen = EFalse; |
|
253 } |
|
254 |
|
255 void CConcurrentDatabaseAccessBase::SyncronizeSignal() |
|
256 { |
|
257 CallRunLAgain(); |
|
258 iSemaphoreSignal.Signal(); |
|
259 iSemaphoreWait.Wait(); |
|
260 } |
|
261 |
|
262 void CConcurrentDatabaseAccessBase::SyncronizeWait() |
|
263 { |
|
264 CallRunLAgain(); |
|
265 iSemaphoreSignal.Wait(); |
|
266 iSemaphoreWait.Signal(); |
|
267 } |
|
268 |
|
269 // |
|
270 /* CConcurrentOwnerCardModifier - Specification */ |
|
271 // This class should allow the two threads to compare the owner ID's of there db. |
|
272 class TOwnerCardCompare |
|
273 { |
|
274 public: |
|
275 enum EThreadName |
|
276 { |
|
277 EModifier, |
|
278 EChecker |
|
279 }; |
|
280 public: |
|
281 TOwnerCardCompare(); |
|
282 ~TOwnerCardCompare(); |
|
283 void AssignValuesAndCheckL(TContactItemId aValue, EThreadName aThreadName); |
|
284 |
|
285 private: |
|
286 void CheckValuesL(); |
|
287 void ClearValues(); |
|
288 |
|
289 private: // data |
|
290 TBool iModifierDataPresent; |
|
291 TBool iCheckerDataPresent; |
|
292 TContactItemId iModifierValue; |
|
293 TContactItemId iCheckerValue; |
|
294 }; |
|
295 |
|
296 // |
|
297 /* CConcurrentOwnerCardModifier - Implementatio */ |
|
298 // This class should allow the two threads to compare the owner ID's of there db. |
|
299 TOwnerCardCompare::TOwnerCardCompare() |
|
300 { |
|
301 ClearValues(); |
|
302 } |
|
303 TOwnerCardCompare::~TOwnerCardCompare() |
|
304 { |
|
305 ClearValues(); |
|
306 } |
|
307 |
|
308 void TOwnerCardCompare::AssignValuesAndCheckL(TContactItemId aValue, EThreadName aThreadName) |
|
309 { |
|
310 switch ( aThreadName ) |
|
311 { |
|
312 case EModifier: |
|
313 iModifierDataPresent = ETrue; |
|
314 iModifierValue = aValue; |
|
315 break; |
|
316 |
|
317 case EChecker: |
|
318 iCheckerDataPresent = ETrue; |
|
319 iCheckerValue = aValue; |
|
320 break; |
|
321 } |
|
322 CheckValuesL(); |
|
323 } |
|
324 |
|
325 void TOwnerCardCompare::CheckValuesL() |
|
326 { |
|
327 if ( iModifierDataPresent && iCheckerDataPresent ) |
|
328 { |
|
329 TheTest( (iCheckerValue == iModifierValue) ); |
|
330 ClearValues(); |
|
331 } |
|
332 } |
|
333 |
|
334 void TOwnerCardCompare::ClearValues() |
|
335 { |
|
336 iCheckerDataPresent = EFalse; |
|
337 iModifierDataPresent = EFalse; |
|
338 iCheckerValue = 0; |
|
339 iModifierValue = 0xFFFFFFFF; |
|
340 } |
|
341 |
|
342 // |
|
343 /* CConcurrentOwnerCardModifier - Specification */ |
|
344 // This class should create the db, and set the owner card. |
|
345 class CConcurrentOwnerCardModifier : public CConcurrentDatabaseAccessBase |
|
346 { |
|
347 public: |
|
348 CConcurrentOwnerCardModifier(TOwnerCardCompare& aOwnerCardCompare); |
|
349 ~CConcurrentOwnerCardModifier(); |
|
350 |
|
351 static CConcurrentOwnerCardModifier* NewLC(const TDesC& aFilename, TOwnerCardCompare& aOwnerCardCompare); |
|
352 virtual void ConstructL(const TDesC& aFilename); |
|
353 |
|
354 static TInt ThreadFunction(TAny* aSelf); |
|
355 |
|
356 |
|
357 protected: |
|
358 TBool RunTestImplementationL(); |
|
359 |
|
360 private: |
|
361 void AssignAndCompareOwnerCardIdL(TContactItemId aOwner); |
|
362 |
|
363 private: |
|
364 TOwnerCardCompare& iOwnerCardCompare; |
|
365 }; |
|
366 |
|
367 // |
|
368 /* CConcurrentOwnerCardModifier - Implementation */ |
|
369 |
|
370 CConcurrentOwnerCardModifier* CConcurrentOwnerCardModifier::NewLC(const TDesC& aFilename, TOwnerCardCompare& aOwnerCardCompare) |
|
371 { |
|
372 CConcurrentOwnerCardModifier* self = NULL; |
|
373 self = new (ELeave) CConcurrentOwnerCardModifier(aOwnerCardCompare); |
|
374 CleanupStack::PushL( self ); |
|
375 self->ConstructL(aFilename); |
|
376 return self; |
|
377 } |
|
378 |
|
379 CConcurrentOwnerCardModifier::CConcurrentOwnerCardModifier(TOwnerCardCompare& aOwnerCardCompare) |
|
380 : iOwnerCardCompare( aOwnerCardCompare ) |
|
381 { |
|
382 } |
|
383 |
|
384 CConcurrentOwnerCardModifier::~CConcurrentOwnerCardModifier() |
|
385 { |
|
386 } |
|
387 |
|
388 TInt CConcurrentOwnerCardModifier::ThreadFunction(TAny* aSelf) |
|
389 { |
|
390 CConcurrentOwnerCardModifier* self = STATIC_CAST(CConcurrentOwnerCardModifier*, aSelf); |
|
391 |
|
392 // Prepare the stuff required before we start the |
|
393 // active scheduler. |
|
394 TInt error = KErrNone; |
|
395 CTrapCleanup* cleanup = CTrapCleanup::New(); |
|
396 if (!cleanup) |
|
397 return KErrNoMemory; |
|
398 |
|
399 // Call virtual handler which does anything that needs doing as |
|
400 // a result of the thread function from being created. |
|
401 TRAP(error, self->RunTestL()); |
|
402 |
|
403 |
|
404 delete cleanup; |
|
405 return error; |
|
406 } |
|
407 |
|
408 void CConcurrentOwnerCardModifier::ConstructL(const TDesC& aFilename) |
|
409 { |
|
410 CConcurrentDatabaseAccessBase::ConstructL(aFilename); |
|
411 |
|
412 iThread.Create( KThreadNameOne, CConcurrentOwnerCardModifier::ThreadFunction, KDefaultStackSize, 0x2000, 0x20000, this, EOwnerThread ); |
|
413 iThread.Resume(); |
|
414 iThread.SetPriority(/*EPriorityNormal*/EPriorityAbsoluteBackground); |
|
415 } |
|
416 |
|
417 // 1. Set up |
|
418 // 2. Check current owner card. |
|
419 // 3. Sync |
|
420 // 4. modify owner card |
|
421 // 5. Sync |
|
422 // 6. Check owner card |
|
423 // 7. Sync |
|
424 // 8. Finished. |
|
425 TBool CConcurrentOwnerCardModifier::RunTestImplementationL() |
|
426 { |
|
427 TInt bit = 0; |
|
428 TContactItemId id; |
|
429 CRandomContactGenerator* generator = NULL; |
|
430 CContactItem* item = NULL; |
|
431 TBool retval = EFalse; |
|
432 |
|
433 switch( iStage ) |
|
434 { |
|
435 case EOne_Startup: |
|
436 OpenSemaphore(); |
|
437 retval = NextStage(); |
|
438 SyncronizeWait(); // pause until corresponding Searcher thread is ready. |
|
439 break; |
|
440 |
|
441 case ETwo_FirstCheck: |
|
442 id = iDb->OwnCardId(); |
|
443 AssignAndCompareOwnerCardIdL( id ); |
|
444 retval = NextStage(); |
|
445 SyncronizeWait(); |
|
446 break; |
|
447 |
|
448 case EThree_ChangeOwner: |
|
449 generator = CRandomContactGenerator::NewL(); |
|
450 CleanupStack::PushL( generator ); |
|
451 generator->SetDbL(*iDb); |
|
452 |
|
453 bit |= CContactDatabase::ESmsable; |
|
454 id = generator->AddTypicalContactForFilterL(bit); |
|
455 item = iDb->ReadContactL( id ); |
|
456 CleanupStack::PushL( item ); |
|
457 iDb->SetOwnCardL( *item ); |
|
458 CleanupStack::PopAndDestroy( item ); |
|
459 item = NULL; |
|
460 CleanupStack::PopAndDestroy( generator ); |
|
461 generator = NULL; |
|
462 retval = NextStage(); |
|
463 SyncronizeWait(); // wait here. |
|
464 break; |
|
465 |
|
466 case ENOP_One: |
|
467 CallRunLAgain(); |
|
468 retval = NextStage(); |
|
469 break; |
|
470 |
|
471 case ENOP_Two: |
|
472 CallRunLAgain(); |
|
473 retval = NextStage(); |
|
474 break; |
|
475 |
|
476 case EFour_SecondCheck: |
|
477 iDb->CountL(); |
|
478 id = iDb->OwnCardId(); |
|
479 AssignAndCompareOwnerCardIdL( id ); |
|
480 retval = NextStage(); |
|
481 SyncronizeWait(); |
|
482 break; |
|
483 |
|
484 case EFive_Cleanup: |
|
485 CloseSemaphore(); |
|
486 CloseTest(); |
|
487 retval = ETrue; |
|
488 break; |
|
489 |
|
490 default: |
|
491 break; |
|
492 } |
|
493 |
|
494 return retval; |
|
495 } |
|
496 |
|
497 |
|
498 void CConcurrentOwnerCardModifier::AssignAndCompareOwnerCardIdL(TContactItemId aOwner) |
|
499 { |
|
500 //SyncronizeWait(); |
|
501 iOwnerCardCompare.AssignValuesAndCheckL( aOwner, TOwnerCardCompare::EModifier ); |
|
502 //SyncronizeWait(); |
|
503 //SyncronizeWait(); |
|
504 } |
|
505 |
|
506 // |
|
507 /* CConcurrentOwnerCardChecker */ |
|
508 class CConcurrentOwnerCardChecker : public CConcurrentDatabaseAccessBase |
|
509 { |
|
510 public: |
|
511 CConcurrentOwnerCardChecker(TOwnerCardCompare& aOwnerCardCompare); |
|
512 ~CConcurrentOwnerCardChecker(); |
|
513 |
|
514 static CConcurrentOwnerCardChecker* NewLC(const TDesC& aFilename, TOwnerCardCompare& aOwnerCardCompare); |
|
515 virtual void ConstructL(const TDesC& aFilename); |
|
516 static TInt ThreadFunction(TAny* aSelf); |
|
517 static TInt FakeFunction(TAny *aParams); |
|
518 |
|
519 |
|
520 |
|
521 protected: |
|
522 TBool RunTestImplementationL(); |
|
523 |
|
524 private: |
|
525 void AssignAndCompareOwnerCardIdL(TContactItemId aOwner); |
|
526 |
|
527 private: |
|
528 TOwnerCardCompare& iOwnerCardCompare; |
|
529 }; |
|
530 |
|
531 CConcurrentOwnerCardChecker* CConcurrentOwnerCardChecker::NewLC(const TDesC& aFilename, TOwnerCardCompare& aOwnerCardCompare) |
|
532 { |
|
533 CConcurrentOwnerCardChecker* self = NULL; |
|
534 self = new (ELeave) CConcurrentOwnerCardChecker(aOwnerCardCompare); |
|
535 CleanupStack::PushL( self ); |
|
536 self->ConstructL(aFilename); |
|
537 return self; |
|
538 } |
|
539 |
|
540 CConcurrentOwnerCardChecker::CConcurrentOwnerCardChecker(TOwnerCardCompare& aOwnerCardCompare) |
|
541 : iOwnerCardCompare( aOwnerCardCompare ) |
|
542 { |
|
543 } |
|
544 |
|
545 CConcurrentOwnerCardChecker::~CConcurrentOwnerCardChecker() |
|
546 { |
|
547 } |
|
548 |
|
549 TInt CConcurrentOwnerCardChecker::ThreadFunction(TAny* aSelf) |
|
550 { |
|
551 CConcurrentOwnerCardChecker* self = static_cast<CConcurrentOwnerCardChecker*>(aSelf); |
|
552 |
|
553 // Prepare the stuff required before we start the |
|
554 // active scheduler. |
|
555 TInt error = KErrNone; |
|
556 |
|
557 CTrapCleanup* cleanup = CTrapCleanup::New(); |
|
558 if (!cleanup) |
|
559 return KErrNoMemory; |
|
560 |
|
561 // Call virtual handler which does anything that needs doing as |
|
562 // a result of the thread function from being created. |
|
563 TRAP(error, self->RunTestL()); |
|
564 |
|
565 |
|
566 delete cleanup; |
|
567 return error; |
|
568 } |
|
569 |
|
570 void CConcurrentOwnerCardChecker::ConstructL(const TDesC& aFilename) |
|
571 { |
|
572 CConcurrentDatabaseAccessBase::ConstructL(aFilename); |
|
573 |
|
574 iThread.Create( KThreadNameTwo, CConcurrentOwnerCardChecker::ThreadFunction, KDefaultStackSize, 0x2000, 0x20000, this, EOwnerThread ); |
|
575 iThread.Resume(); |
|
576 iThread.SetPriority(/*EPriorityNormal*/EPriorityAbsoluteBackground); |
|
577 |
|
578 } |
|
579 |
|
580 |
|
581 TInt CConcurrentOwnerCardChecker::FakeFunction(TAny* /*aParams*/) |
|
582 { |
|
583 return(KErrNone); |
|
584 } |
|
585 |
|
586 TBool CConcurrentOwnerCardChecker::RunTestImplementationL() |
|
587 { |
|
588 // Prep, and get ready to run. Then before starting the search loop |
|
589 // wait for the other thread. |
|
590 TContactItemId id; |
|
591 TBool retval = EFalse; |
|
592 |
|
593 switch( iStage ) |
|
594 { |
|
595 case EOne_Startup: |
|
596 //TCallBack callBack(FakeFunction); |
|
597 OpenSemaphore(); |
|
598 retval = NextStage(); |
|
599 SyncronizeSignal(); // wait for the other thread. |
|
600 break; |
|
601 |
|
602 case ETwo_FirstCheck: |
|
603 id = iDb->OwnCardId(); |
|
604 AssignAndCompareOwnerCardIdL( id ); |
|
605 retval = NextStage(); |
|
606 SyncronizeSignal(); |
|
607 break; |
|
608 |
|
609 case EThree_ChangeOwner: |
|
610 retval = NextStage(); |
|
611 SyncronizeSignal(); |
|
612 break; |
|
613 |
|
614 case ENOP_One: |
|
615 CallRunLAgain(); |
|
616 retval = NextStage(); |
|
617 break; |
|
618 |
|
619 case ENOP_Two: |
|
620 CallRunLAgain(); |
|
621 retval = NextStage(); |
|
622 break; |
|
623 |
|
624 case EFour_SecondCheck: |
|
625 iDb->CountL(); |
|
626 id = iDb->OwnCardId(); |
|
627 AssignAndCompareOwnerCardIdL( id ); |
|
628 retval = NextStage(); |
|
629 SyncronizeSignal(); |
|
630 break; |
|
631 |
|
632 case EFive_Cleanup: |
|
633 CloseSemaphore(); |
|
634 CloseTest(); |
|
635 retval = NextStage(); |
|
636 break; |
|
637 |
|
638 default: |
|
639 break; |
|
640 } |
|
641 |
|
642 return retval; |
|
643 } |
|
644 |
|
645 |
|
646 void CConcurrentOwnerCardChecker::AssignAndCompareOwnerCardIdL(TContactItemId aOwner) |
|
647 { |
|
648 //SyncronizeSignal(); |
|
649 //SyncronizeSignal(); |
|
650 iOwnerCardCompare.AssignValuesAndCheckL( aOwner, TOwnerCardCompare::EChecker ); |
|
651 //SyncronizeSignal(); |
|
652 } |
|
653 |
|
654 // |
|
655 /* Test Function Prototypes */ |
|
656 // |
|
657 void CreateTestDatabaseL(const TDesC& aFilename); |
|
658 void TestL(); |
|
659 void doMainL(); |
|
660 |
|
661 // |
|
662 /* Test Function Implementations */ |
|
663 // |
|
664 void CreateTestDatabaseL(const TDesC& aFilename ) |
|
665 { |
|
666 TInt counter = 0; |
|
667 TInt bit = 0; |
|
668 CContactDatabase* database = NULL; |
|
669 CRandomContactGenerator* generator = NULL; |
|
670 CContactItem* ownerCardItem = NULL; |
|
671 TContactItemId ownerCard = 0; |
|
672 |
|
673 database = CContactDatabase::ReplaceL(aFilename); |
|
674 CleanupStack::PushL( database ); |
|
675 |
|
676 generator = CRandomContactGenerator::NewL(); |
|
677 CleanupStack::PushL( generator ); |
|
678 |
|
679 generator->SetDbL(*database); |
|
680 |
|
681 |
|
682 bit |= CContactDatabase::ESmsable; |
|
683 ownerCard = generator->AddTypicalContactForFilterL(bit); |
|
684 TheTest.Printf(_L("Adding SMS contacts %d\n"), counter); |
|
685 |
|
686 |
|
687 ownerCardItem = database->ReadContactL( ownerCard ); |
|
688 CleanupStack::PushL( ownerCardItem ); |
|
689 database->SetOwnCardL( *ownerCardItem ); |
|
690 CleanupStack::PopAndDestroy( ownerCardItem ); ownerCardItem = NULL; |
|
691 |
|
692 CleanupStack::PopAndDestroy( generator ); |
|
693 CleanupStack::PopAndDestroy( database ); |
|
694 } |
|
695 |
|
696 |
|
697 void TestL() |
|
698 { |
|
699 TRequestStatus thread1; |
|
700 TRequestStatus thread2; |
|
701 TOwnerCardCompare compareTool; |
|
702 CConcurrentOwnerCardChecker* searcher = NULL; |
|
703 CConcurrentOwnerCardModifier* inserter = NULL; |
|
704 |
|
705 CreateTestDatabaseL( KDatabaseFileName ); |
|
706 |
|
707 searcher = CConcurrentOwnerCardChecker::NewLC( KDatabaseFileName, compareTool ); |
|
708 User::After(KDelay); // so that checker thread created first |
|
709 inserter = CConcurrentOwnerCardModifier::NewLC( KDatabaseFileName, compareTool ); |
|
710 |
|
711 searcher->iThread.Logon(thread1); |
|
712 inserter->iThread.Logon(thread2); |
|
713 |
|
714 User::WaitForRequest(thread2); |
|
715 User::WaitForRequest(thread1); |
|
716 |
|
717 CleanupStack::PopAndDestroy( inserter ); |
|
718 CleanupStack::PopAndDestroy( searcher ); |
|
719 |
|
720 // fail if either thread failed |
|
721 User::LeaveIfError(thread1.Int()); |
|
722 User::LeaveIfError(thread2.Int()); |
|
723 } |
|
724 |
|
725 |
|
726 // |
|
727 // -------> Static global functions (source) |
|
728 // |
|
729 void doMainL() |
|
730 { |
|
731 RFs fs; |
|
732 User::LeaveIfError(fs.Connect()); |
|
733 CleanupClosePushL(fs); |
|
734 CTestRegister * TempFiles = CTestRegister::NewLC(); |
|
735 TempFiles->RegisterL(KDatabaseFileName, EFileTypeCnt); |
|
736 |
|
737 CTestActiveScheduler* scheduler = new (ELeave) CTestActiveScheduler; |
|
738 CleanupStack::PushL(scheduler); |
|
739 CActiveScheduler::Install(scheduler); |
|
740 |
|
741 |
|
742 |
|
743 // Delete any existing ini file so that we can be sure this test is ok |
|
744 TestL(); |
|
745 |
|
746 CleanupStack::PopAndDestroy( 3 ); // scheduler, tempfiles, fs |
|
747 |
|
748 } |
|
749 |
|
750 |
|
751 /** |
|
752 |
|
753 @SYMTestCaseID PIM-T-OWNCARD-0001 |
|
754 |
|
755 */ |
|
756 |
|
757 GLDEF_C TInt E32Main() |
|
758 { |
|
759 CTrapCleanup* cleanupStack = NULL; |
|
760 __UHEAP_MARK; |
|
761 TheTest.Start(_L("@SYMTESTCaseID:PIM-T-OWNCARD-0001 Multi session testcode")); |
|
762 |
|
763 TheTest.Title(); |
|
764 cleanupStack = CTrapCleanup::New(); |
|
765 TRAPD(ret, doMainL()); |
|
766 TheTest(ret == KErrNone); |
|
767 delete cleanupStack; |
|
768 |
|
769 TheTest.End(); |
|
770 TheTest.Close(); |
|
771 __UHEAP_MARKEND; |
|
772 return(KErrNone); |
|
773 } |