phonebookengines/contactsmodel/tsrc/t_IccImportLock.cpp
changeset 0 e686773b3f54
equal deleted inserted replaced
-1:000000000000 0:e686773b3f54
       
     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 
       
    17 // System includes
       
    18 #include <cntdb.h>
       
    19 #include <cntdef.h>
       
    20 #include <cntitem.h>
       
    21 #include <cntfield.h>
       
    22 #include <cntfldst.h>
       
    23 
       
    24 // System includes
       
    25 #include <e32std.h>
       
    26 #include <e32twin.h>
       
    27 #include <e32test.h>
       
    28 #include <cntdbobs.h>
       
    29 #include <e32math.h>
       
    30 
       
    31 // User includes
       
    32 #include "T_UTILS.H"
       
    33 #include "t_utils2.h"
       
    34 
       
    35 // Constant
       
    36 _LIT(KDatabaseFileName, "c:INC016848.cdb");
       
    37 
       
    38 _LIT(KSemaphoreNameOne,		"One");
       
    39 _LIT(KSemaphoreNameTwo,		"Two");
       
    40 
       
    41 _LIT(KThreadNameOne,		"OneThread ICC");
       
    42 _LIT(KThreadNameTwo,		"TwoThread Group");
       
    43 
       
    44 
       
    45 const TInt KNumberOfGroupInserts = 200;
       
    46 const TInt KNumberOfInserts = 9*KNumberOfGroupInserts/4;
       
    47 
       
    48 const TInt KStandardTimeOut = 50000;
       
    49 
       
    50 
       
    51 static RTest					TheTest(_L("INC016848 - DB stressing - Group insert"));
       
    52 static RFs						TheFs;
       
    53 
       
    54 //
       
    55 /* CTestActiveScheduler                                                      */
       
    56 //  This class has been nicked from the t_currentdb.h / .cpp files
       
    57 class CTestActiveScheduler : public CActiveScheduler
       
    58 	{
       
    59 	public:
       
    60 		void Error (TInt aError) const;
       
    61 	};
       
    62 void CTestActiveScheduler::Error(TInt aError) const
       
    63 	{
       
    64 	User::Panic(_L("AScheduler"),aError);
       
    65 	}
       
    66 
       
    67 
       
    68 LOCAL_C void CleanupFilesL()
       
    69 	{
       
    70     // delete the database file
       
    71 	if (CContactDatabase::ContactDatabaseExistsL(KDatabaseFileName) )
       
    72 		{
       
    73 		CContactDatabase::DeleteDatabaseL(KDatabaseFileName);
       
    74 		}
       
    75 	}
       
    76 
       
    77 
       
    78 //
       
    79 /* CConcurrentDatabaseAccessBase - Specification                             */
       
    80 // Forms the base class for both threads.
       
    81 class CConcurrentDatabaseAccessBase : public CBase
       
    82 	{
       
    83 	public:
       
    84 		CConcurrentDatabaseAccessBase();
       
    85 		virtual ~CConcurrentDatabaseAccessBase();
       
    86 
       
    87 		virtual void ConstructL(const TDesC& aFilename);
       
    88 
       
    89 		void RunTestL();
       
    90 
       
    91 
       
    92 	public: // data
       
    93 		RThread					iThread;
       
    94 
       
    95 	protected:
       
    96 		void OpenSemaphore();
       
    97 		void CloseSemaphore();
       
    98 		void SyncronizeSignal();
       
    99 		void SyncronizeWait();
       
   100 		void OpenDatabaseL();
       
   101 		void CloseDatabase();
       
   102 		void SetUpTestL(const TDesC& aThreadName);
       
   103 		void CloseTest();
       
   104 
       
   105 		void OpenLogFileL(const TDesC& aFilename);
       
   106 		void CloseLogFile();
       
   107 
       
   108 		virtual void RunTestImplementationL() = 0;
       
   109 		void MoveWindow(TInt aDx);
       
   110 
       
   111 	protected:
       
   112 		CContactDatabase*		iDb;
       
   113 		//CConsoleBase*			iConsole;
       
   114 		RTest*					iTest;
       
   115 		RFile					iFile;
       
   116 
       
   117 
       
   118 	private:
       
   119 		RSemaphore				iSemaphoreSignal;
       
   120 		RSemaphore				iSemaphoreWait;
       
   121 		TBool					iSemaphoreOpen;
       
   122 		HBufC*					iDatabaseName;
       
   123 		CTestRegister* 			iFileRegister;
       
   124 	};
       
   125 
       
   126 //
       
   127 /* CConcurrentDatabaseAccessBase - Implementation                            */
       
   128 CConcurrentDatabaseAccessBase::CConcurrentDatabaseAccessBase()
       
   129 	{
       
   130 	}
       
   131 
       
   132 CConcurrentDatabaseAccessBase::~CConcurrentDatabaseAccessBase()
       
   133 	{
       
   134 	iThread.Close();
       
   135 	CloseSemaphore();
       
   136 	delete iDatabaseName;
       
   137 	if (iFileRegister)
       
   138 		delete iFileRegister;
       
   139 	}
       
   140 
       
   141 void CConcurrentDatabaseAccessBase::ConstructL(const TDesC& aFilename)
       
   142 	{
       
   143 	iDatabaseName = aFilename.AllocL();
       
   144 	}
       
   145 
       
   146 void CConcurrentDatabaseAccessBase::OpenDatabaseL()
       
   147 	{
       
   148 	iDb = CContactDatabase::OpenL(*iDatabaseName, CContactDatabase::EMultiThread);
       
   149 	}
       
   150 
       
   151 void CConcurrentDatabaseAccessBase::CloseDatabase()
       
   152 	{
       
   153 	delete iDb;
       
   154 	iDb = NULL;
       
   155 	}
       
   156 
       
   157 void CConcurrentDatabaseAccessBase::SetUpTestL(const TDesC& aThreadName)
       
   158 	{
       
   159 	// Set's up extra resources.
       
   160 	CConsoleBase* console = NULL;
       
   161 	TSize size;
       
   162 
       
   163 	// Create and name an RTest
       
   164 	iTest = new(ELeave) RTest(aThreadName);
       
   165 	iTest->Start(_L("Starting test"));
       
   166 
       
   167 	// Position our console window
       
   168 	size = iTest->Console()->ScreenSize();
       
   169 	size.iWidth = size.iWidth / 2 - 2;
       
   170 	size.iHeight = size.iHeight - 3;
       
   171 
       
   172 	console = Console::NewL(aThreadName, size);
       
   173 	delete const_cast<RTest*>(iTest)->Console();
       
   174 
       
   175 	iTest->SetConsole(console);
       
   176 	console->ClearScreen();
       
   177 	}
       
   178 
       
   179 void CConcurrentDatabaseAccessBase::CloseTest()
       
   180 	{
       
   181 	iTest->Close();
       
   182 	delete iTest;
       
   183 	iTest = NULL;
       
   184 	}
       
   185 
       
   186 void CConcurrentDatabaseAccessBase::OpenLogFileL(const TDesC& aFilename)
       
   187 	{
       
   188 	if (iFileRegister)
       
   189 		{
       
   190 		delete iFileRegister;
       
   191 		iFileRegister = NULL;
       
   192 		}
       
   193 	iFileRegister = CTestRegister::NewLC();
       
   194 	CleanupStack::Pop(iFileRegister);
       
   195 
       
   196 	// Open Debug File
       
   197 	iFileRegister->CreateLogFileLC(iFile, aFilename);
       
   198 	CleanupStack::Pop(&iFile);
       
   199 	}
       
   200 
       
   201 void CConcurrentDatabaseAccessBase::CloseLogFile()
       
   202 	{
       
   203 	iFile.Close();
       
   204 	delete iFileRegister;
       
   205 	iFileRegister = NULL;
       
   206 	}
       
   207 
       
   208 
       
   209 void CConcurrentDatabaseAccessBase::RunTestL()
       
   210 	{
       
   211 	// set's up an active scheduler for the thread
       
   212 	// and calls the RunTesImplementation function to actually
       
   213 	// preform the tests. This function should be implemented in the
       
   214 	// child class.
       
   215 	CTestActiveScheduler*  scheduler = NULL;
       
   216 
       
   217 	scheduler = new (ELeave) CTestActiveScheduler;
       
   218 	CleanupStack::PushL(scheduler);
       
   219 	CActiveScheduler::Install(scheduler);
       
   220 
       
   221 	OpenDatabaseL();
       
   222 
       
   223 	RunTestImplementationL();
       
   224 
       
   225 	CloseDatabase();
       
   226 
       
   227 	CleanupStack::PopAndDestroy( scheduler );
       
   228 	}
       
   229 
       
   230 void CConcurrentDatabaseAccessBase::OpenSemaphore()
       
   231 	{
       
   232 	TInt success = KErrNone;
       
   233 
       
   234 	success = iSemaphoreSignal.OpenGlobal( KSemaphoreNameOne );
       
   235 	if ( success == KErrNotFound )
       
   236 		{
       
   237 		iSemaphoreSignal.CreateGlobal( KSemaphoreNameOne, 0 );
       
   238 		success = KErrNone;
       
   239 		}
       
   240 
       
   241 
       
   242 	success = iSemaphoreWait.OpenGlobal( KSemaphoreNameTwo );
       
   243 	if ( success == KErrNotFound )
       
   244 		{
       
   245 		iSemaphoreWait.CreateGlobal( KSemaphoreNameTwo, 0 );
       
   246 		}
       
   247 
       
   248 	iSemaphoreOpen = ETrue;
       
   249 	}
       
   250 
       
   251 void CConcurrentDatabaseAccessBase::CloseSemaphore()
       
   252 	{
       
   253 	if (iSemaphoreOpen)
       
   254 		{
       
   255 		iSemaphoreSignal.Close();
       
   256 		iSemaphoreWait.Close();
       
   257 		}
       
   258 
       
   259 	iSemaphoreOpen = EFalse;
       
   260 	}
       
   261 
       
   262 void CConcurrentDatabaseAccessBase::SyncronizeSignal()
       
   263 	{
       
   264 	iSemaphoreSignal.Signal();
       
   265 	iSemaphoreWait.Wait();
       
   266 	}
       
   267 
       
   268 void CConcurrentDatabaseAccessBase::SyncronizeWait()
       
   269 	{
       
   270 	iSemaphoreSignal.Wait();
       
   271 	iSemaphoreWait.Signal();
       
   272 	}
       
   273 
       
   274 
       
   275 void CConcurrentDatabaseAccessBase::MoveWindow(TInt aDx)
       
   276 	{
       
   277 	const TInt scrHgtChars=iTest->Console()->ScreenSize().iHeight;
       
   278 	TMachineInfoV1Buf machineBuf;
       
   279 	UserHal::MachineInfo(machineBuf);
       
   280 	const TMachineInfoV1& machineInfo=machineBuf();
       
   281 	const TSize scrSizePixels=machineInfo.iDisplaySizeInPixels;
       
   282 	const TInt xCentre=scrSizePixels.iWidth/2;
       
   283 	const TInt xStart=scrSizePixels.iWidth/8;
       
   284 	const TInt xEnd=3*scrSizePixels.iWidth/8;
       
   285 	const TInt xMoveBy=(xEnd-xStart)/3;
       
   286 	const TInt yCentre=scrSizePixels.iHeight/2;
       
   287 	const TInt yEnd=yCentre+scrSizePixels.iHeight/scrHgtChars;
       
   288 	TRawEvent event;
       
   289 	event.Set(TRawEvent::EButton1Down,xCentre+aDx*xStart,yCentre);
       
   290 	UserSvr::AddEvent(event);
       
   291 	event.Set(TRawEvent::EPointerMove,xCentre+aDx*(xStart+xMoveBy),yEnd);
       
   292 	UserSvr::AddEvent(event);
       
   293 	event.Set(TRawEvent::EPointerMove,xCentre+aDx*(xEnd-xMoveBy),yEnd);
       
   294 	UserSvr::AddEvent(event);
       
   295 	/*event.Set(TRawEvent::EPointerMove,xCentre+aDx*xEnd,yEnd);
       
   296 	UserSvr::AddEvent(event);*/
       
   297 	event.Set(TRawEvent::EButton1Up,xCentre+aDx*xEnd,yEnd);
       
   298 	UserSvr::AddEvent(event);
       
   299 	}
       
   300 
       
   301 
       
   302 //
       
   303 /* CConcurrentDatabaseInserter - Specification                               */
       
   304 // This class is the inserter thread. It's thread function should insert
       
   305 // contacts into the database using the t_utils CRandomContactGenerator class
       
   306 class CConcurrentDatabaseInserter : public CConcurrentDatabaseAccessBase
       
   307 	{
       
   308 	public:
       
   309 		CConcurrentDatabaseInserter();
       
   310 		~CConcurrentDatabaseInserter();
       
   311 
       
   312 		static CConcurrentDatabaseInserter* NewLC(const TDesC& aFilename);
       
   313 		virtual void ConstructL(const TDesC& aFilename);
       
   314 
       
   315 		static TInt ThreadFunction(TAny* aSelf);
       
   316 
       
   317 
       
   318 	protected:
       
   319 		void	RunTestImplementationL();
       
   320 
       
   321 	private:
       
   322 	};
       
   323 
       
   324 //
       
   325 /* CConcurrentDatabaseInserter - Implementation                              */
       
   326 
       
   327 CConcurrentDatabaseInserter* CConcurrentDatabaseInserter::NewLC(const TDesC& aFilename)
       
   328 	{
       
   329 	CConcurrentDatabaseInserter* self = NULL;
       
   330 	self = new (ELeave) CConcurrentDatabaseInserter();
       
   331 	CleanupStack::PushL( self );
       
   332 	self->ConstructL(aFilename);
       
   333 	return self;
       
   334 	}
       
   335 
       
   336 CConcurrentDatabaseInserter::CConcurrentDatabaseInserter()
       
   337 	{
       
   338 	}
       
   339 
       
   340 CConcurrentDatabaseInserter::~CConcurrentDatabaseInserter()
       
   341 	{
       
   342 	}
       
   343 
       
   344 TInt CConcurrentDatabaseInserter::ThreadFunction(TAny* aSelf)
       
   345 	{
       
   346 	CConcurrentDatabaseInserter* self = STATIC_CAST(CConcurrentDatabaseInserter*, aSelf);
       
   347 
       
   348 	// Prepare the stuff required before we start the
       
   349 	// active scheduler.
       
   350 	TInt error = KErrNone;
       
   351     CTrapCleanup* cleanup = CTrapCleanup::New();
       
   352 	if	(!cleanup)
       
   353 		return KErrNoMemory;
       
   354 
       
   355 	// Call virtual handler which does anything that needs doing as
       
   356 	// a result of the thread function from being created.
       
   357 	TRAP(error, self->RunTestL());
       
   358 
       
   359 
       
   360     delete cleanup;
       
   361 	return error;
       
   362 	}
       
   363 
       
   364 void CConcurrentDatabaseInserter::ConstructL(const TDesC& aFilename)
       
   365 	{
       
   366 	CConcurrentDatabaseAccessBase::ConstructL(aFilename);
       
   367 
       
   368 	iThread.Create( KThreadNameOne, CConcurrentDatabaseInserter::ThreadFunction, KDefaultStackSize, 0x2000, 0x20000, this, EOwnerThread );
       
   369 	iThread.Resume();
       
   370 	iThread.SetPriority(EPriorityLess);
       
   371 	}
       
   372 
       
   373 
       
   374 void CConcurrentDatabaseInserter::RunTestImplementationL()
       
   375 	{
       
   376 	TInt retries = 0;
       
   377 	TInt counter = 0;
       
   378 	TInt errorCount = 0;
       
   379 	TInt bit = 0;
       
   380 	TInt leaveCode = KErrNone;
       
   381 	HBufC8* fileBuffer = HBufC8::NewL( 256 );
       
   382 	CleanupStack::PushL( fileBuffer );
       
   383 	TPtr8 ptr = fileBuffer->Des();
       
   384 
       
   385 	CRandomContactGenerator* generator = NULL;
       
   386 
       
   387 	SetUpTestL(KThreadNameOne());
       
   388 
       
   389 	generator = CRandomContactGenerator::NewL();
       
   390 	CleanupStack::PushL( generator );
       
   391 	generator->SetDbL(*iDb);
       
   392 	OpenLogFileL(_L("CConcurrentDatabaseInserter.txt"));
       
   393 
       
   394 	bit|= CContactDatabase::ESmsable;
       
   395 
       
   396 	OpenSemaphore();
       
   397 	SyncronizeWait(); // pause until corresponding Searcher thread is ready.
       
   398 
       
   399 	SyncronizeWait(); // Wait while other thread moves there window
       
   400 	MoveWindow(1);
       
   401 	SyncronizeWait(); // Tell other thread our window has moved
       
   402 
       
   403 	for (counter = 0; counter < KNumberOfInserts ; counter++)
       
   404 		{
       
   405 
       
   406 		retries = 0;
       
   407 
       
   408 		do
       
   409 			{
       
   410 			leaveCode = KErrNone;
       
   411 			retries++;
       
   412 			generator->AddTypicalContactForFilterL(bit, leaveCode);
       
   413 			iTest->Printf(_L("Insert contact %d Error=%d\n"), counter, leaveCode );
       
   414 			if ( leaveCode != KErrNone )
       
   415 				{
       
   416 				errorCount ++;
       
   417 				User::After( KStandardTimeOut * retries );
       
   418 				}
       
   419 			}
       
   420 		while ( leaveCode != KErrNone );
       
   421 
       
   422 		User::After( KStandardTimeOut ); // delay to allow second thread access.
       
   423 		}
       
   424 
       
   425 	iTest->Printf(_L("Insert contacts errorCount (retries) = %d\n"), errorCount );
       
   426 
       
   427 	CleanupStack::PopAndDestroy( generator );
       
   428 	CleanupStack::PopAndDestroy( fileBuffer );
       
   429 	ptr.Set(NULL, 0, 0);
       
   430 
       
   431 	iTest->Printf(_L("Finished, waiting for the other thread to stop\n"));
       
   432 	SyncronizeWait();
       
   433 	CloseSemaphore();
       
   434 	CloseLogFile();
       
   435 	CloseTest();
       
   436 	}
       
   437 
       
   438 //
       
   439 /* CConcurrentDBGroupInserter                                               */
       
   440 class CConcurrentDBGroupInserter : public CConcurrentDatabaseAccessBase
       
   441 	{
       
   442 	public:
       
   443 		CConcurrentDBGroupInserter();
       
   444 		~CConcurrentDBGroupInserter();
       
   445 
       
   446 		static CConcurrentDBGroupInserter* NewLC(const TDesC& aFilename);
       
   447 		virtual void ConstructL(const TDesC& aFilename);
       
   448 		static TInt ThreadFunction(TAny* aSelf);
       
   449 		static TInt FakeFunction(TAny *aParams);
       
   450 
       
   451 
       
   452 
       
   453 	protected:
       
   454 		void	RunTestImplementationL();
       
   455 
       
   456 	private:
       
   457 	};
       
   458 
       
   459 CConcurrentDBGroupInserter* CConcurrentDBGroupInserter::NewLC(const TDesC& aFilename)
       
   460 	{
       
   461 	CConcurrentDBGroupInserter* self = NULL;
       
   462 	self = new (ELeave) CConcurrentDBGroupInserter();
       
   463 	CleanupStack::PushL( self );
       
   464 	self->ConstructL(aFilename);
       
   465 	return self;
       
   466 	}
       
   467 
       
   468 CConcurrentDBGroupInserter::CConcurrentDBGroupInserter()
       
   469 	{
       
   470 	}
       
   471 
       
   472 CConcurrentDBGroupInserter::~CConcurrentDBGroupInserter()
       
   473 	{
       
   474 	}
       
   475 
       
   476 TInt CConcurrentDBGroupInserter::ThreadFunction(TAny* aSelf)
       
   477 	{
       
   478 	CConcurrentDBGroupInserter* self = static_cast<CConcurrentDBGroupInserter*>(aSelf);
       
   479 
       
   480 	// Prepare the stuff required before we start the
       
   481 	// active scheduler.
       
   482 	TInt error = KErrNone;
       
   483 
       
   484     CTrapCleanup* cleanup = CTrapCleanup::New();
       
   485 	if	(!cleanup)
       
   486 		return KErrNoMemory;
       
   487 
       
   488 	// Call virtual handler which does anything that needs doing as
       
   489 	// a result of the thread function from being created.
       
   490 	TRAP(error, self->RunTestL());
       
   491 
       
   492 
       
   493     delete cleanup;
       
   494 	return error;
       
   495 	}
       
   496 
       
   497 void CConcurrentDBGroupInserter::ConstructL(const TDesC& aFilename)
       
   498 	{
       
   499 	CConcurrentDatabaseAccessBase::ConstructL(aFilename);
       
   500 
       
   501 	iThread.Create( KThreadNameTwo, CConcurrentDBGroupInserter::ThreadFunction, KDefaultStackSize, 0x2000, 0x20000, this, EOwnerThread );
       
   502 	iThread.Resume();
       
   503 	iThread.SetPriority(EPriorityNormal);
       
   504 
       
   505 	}
       
   506 
       
   507 
       
   508 TInt CConcurrentDBGroupInserter::FakeFunction(TAny* /*aParams*/)
       
   509 	{
       
   510 	return(KErrNone);
       
   511 	}
       
   512 
       
   513 void CConcurrentDBGroupInserter::RunTestImplementationL()
       
   514 	{
       
   515 	// Prep, and get ready to run. Then before starting the search loop
       
   516 	// wait for the other thread.
       
   517 	_LIT(KGroupName, "GroupName[%d]");
       
   518 	TInt counter = 0;
       
   519 	TInt errorCount = 0;
       
   520 	TInt error = 0;
       
   521 	CContactItem* item = NULL;
       
   522 	TBuf<80> groupNameBuffer;
       
   523 
       
   524 	SetUpTestL(KThreadNameTwo());
       
   525 	OpenSemaphore();
       
   526 	SyncronizeSignal(); // wait for the other thread.
       
   527 
       
   528 	MoveWindow(-1);
       
   529 	SyncronizeSignal();	// Tell other thread our window has moved
       
   530 	SyncronizeSignal(); // Wait until other thread has moved it's window
       
   531 
       
   532 	User::After( KStandardTimeOut ); // simulate user delay,
       
   533 
       
   534 	const TInt KDelayIncrease=10000;
       
   535 	const TInt KDelayMinimum=10000;
       
   536 	const TInt KIncreaseEvery=4;
       
   537 	TInt delay=KDelayMinimum;
       
   538 	for (counter = 0; counter < KNumberOfGroupInserts; counter++)
       
   539 		{
       
   540 		User::After(delay);
       
   541 		groupNameBuffer.Format( KGroupName, counter );
       
   542 
       
   543 		FOREVER
       
   544 			{
       
   545 			// Trap the search, and display the error code on the screen
       
   546 			TRAP(error,
       
   547 				{
       
   548 				item = iDb->CreateContactGroupLC( KGroupName, /* t/f ? */ EFalse );
       
   549 				CleanupStack::PopAndDestroy( item );
       
   550 				item = NULL;
       
   551 				});
       
   552 
       
   553 			iTest->Printf(_L("Insert Group %d Error=%d\n"), counter, error );
       
   554 			if( error == KErrNone )
       
   555 				break;
       
   556 
       
   557 			errorCount ++;
       
   558 			// bail for any error other than Locked
       
   559 			if (error != KErrLocked)
       
   560 				{
       
   561 				TRAP_IGNORE(CleanupFilesL());
       
   562 				}
       
   563 			(*iTest)( error == KErrLocked );
       
   564 			}
       
   565 
       
   566 		if (counter%KIncreaseEvery==KIncreaseEvery-1)
       
   567 			delay+=KDelayIncrease;
       
   568 		}
       
   569 
       
   570 	iTest->Printf(_L("Create contact groups errorCount (retries) = %d\n"), errorCount );
       
   571 
       
   572 	iTest->Printf(_L("Finished, waiting for the other thread to stop\n"));
       
   573 
       
   574 //The errorCount counts the number of times the call to CreateContactGroupLC above returns
       
   575 //KErrLocked. On hardware it is expected that KErrLocked will occur when a write is attempted and the
       
   576 //other thread has a lock on the database.  Due to the Wins threading model this should be 0 on Wins.
       
   577 //This harness can therefore be used as a benchmark on harware and the number of KErrLocked
       
   578 //contentions observed manually.
       
   579 #ifdef __WINS__
       
   580 	if (errorCount != 0)
       
   581 		{
       
   582 		TRAP_IGNORE(CleanupFilesL());
       
   583 		}
       
   584 	(*iTest)( errorCount == 0 );
       
   585 #endif
       
   586 	SyncronizeSignal();
       
   587 	CloseSemaphore();
       
   588 	CloseTest();
       
   589 	}
       
   590 
       
   591 //
       
   592 /* Test Function Prototypes                                                  */
       
   593 //
       
   594 void CreateTestDatabaseL(const TDesC& aFilename );
       
   595 void TestL();
       
   596 void doMainL();
       
   597 
       
   598 //
       
   599 /* Test Function Implementations                                             */
       
   600 //
       
   601 void CreateTestDatabaseL(const TDesC& aFilename )
       
   602 	{
       
   603 	CContactDatabase* database = NULL;
       
   604 
       
   605 	database = CContactDatabase::ReplaceL(aFilename);
       
   606 	CleanupStack::PushL( database );
       
   607 
       
   608 	CleanupStack::PopAndDestroy( database );
       
   609 	}
       
   610 
       
   611 
       
   612 void TestL()
       
   613 	{
       
   614 	TRequestStatus groupThread;
       
   615 	TRequestStatus inserterThread;
       
   616 	CConcurrentDBGroupInserter* groupInserter = NULL;
       
   617 	CConcurrentDatabaseInserter* inserter = NULL;
       
   618 	TCntProfile profile[1];
       
   619 
       
   620 	CreateTestDatabaseL( KDatabaseFileName );
       
   621 
       
   622 	CCntTest::ProfileStart(0);
       
   623 
       
   624 	groupInserter = CConcurrentDBGroupInserter::NewLC( KDatabaseFileName );
       
   625 	inserter = CConcurrentDatabaseInserter::NewLC( KDatabaseFileName );
       
   626 
       
   627 	groupInserter->iThread.Logon(groupThread);
       
   628 	inserter->iThread.Logon(inserterThread);
       
   629 
       
   630 	User::WaitForRequest(groupThread);
       
   631 	User::WaitForRequest(inserterThread);
       
   632 
       
   633 	CCntTest::ProfileEnd(0);
       
   634 	CCntTest::ProfileResult(profile, 0, 1);
       
   635 
       
   636 	RDebug::Print(_L("Time taken (secs) %f\n"), profile[0].iTime/1000000.0);
       
   637 
       
   638 	CleanupStack::PopAndDestroy( inserter );
       
   639 	CleanupStack::PopAndDestroy( groupInserter );
       
   640 
       
   641 	}
       
   642 
       
   643 
       
   644 //
       
   645 // -------> Static global functions (source)
       
   646 //
       
   647 void doMainL()
       
   648 	{
       
   649 	User::LeaveIfError( TheFs.Connect() );
       
   650 	CleanupClosePushL(TheFs);
       
   651 
       
   652 	CTestRegister* TempFiles = CTestRegister::NewLC();
       
   653 	TempFiles->RegisterL(KDatabaseFileName, EFileTypeCnt);
       
   654 
       
   655 	// Delete any existing ini file so that we can be sure this test is ok
       
   656 	TestL();
       
   657 
       
   658 	CleanupStack::PopAndDestroy(2, &TheFs );
       
   659 
       
   660 	}
       
   661 
       
   662 /**
       
   663 
       
   664 @SYMTestCaseID     PIM-T-ICCIMPORTLOCK-0001
       
   665 
       
   666 */
       
   667 
       
   668 GLDEF_C TInt E32Main()
       
   669 	{
       
   670 	CTestActiveScheduler*  scheduler = new CTestActiveScheduler;
       
   671 	CActiveScheduler::Install(scheduler);
       
   672 	CTrapCleanup* cleanupStack = NULL;
       
   673 	__UHEAP_MARK;
       
   674 	TheTest.Start(_L("@SYMTESTCaseID:PIM-T-ICCIMPORTLOCK-0001 Multi session testcode"));
       
   675 
       
   676 	TheTest.Title();
       
   677 	cleanupStack = CTrapCleanup::New();
       
   678 	TRAPD(ret, doMainL());
       
   679     // ensure files are cleaned up even if doMainL() leaves
       
   680     TRAP_IGNORE(CleanupFilesL() );
       
   681 	TheTest(ret == KErrNone);
       
   682 	delete cleanupStack;
       
   683 	delete scheduler;
       
   684 
       
   685 	TheTest.End();
       
   686 	TheTest.Close();
       
   687 	__UHEAP_MARKEND;
       
   688 	return(KErrNone);
       
   689 	}