kerneltest/e32test/system/d_dobject.cpp
changeset 0 a41df078684a
child 62 4a8fed1c0ef6
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     1 // Copyright (c) 2004-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 the License "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 // e32test\system\d_dobject.cpp
       
    15 // LDD for testing RObjectIx class
       
    16 // 
       
    17 //
       
    18 
       
    19 #include <kernel/kern_priv.h>
       
    20 #include "d_dobject.h"
       
    21 #include "../misc/prbs.h"
       
    22 
       
    23 
       
    24 //
       
    25 // Handle Mutex referenced from ObjectIx.cpp (normally from sglobals.cpp).
       
    26 //
       
    27 DMutex* RObjectIx::HandleMutex;
       
    28 
       
    29 //
       
    30 // Constants for test sizes and stepings...
       
    31 //
       
    32 const TInt KDObjectTestMaxTestSize  = 2000;	// Bigest size to test
       
    33 const TInt KDObjectTestStepStart    = 19;	// Test all values below this
       
    34 const TInt KDObjectTestStep         = 31;	// Step value used when above KDObjectTestStepStart.
       
    35 const TInt KDObjectTestLoopCount    = 3;	// Loop count used in some tests to repeat random testing.
       
    36 
       
    37 
       
    38 //
       
    39 // LDD factory
       
    40 //
       
    41 
       
    42 class DObjectTestFactory : public DLogicalDevice
       
    43 	{
       
    44 public:
       
    45 	DObjectTestFactory();
       
    46 	~DObjectTestFactory();
       
    47 	virtual TInt Install();
       
    48 	virtual void GetCaps(TDes8& aDes) const;
       
    49 	virtual TInt Create(DLogicalChannelBase*& aChannel);
       
    50 public:
       
    51 	};
       
    52 
       
    53 //
       
    54 // Logical Channel
       
    55 //
       
    56 const TInt KObjectIndexMask=0x7fff;
       
    57 
       
    58 class DObjectTest : public DLogicalChannelBase
       
    59 	{
       
    60 public:
       
    61 	virtual ~DObjectTest();
       
    62 protected:
       
    63 	virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
       
    64 	virtual TInt Request(TInt aFunction, TAny* a1, TAny* a2);
       
    65 public:
       
    66 	DObjectTestFactory* iFactory;
       
    67 
       
    68 private:
       
    69 	TInt RObjectIxTest1(TInt aSize);
       
    70 	TInt RObjectIxTest2(TInt aSize);
       
    71 	TInt RObjectIxTest3(TInt aSize, TBool aPerformanceTest);
       
    72 	TInt RObjectIxTest4(TInt aSize);
       
    73 	TInt RObjectIxTestExerciseIx(RObjectIx& aObjectIx, TInt aSize);
       
    74 	TInt RObjectIxInvalidHandleLookupTest(TInt aSize);
       
    75 	TInt DObjectNameTest();
       
    76 
       
    77 	inline TInt Index(TInt aHandle)	{return(aHandle&KObjectIndexMask);}
       
    78 
       
    79 private:
       
    80 	struct DOBjAndHandle
       
    81 		{
       
    82 		DObject* iObject;
       
    83 		TInt	 iHandle;
       
    84 		};
       
    85 
       
    86 	TUint iSeed[2];
       
    87 	DOBjAndHandle* iObjAndHandle;	
       
    88 	};
       
    89 
       
    90 //
       
    91 // LDD factory
       
    92 //
       
    93 
       
    94 DObjectTestFactory::DObjectTestFactory()
       
    95 	{
       
    96 	Kern::MutexCreate(RObjectIx::HandleMutex, _L("HandleMutex"), KMutexOrdHandle);
       
    97 	}
       
    98 
       
    99 DObjectTestFactory::~DObjectTestFactory()
       
   100 	{
       
   101 	delete RObjectIx::HandleMutex;
       
   102 	RObjectIx::HandleMutex = NULL;
       
   103 	}
       
   104 
       
   105 TInt DObjectTestFactory::Create(DLogicalChannelBase*& aChannel)
       
   106 	{
       
   107 	aChannel=new DObjectTest;
       
   108 	return KErrNone;
       
   109 	}
       
   110 
       
   111 TInt DObjectTestFactory::Install()
       
   112 	{
       
   113 	return SetName(&KDObjectTestLddName);
       
   114 	}
       
   115 
       
   116 void DObjectTestFactory::GetCaps(TDes8& /* aDes */) const
       
   117 	{
       
   118 	//aDes.FillZ(aDes.MaxLength());
       
   119 	}
       
   120 
       
   121 DECLARE_STANDARD_LDD()
       
   122 	{
       
   123 	return new DObjectTestFactory;
       
   124 	}
       
   125 
       
   126 //
       
   127 // Logical Channel
       
   128 //
       
   129 
       
   130 TInt DObjectTest::DoCreate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& /*aVer*/)
       
   131 	{
       
   132 	if (NULL == (iObjAndHandle = (DOBjAndHandle*)Kern::Alloc(KDObjectTestMaxTestSize * sizeof(DOBjAndHandle))))
       
   133 		return KErrNoMemory;
       
   134 	return KErrNone;
       
   135 	}
       
   136 
       
   137 DObjectTest::~DObjectTest()
       
   138 	{
       
   139 	delete[] iObjAndHandle;
       
   140 	}
       
   141 
       
   142 
       
   143 //Adds a number of DObjects to RObjectIx, then removes them in the same order.
       
   144 TInt DObjectTest::RObjectIxTest1(TInt aSize)
       
   145 {
       
   146 	TInt i,r;
       
   147 	DObject* object;
       
   148 	RObjectIx  myIx;
       
   149 
       
   150 	myIx.Check(0);
       
   151 
       
   152 	for (i=0; i<aSize; i++) //Add
       
   153 		{
       
   154 		if( (iObjAndHandle[i].iObject = new DObject) == NULL) 
       
   155 			{
       
   156 			myIx.Close(NULL);
       
   157 			return KErrNoMemory;
       
   158 			}
       
   159 		iObjAndHandle[i].iObject->iContainerID = 0;
       
   160 		r = myIx.Add(iObjAndHandle[i].iObject, 0);
       
   161 		if (r<0)
       
   162 			{
       
   163 			myIx.Check(0);
       
   164 			myIx.Close(NULL);
       
   165 			return r;
       
   166 			}
       
   167 		iObjAndHandle[i].iHandle = r;
       
   168 		}
       
   169 
       
   170 	myIx.Check(0);
       
   171 	
       
   172 	for (i=0; i<aSize; i++)		//Remove
       
   173 		{
       
   174 		TUint32  attr = 0; // Receives the attributes of the removed handle...
       
   175 
       
   176 		if (KErrNone != (r=myIx.Remove(iObjAndHandle[i].iHandle, object, attr))) 
       
   177 			{
       
   178 			myIx.Check(0);
       
   179 			myIx.Close(NULL);
       
   180 			return r;
       
   181 			}
       
   182 		iObjAndHandle[i].iObject->Close(NULL);
       
   183 		}
       
   184 
       
   185 	myIx.Check(0);
       
   186 	myIx.Close(NULL);
       
   187 
       
   188 	return KErrNone;
       
   189 }
       
   190 
       
   191 //Adds a number of DObjects to RObjectIx, then removes them in the reverse order.
       
   192 TInt DObjectTest::RObjectIxTest2(TInt aSize)
       
   193 {
       
   194 	TInt i,r;
       
   195 	DObject* object;
       
   196 	RObjectIx myIx;
       
   197 	
       
   198 	myIx.Check(0);
       
   199 
       
   200 	for (i=0; i<aSize; i++) //Add
       
   201 		{
       
   202 		if( (iObjAndHandle[i].iObject = new DObject) == NULL) 
       
   203 			{
       
   204 			myIx.Close(NULL);
       
   205 			return KErrNoMemory;
       
   206 			}
       
   207 		iObjAndHandle[i].iObject->iContainerID = 0;
       
   208 		r = myIx.Add(iObjAndHandle[i].iObject, 0);
       
   209 		if (r<0)
       
   210 			{
       
   211 			myIx.Check(0);
       
   212 			myIx.Close(NULL);
       
   213 			return r;
       
   214 			}
       
   215 		iObjAndHandle[i].iHandle = r;
       
   216 		}
       
   217 
       
   218 	myIx.Check(0);
       
   219 
       
   220 	for (i=aSize-1; i>=0; i--)		//Remove in reverse
       
   221 		{
       
   222 		TUint32  attr = 0; // Receives the attributes of the removed handle...
       
   223 
       
   224 		if (KErrNone != (r=myIx.Remove(iObjAndHandle[i].iHandle, object, attr))) 
       
   225 			{
       
   226 			myIx.Check(0);
       
   227 			myIx.Close(NULL);
       
   228 			return r;
       
   229 			}
       
   230 		iObjAndHandle[i].iObject->Close(NULL);
       
   231 		}
       
   232 
       
   233 	myIx.Check(0);
       
   234 	myIx.Close(NULL);
       
   235 
       
   236 	return KErrNone;
       
   237 }
       
   238 
       
   239 //Adds and removes random number of DObjects to/from RObjectIx.
       
   240 TInt DObjectTest::RObjectIxTest3(TInt aSize, TBool aPerformanceTest)
       
   241 {
       
   242 	TInt index, x, r;
       
   243 	DObject* object;
       
   244 	RObjectIx myIx;
       
   245 
       
   246 	//---Create & init the objects we need
       
   247 	for (x=0; x<aSize; x++) iObjAndHandle[x].iObject = NULL; //initialize the array
       
   248 
       
   249 	if (!aPerformanceTest)
       
   250 		myIx.Check(0);
       
   251 
       
   252 	for (x = 0;  x < KDObjectTestLoopCount;  x++)
       
   253 		{
       
   254 		
       
   255 		//---Add the random number of objects (in random order)---
       
   256 		TInt toAdd=Random(iSeed)%(aSize-myIx.ActiveCount()+1);
       
   257 		while (toAdd--)
       
   258 			{
       
   259 			index=Random(iSeed)%aSize;
       
   260 			while (iObjAndHandle[index].iObject) index=(index+1)%aSize; //Find the next NULL pointer 
       
   261 			if( (iObjAndHandle[index].iObject = new DObject) == NULL) 
       
   262 				{
       
   263 				myIx.Close(NULL);
       
   264 				return KErrNoMemory;
       
   265 				}
       
   266 			r = myIx.Add(iObjAndHandle[index].iObject, 0);
       
   267 			if (r<0)
       
   268 				{
       
   269 				if (!aPerformanceTest)
       
   270 					myIx.Check(0);
       
   271 				myIx.Close(NULL);
       
   272 				return r;
       
   273 				}
       
   274 			iObjAndHandle[index].iHandle = r;
       
   275 			}
       
   276 
       
   277 		if (!aPerformanceTest)
       
   278 			myIx.Check(0);
       
   279 
       
   280 		//---Remove the random number of objects (in random order)---
       
   281 		TInt toRemove=Random(iSeed)%(myIx.ActiveCount()+1);
       
   282 		while (toRemove--)
       
   283 			{
       
   284 			index=Random(iSeed)%aSize;
       
   285 			while (!iObjAndHandle[index].iObject) index=(index+1)%aSize; //Find the next non-NULL pointer 
       
   286 
       
   287 			TUint32  attr = 0; // Receives the attributes of the removed handle...
       
   288 
       
   289 			if (KErrNone != (r=myIx.Remove(iObjAndHandle[index].iHandle, object, attr)))
       
   290 				{
       
   291 				if (!aPerformanceTest)
       
   292 					myIx.Check(0);
       
   293 				myIx.Close(NULL);
       
   294 				return r;
       
   295 				}
       
   296 			iObjAndHandle[index].iObject->Close(NULL);
       
   297 			iObjAndHandle[index].iObject=NULL;
       
   298 			}
       
   299 
       
   300 		if(aPerformanceTest) continue;
       
   301 
       
   302 		myIx.Check(0);
       
   303 
       
   304 		//---Test data consistency---
       
   305 		TInt objNum=0;
       
   306 		for (index=0;index<aSize;index++) 
       
   307 			{
       
   308 			if (iObjAndHandle[index].iObject)
       
   309 				{
       
   310 				objNum++;
       
   311 				
       
   312 				//Test At(TInt aHandle) method
       
   313 				NKern::LockSystem();
       
   314 				if (iObjAndHandle[index].iObject != myIx.At(iObjAndHandle[index].iHandle))
       
   315 					{
       
   316 					NKern::UnlockSystem();
       
   317 					myIx.Check(0);
       
   318 					myIx.Close(NULL);
       
   319 					return KErrGeneral;
       
   320 					}
       
   321 				NKern::UnlockSystem();
       
   322 
       
   323 				
       
   324 				//Test Count(CObject* aObject) method
       
   325 				RObjectIx::Wait();
       
   326 				if (1!=myIx.Count(iObjAndHandle[index].iObject))
       
   327 					{
       
   328 					RObjectIx::Signal();
       
   329 					myIx.Check(0);
       
   330 					myIx.Close(NULL);
       
   331 					return KErrGeneral;
       
   332 					}
       
   333 				
       
   334 				//Test At(CObject* aObject) method
       
   335 				if (iObjAndHandle[index].iHandle != myIx.At(iObjAndHandle[index].iObject))
       
   336 					{
       
   337 					RObjectIx::Signal();
       
   338 					myIx.Check(0);
       
   339 					myIx.Close(NULL);
       
   340 					return KErrGeneral;
       
   341 					}
       
   342 				RObjectIx::Signal();
       
   343 
       
   344 				//Test operator[](TInt index) method
       
   345 				NKern::LockSystem();
       
   346 				if (iObjAndHandle[index].iObject != myIx[Index(iObjAndHandle[index].iHandle)])
       
   347 					{
       
   348 					NKern::UnlockSystem();
       
   349 					myIx.Check(0);
       
   350 					myIx.Close(NULL);
       
   351 					return KErrGeneral;
       
   352 					}
       
   353 				NKern::UnlockSystem();
       
   354 
       
   355 				}
       
   356 			}
       
   357 	
       
   358 		if (objNum != myIx.ActiveCount())
       
   359 			{
       
   360 			myIx.Check(0);
       
   361 			myIx.Close(NULL);
       
   362 			return KErrGeneral;
       
   363 			}
       
   364 		}
       
   365 
       
   366 	myIx.Check(0);
       
   367 	myIx.Close(NULL);
       
   368 
       
   369 	return KErrNone;
       
   370 }
       
   371 
       
   372 
       
   373 //Adds a number of DObjects to RObjectIx using reserved slots, then removes
       
   374 // them in the same order. Repeat using the reverse order.
       
   375 TInt DObjectTest::RObjectIxTest4(TInt aSize)
       
   376 	{
       
   377 	TInt i,r;
       
   378 	DObject* object;
       
   379 	RObjectIx myIx;
       
   380 
       
   381 	myIx.Check(0);
       
   382 	myIx.Reserve(aSize);
       
   383 	myIx.Check(0);
       
   384 	myIx.Reserve(-aSize);
       
   385 	myIx.Check(0);
       
   386 	myIx.Reserve(aSize);
       
   387 	myIx.Check(0);
       
   388 	
       
   389 	for (i=0; i<aSize; i++) //Add
       
   390 		{
       
   391 		if( (iObjAndHandle[i].iObject = new DObject) == NULL) 
       
   392 			{
       
   393 			myIx.Check(0);
       
   394 			myIx.Close(NULL);
       
   395 			return KErrNoMemory;
       
   396 			}
       
   397 		iObjAndHandle[i].iObject->iContainerID = 0;
       
   398 		r = myIx.Add(iObjAndHandle[i].iObject, (TUint32)RObjectIx::EReserved);
       
   399 		if (r<0)
       
   400 			{
       
   401 			myIx.Check(0);
       
   402 			myIx.Close(NULL);
       
   403 			return r;
       
   404 			}
       
   405 		iObjAndHandle[i].iHandle = r;
       
   406 		}
       
   407 
       
   408 	myIx.Check(0);
       
   409 
       
   410 	TInt toRemove=Random(iSeed)%(myIx.ActiveCount()+1);
       
   411 	TInt toAdd=toRemove; // will put them all back again...
       
   412 	while (toRemove--)
       
   413 		{
       
   414 		i=Random(iSeed)%aSize;
       
   415 		while (!iObjAndHandle[i].iObject) i=(i+1)%aSize; //Find the next non-NULL pointer 
       
   416 
       
   417 		TUint32  attr = 0; // Receives the attributes of the removed handle...
       
   418 
       
   419 		if (KErrNone != (r=myIx.Remove(iObjAndHandle[i].iHandle, object, attr))) 
       
   420 			{
       
   421 			myIx.Check(0);
       
   422 			myIx.Close(NULL);
       
   423 			return r;
       
   424 			}
       
   425 		if ((attr & RObjectIx::EReserved) == 0) 
       
   426 			{
       
   427 			myIx.Check(0);
       
   428 			myIx.Close(NULL);
       
   429 			return KErrBadHandle;
       
   430 			}
       
   431 		iObjAndHandle[i].iObject->Close(NULL);
       
   432 		iObjAndHandle[i].iObject = NULL;
       
   433 		}
       
   434 
       
   435 	myIx.Check(0);
       
   436 
       
   437 	while (toAdd--)
       
   438 		{
       
   439 		i=Random(iSeed)%aSize;
       
   440 		while (iObjAndHandle[i].iObject) i=(i+1)%aSize; //Find the next NULL pointer 
       
   441 
       
   442 		if( (iObjAndHandle[i].iObject = new DObject) == NULL) 
       
   443 			{
       
   444 			myIx.Check(0);
       
   445 			myIx.Close(NULL);
       
   446 			return KErrNoMemory;
       
   447 			}
       
   448 		iObjAndHandle[i].iObject->iContainerID = 0;
       
   449 		r = myIx.Add(iObjAndHandle[i].iObject, (TUint32)RObjectIx::EReserved);
       
   450 		if (r<0)
       
   451 			{
       
   452 			myIx.Check(0);
       
   453 			myIx.Close(NULL);
       
   454 			return r;
       
   455 			}
       
   456 		iObjAndHandle[i].iHandle = r;
       
   457 		}
       
   458 
       
   459 	myIx.Check(0);
       
   460 
       
   461 	for (i=aSize-1; i>=0; i--)		//Remove in reverse
       
   462 		{
       
   463 		TUint32  attr = 0; // Receives the attributes of the removed handle...
       
   464 
       
   465 		if (KErrNone != (r=myIx.Remove(iObjAndHandle[i].iHandle, object, attr))) 
       
   466 			{
       
   467 			myIx.Check(0);
       
   468 			myIx.Close(NULL);
       
   469 			return r;
       
   470 			}
       
   471 		if ((attr & RObjectIx::EReserved) == 0) 
       
   472 			{
       
   473 			myIx.Check(0);
       
   474 			myIx.Close(NULL);
       
   475 			return KErrBadHandle;
       
   476 			}
       
   477 		iObjAndHandle[i].iObject->Close(NULL);
       
   478 		iObjAndHandle[i].iObject = NULL;
       
   479 		}
       
   480 
       
   481 	myIx.Check(0);
       
   482 	myIx.Close(NULL);
       
   483 
       
   484 	return KErrNone;
       
   485 	} // DObjectTest::RObjectIxTest4
       
   486 
       
   487 
       
   488 // Adds a number of DObjects to RObjectIx using both normal and reserved slots, plus
       
   489 // unused reserved slots then removes
       
   490 // them in the same order. Repeat using the reverse order. Used in concurrent
       
   491 // testing with multiple threads.
       
   492 TInt DObjectTest::RObjectIxTestExerciseIx(RObjectIx& aObjectIx, TInt aSize)
       
   493 	{
       
   494 	TInt i,r;
       
   495 	DObject* object;
       
   496 
       
   497 	aObjectIx.Check(0);
       
   498 
       
   499 	for (i=0; i<aSize; i++) //Add and reserve (causing a Grow())...
       
   500 		{
       
   501 		// we reserve handles because it encourages grow and shrinking of the pool
       
   502 		aObjectIx.Reserve(1);
       
   503 
       
   504 		if( (iObjAndHandle[i].iObject = new DObject) == NULL)
       
   505 			{
       
   506 			return KErrNoMemory;
       
   507 			}
       
   508 		iObjAndHandle[i].iObject->iContainerID = 0;
       
   509 		r = aObjectIx.Add(iObjAndHandle[i].iObject, i&0x1 ? (TUint32)RObjectIx::EReserved : 0);
       
   510 		if (r<0)
       
   511 			{
       
   512 			return r;
       
   513 			}
       
   514 		iObjAndHandle[i].iHandle = r;
       
   515 		}
       
   516 
       
   517 	//---Test data consistency---
       
   518 	for (i=0;i<aSize;i++)
       
   519 		{
       
   520 		if (iObjAndHandle[i].iObject)
       
   521 			{
       
   522 			//Test At(TInt aHandle) method
       
   523 			NKern::LockSystem();
       
   524 			if (iObjAndHandle[i].iObject != aObjectIx.At(iObjAndHandle[i].iHandle))
       
   525 				{
       
   526 				NKern::UnlockSystem();
       
   527 				return KErrGeneral;
       
   528 				}
       
   529 			NKern::UnlockSystem();
       
   530 			}
       
   531 		}
       
   532 
       
   533 	aObjectIx.Check(0);
       
   534 
       
   535 	for (i=0; i<aSize; i++)		//Remove
       
   536 		{
       
   537 		TUint32  attr = 0; // Receives the attributes of the removed handle...
       
   538 		if (KErrNone != (r=aObjectIx.Remove(iObjAndHandle[i].iHandle, object, attr)))
       
   539 			{
       
   540 			return r;
       
   541 			}
       
   542 
       
   543 		if ((i&0x1) && ((attr & RObjectIx::EReserved) == 0))
       
   544 			{
       
   545 			return KErrBadHandle;
       
   546 			}
       
   547 
       
   548 		iObjAndHandle[i].iObject->Close(NULL);
       
   549 		iObjAndHandle[i].iObject = NULL;
       
   550 		}
       
   551 
       
   552 	aObjectIx.Check(0);
       
   553 
       
   554 	for (i=0; i<aSize; i++) //Add
       
   555 		{
       
   556 		if( (iObjAndHandle[i].iObject = new DObject) == NULL)
       
   557 			{
       
   558 			return KErrNoMemory;
       
   559 			}
       
   560 		iObjAndHandle[i].iObject->iContainerID = 0;
       
   561 		r = aObjectIx.Add(iObjAndHandle[i].iObject, i&0x1 ?  (TUint32)RObjectIx::EReserved : 0);
       
   562 		if (r<0)
       
   563 			{
       
   564 			return r;
       
   565 			}
       
   566 		iObjAndHandle[i].iHandle = r;
       
   567 		}
       
   568 
       
   569 	//---Test data consistency---
       
   570 	for (i=0;i<aSize;i++)
       
   571 		{
       
   572 		if (iObjAndHandle[i].iObject)
       
   573 			{
       
   574 			NKern::LockSystem();
       
   575 			//Test At(TInt aHandle) method
       
   576 			if (iObjAndHandle[i].iObject != aObjectIx.At(iObjAndHandle[i].iHandle))
       
   577 				{
       
   578 				NKern::UnlockSystem();
       
   579 				return KErrGeneral;
       
   580 				}
       
   581 			NKern::UnlockSystem();
       
   582 			}
       
   583 		}
       
   584 
       
   585 	aObjectIx.Check(0);
       
   586 
       
   587 	for (i=aSize-1; i>=0; i--)		//Remove in reverse
       
   588 		{
       
   589 		TUint32  attr = 0; // Receives the attributes of the removed handle...
       
   590 		if (KErrNone != (r=aObjectIx.Remove(iObjAndHandle[i].iHandle, object, attr)))
       
   591 			{
       
   592 			return r;
       
   593 			}
       
   594 		if ((i&0x1) && ((attr & RObjectIx::EReserved) == 0))
       
   595 			{
       
   596 			return KErrBadHandle;
       
   597 			}
       
   598 
       
   599 		iObjAndHandle[i].iObject->Close(NULL);
       
   600 
       
   601 		aObjectIx.Reserve(-1); // Remove a reserved object causing a TidyAndCompact()...
       
   602 		}
       
   603 
       
   604 	aObjectIx.Check(0);
       
   605 
       
   606 	return KErrNone;
       
   607 	} // DObjectTest::RObjectIxTestExerciseIx
       
   608 
       
   609 
       
   610 /**
       
   611  *  Adds a number of DObjects to RObjectIx, tries random invalid handle to access them,
       
   612  *  then attempts removes them in the same order.
       
   613  * 
       
   614  *  @param aSize  Size of handle array to use.
       
   615  * 
       
   616  *  @return KErrNone or standard error code.
       
   617  */
       
   618 TInt DObjectTest::RObjectIxInvalidHandleLookupTest(TInt aSize)
       
   619 	{
       
   620 	TInt  i, r;
       
   621 	DObject*  object;
       
   622 	RObjectIx myIx;
       
   623 
       
   624 	myIx.Check(0);
       
   625 
       
   626 	//
       
   627 	// Add in some DObjects...
       
   628 	//
       
   629 	for (i = 0;  i < aSize;  i++)
       
   630 		{
       
   631 		if ((iObjAndHandle[i].iObject = new DObject) == NULL) 
       
   632 			{
       
   633 			myIx.Check(0);
       
   634 			myIx.Close(NULL);
       
   635 			return KErrNoMemory;
       
   636 			}
       
   637 
       
   638 		iObjAndHandle[i].iObject->iContainerID = 0;
       
   639 
       
   640 		r = myIx.Add(iObjAndHandle[i].iObject, 0);
       
   641 		if (r < 0)
       
   642 			{
       
   643 			myIx.Check(0);
       
   644 			myIx.Close(NULL);
       
   645 			return r;
       
   646 			}
       
   647 		iObjAndHandle[i].iHandle = r;
       
   648 		}
       
   649 
       
   650 	myIx.Check(0);
       
   651 
       
   652 	//
       
   653 	// Randomly attempt to access handles...
       
   654 	//
       
   655 	TInt  handlesToTest = aSize * KDObjectTestLoopCount;
       
   656 	TInt  count;
       
   657 	
       
   658 	for (count = 0;  count < handlesToTest;  count++)
       
   659 		{
       
   660 		//
       
   661 		// A handle looks like this:
       
   662 		//	Bits 0-14	index
       
   663 		//	Bit 15		no-close flag (ignored)
       
   664 		//	Bits 16-29	instance value
       
   665 		//	Bit 30		thread local flag (ignored)
       
   666 		//	Bit 31		special handle flag (should be 0)
       
   667 		//
       
   668 		NKern::LockSystem();
       
   669 		TInt  randomHandle = Kern::Random() & 0x3fff7fff;
       
   670 		TInt  uniqueID = 0;		// any object type!
       
   671 				
       
   672 		object = myIx.At(randomHandle, uniqueID);
       
   673 		NKern::UnlockSystem();
       
   674 
       
   675 		if (object != NULL)
       
   676 			{
       
   677 			//
       
   678 			// We've picked a valid handle, this is unlikely but check if
       
   679 			// it is really valid...
       
   680 			//
       
   681 			TBool  found = EFalse;
       
   682 			
       
   683 			for (i = 0;  i < aSize;  i++)
       
   684 				{
       
   685 				if (iObjAndHandle[i].iHandle == randomHandle  &&
       
   686 					iObjAndHandle[i].iObject == object)
       
   687 					{
       
   688 					found = ETrue;
       
   689 					break;
       
   690 					}
       
   691 				}
       
   692 			
       
   693 			if (found == EFalse) 
       
   694 				{
       
   695 				myIx.Check(0);
       
   696 				myIx.Close(NULL);
       
   697 				return KErrBadHandle;
       
   698 				}
       
   699 			}
       
   700 		}
       
   701 	
       
   702 	myIx.Check(0);
       
   703 
       
   704 	//
       
   705 	// Remove the DObjects...
       
   706 	//
       
   707 	for (i = 0;  i < aSize;  i++)
       
   708 		{
       
   709 		TUint32  attr = 0; // Receives the attributes of the removed handle...
       
   710 
       
   711 		if (KErrNone != (r=myIx.Remove(iObjAndHandle[i].iHandle, object, attr))) 
       
   712 			{
       
   713 			myIx.Check(0);
       
   714 			myIx.Close(NULL);
       
   715 			return r;
       
   716 			}
       
   717 
       
   718 		iObjAndHandle[i].iObject->Close(NULL);
       
   719 		}
       
   720 
       
   721 	myIx.Check(0);
       
   722 	myIx.Close(NULL);
       
   723 
       
   724 	return KErrNone;
       
   725 	} // DObjectTest::RObjectIxInvalidHandleLookupTest
       
   726 
       
   727 
       
   728 TInt DObjectTest::DObjectNameTest()
       
   729 	{
       
   730 #define TEST_GOOD_NAME(name) if (Kern::ValidateName(name) != KErrNone) return KErrBadName;
       
   731 #define TEST_BAD_NAME(name) if (Kern::ValidateName(name) != KErrBadName) return KErrBadName;
       
   732 #define TEST_GOOD_FULLNAME(name) if (Kern::ValidateFullName(name) != KErrNone) return KErrBadName;
       
   733 #define TEST_BAD_FULLNAME(name) if (Kern::ValidateFullName(name) != KErrBadName) return KErrBadName;
       
   734 	
       
   735 	
       
   736 	_LIT(KGoodName1,"DObject1 ABCDEFGHIJKLMNOPRSTUVWXYZ0123456789");
       
   737 	_LIT(KGoodName2,"DObject2 abdefghijklmnoprstuvwxyz!\"#$%&'()+,-./;<=>@[\\]^_`{|}~");
       
   738 	_LIT(KGoodFullName1,"DObject :3");
       
   739 	_LIT(KBadName1,"DObject 5 *");
       
   740 	_LIT(KBadName2,"DObject 6 ?");
       
   741 	TUint8 badName3[] = {'D','O','b','j','e','c','t',0x00};
       
   742 	TUint8 badName4[] = {'D','O','b','j','e','c','t',0x1f};
       
   743 	TUint8 badName5[] = {'D','O','b','j','e','c','t',0x7f};
       
   744 	TUint8 badName6[] = {'D','O','b','j','e','c','t',0xff};
       
   745 	TPtr8 badNamePtr(badName3, sizeof(badName3), sizeof(badName3));
       
   746 	
       
   747 	// Test Kern::ValidateName for good and bad names
       
   748 	TEST_GOOD_NAME(KGoodName1);
       
   749 	TEST_GOOD_NAME(KGoodName2);
       
   750 	TEST_BAD_NAME(KGoodFullName1);
       
   751 	TEST_BAD_NAME(KBadName1);
       
   752 	TEST_BAD_NAME(KBadName2);
       
   753 	TEST_BAD_NAME(badNamePtr); // already set to badName3 as no TPtr8 default constructor
       
   754 	badNamePtr.Set(badName4, sizeof(badName4), sizeof(badName4));
       
   755 	TEST_BAD_NAME(badNamePtr);
       
   756 	badNamePtr.Set(badName5, sizeof(badName5), sizeof(badName5));
       
   757 	TEST_BAD_NAME(badNamePtr);
       
   758 	badNamePtr.Set(badName6, sizeof(badName6), sizeof(badName6));
       
   759 	TEST_BAD_NAME(badNamePtr);
       
   760 	
       
   761 	// Test Kern::ValidateFullName for good and bad full names
       
   762 	TEST_GOOD_FULLNAME(KGoodName1);
       
   763 	TEST_GOOD_FULLNAME(KGoodName2);
       
   764 	TEST_GOOD_FULLNAME(KGoodFullName1);
       
   765 	TEST_BAD_FULLNAME(KBadName1);
       
   766 	TEST_BAD_FULLNAME(KBadName2);
       
   767 	badNamePtr.Set(badName3, sizeof(badName3), sizeof(badName3));
       
   768 	TEST_BAD_FULLNAME(badNamePtr);
       
   769 	badNamePtr.Set(badName4, sizeof(badName4), sizeof(badName4));
       
   770 	TEST_BAD_FULLNAME(badNamePtr);
       
   771 	badNamePtr.Set(badName5, sizeof(badName5), sizeof(badName5));
       
   772 	TEST_BAD_FULLNAME(badNamePtr);
       
   773 	badNamePtr.Set(badName6, sizeof(badName6), sizeof(badName6));
       
   774 	TEST_BAD_FULLNAME(badNamePtr);
       
   775 
       
   776 	return KErrNone;
       
   777 	}
       
   778 
       
   779 TInt DObjectTest::Request(TInt aFunction, TAny* a1, TAny* a2)
       
   780 	{
       
   781 	TInt r=KErrNone;
       
   782 	TInt i;
       
   783 	TInt duration;
       
   784 	SParam param;
       
   785 	TAny* args[2];	
       
   786 
       
   787 	TRequestStatus* s=(TRequestStatus*)a1;
       
   788 	kumemget32(args,a2,sizeof(args));
       
   789 
       
   790 	switch (~aFunction)
       
   791 		{
       
   792 	case RTestDObject::ERObjectIxTest1:
       
   793 		duration = NKern::TickCount();
       
   794 
       
   795 		NKern::ThreadEnterCS();
       
   796 		for (i = 1;  i < KDObjectTestMaxTestSize;  i = i<KDObjectTestStepStart?i+1:i+KDObjectTestStep) 
       
   797 			if (KErrNone != (r=RObjectIxTest1(i)))
       
   798 				{
       
   799 				NKern::ThreadLeaveCS();
       
   800 				Kern::RequestComplete(s, r);
       
   801 				return KErrNone;
       
   802 				}
       
   803 		NKern::ThreadLeaveCS();
       
   804 
       
   805 		duration = NKern::TickCount() - duration;
       
   806 		kumemput32(args[0], &duration, sizeof(TInt));
       
   807 
       
   808 		Kern::RequestComplete(s,KErrNone);
       
   809 		return KErrNone;
       
   810 
       
   811 	case RTestDObject::ERObjectIxTest2:
       
   812 		duration = NKern::TickCount();
       
   813 
       
   814 		NKern::ThreadEnterCS();
       
   815 		for (i = 1;  i < KDObjectTestMaxTestSize;  i = i<KDObjectTestStepStart?i+1:i+KDObjectTestStep) 
       
   816 			if (KErrNone != (r=RObjectIxTest2(i)))
       
   817 				{
       
   818 				NKern::ThreadLeaveCS();
       
   819 				Kern::RequestComplete(s, r);
       
   820 				return KErrNone;
       
   821 				}
       
   822 
       
   823 		NKern::ThreadLeaveCS();
       
   824 
       
   825 		duration = NKern::TickCount() - duration;
       
   826 		kumemput32(args[0], &duration, sizeof(TInt));
       
   827 
       
   828 		Kern::RequestComplete(s,KErrNone);
       
   829 		return KErrNone;
       
   830 
       
   831 	case RTestDObject::ERObjectIxTest3:
       
   832 		kumemget32(&param, args[0], sizeof(param));
       
   833 
       
   834 		duration = NKern::TickCount();
       
   835 		iSeed[0] = param.iSeed[0];
       
   836 		iSeed[1] = param.iSeed[1];
       
   837 		NKern::ThreadEnterCS();
       
   838 		for (i = 1;  i < KDObjectTestMaxTestSize;  i = i<KDObjectTestStepStart?i+1:i+KDObjectTestStep) 
       
   839 			if (KErrNone != (r=RObjectIxTest3(i, param.iPerformanceTest)))
       
   840 				{
       
   841 				NKern::ThreadLeaveCS();
       
   842 				Kern::RequestComplete(s, r);
       
   843 				return KErrNone;
       
   844 				}
       
   845 		NKern::ThreadLeaveCS();
       
   846 		
       
   847 		duration = NKern::TickCount() - duration;
       
   848 		kumemput32(&((SParam*)args[0])->duration, &duration, sizeof(TInt));
       
   849 
       
   850 		Kern::RequestComplete(s,KErrNone);
       
   851 		return KErrNone;
       
   852 
       
   853 	case RTestDObject::ERObjectIxTest4:
       
   854 		duration = NKern::TickCount();
       
   855 
       
   856 		NKern::ThreadEnterCS();
       
   857 		for (i = 1;  i < KDObjectTestMaxTestSize;  i = i<KDObjectTestStepStart?i+1:i+KDObjectTestStep) 
       
   858 			if (KErrNone != (r=RObjectIxTest4(i)))
       
   859 				{
       
   860 				NKern::ThreadLeaveCS();
       
   861 				Kern::RequestComplete(s, r);
       
   862 				return KErrNone;
       
   863 				}
       
   864 		NKern::ThreadLeaveCS();
       
   865 
       
   866 		duration = NKern::TickCount() - duration;
       
   867 		kumemput32(args[0], &duration, sizeof(TInt));
       
   868 
       
   869 		Kern::RequestComplete(s,KErrNone);
       
   870 		return KErrNone;
       
   871 
       
   872 	case RTestDObject::ERObjectIxThreadTestCreateIx:
       
   873 		//RTestDObject::RObjectIxThreadTestCreateIx(void*& aRObjectIxPtr);
       
   874 		{
       
   875 		RObjectIx*  threadTestObjectIx = NULL;
       
   876 		
       
   877 		NKern::ThreadEnterCS();
       
   878 		threadTestObjectIx = new RObjectIx();
       
   879 		if (threadTestObjectIx == NULL)
       
   880 			{
       
   881 			NKern::ThreadLeaveCS();
       
   882 			r = KErrNoMemory;
       
   883 			}
       
   884 		else
       
   885 			{
       
   886 			NKern::ThreadLeaveCS();
       
   887 			
       
   888 			kumemput32(args[0], &threadTestObjectIx, sizeof(RObjectIx*));
       
   889 			r = KErrNone;
       
   890 			}
       
   891 		Kern::RequestComplete(s, r);
       
   892 		r = KErrNone;
       
   893 		}
       
   894 		break;
       
   895 		
       
   896 	case RTestDObject::ERObjectIxThreadTestExerciseIx:
       
   897 		//RTestDObject::RObjectIxThreadTestExerciseIx(void* aRObjectIxPtr);
       
   898 		{
       
   899 		RObjectIx*  threadTestObjectIx = (RObjectIx*) args[0];
       
   900 
       
   901 		NKern::ThreadEnterCS();
       
   902 		for (i = 1;  i < KDObjectTestMaxTestSize;  i = i<KDObjectTestStepStart?i+1:i+KDObjectTestStep) 
       
   903 			{
       
   904 			if (KErrNone != (r=RObjectIxTestExerciseIx(*threadTestObjectIx, i)))
       
   905 				{
       
   906 				NKern::ThreadLeaveCS();
       
   907 				Kern::RequestComplete(s, r);
       
   908 				return KErrNone;
       
   909 				}
       
   910 			}
       
   911 		NKern::ThreadLeaveCS();
       
   912 
       
   913 		Kern::RequestComplete(s, KErrNone);
       
   914 		r = KErrNone;
       
   915 		}
       
   916 		break;
       
   917 		
       
   918 	case RTestDObject::ERObjectIxThreadTestFreeIx:
       
   919 		//RTestDObject::RObjectIxThreadTestFreeIx(void* aRObjectIxPtr)
       
   920 		{
       
   921 		RObjectIx*  threadTestObjectIx = (RObjectIx*) args[0];
       
   922 		
       
   923 		NKern::ThreadEnterCS();
       
   924 		threadTestObjectIx->Check(0);
       
   925 		threadTestObjectIx->Close(NULL);
       
   926 		delete threadTestObjectIx;
       
   927 		threadTestObjectIx = NULL;
       
   928 		NKern::ThreadLeaveCS();
       
   929 		
       
   930 		Kern::RequestComplete(s, KErrNone);
       
   931 		r = KErrNone;
       
   932 		}
       
   933 		break;
       
   934 		
       
   935 	case RTestDObject::ERObjectIxInvalidHandleLookupTest:
       
   936 		//RTestDObject::InvalidHandleLookupTest()
       
   937 		{
       
   938 		NKern::ThreadEnterCS();
       
   939 		for (i = 1;  i < KDObjectTestMaxTestSize;  i = i<KDObjectTestStepStart?i+1:i+KDObjectTestStep) 
       
   940 			{
       
   941 			if (KErrNone != (r=RObjectIxInvalidHandleLookupTest(i)))
       
   942 				{
       
   943 				NKern::ThreadLeaveCS();
       
   944 				Kern::RequestComplete(s, r);
       
   945 				return KErrNone;
       
   946 				}
       
   947 			}
       
   948 		NKern::ThreadLeaveCS();
       
   949 
       
   950 		Kern::RequestComplete(s, r);
       
   951 		}
       
   952 		break;
       
   953 		
       
   954 	case RTestDObject::EDObjectNameTest:
       
   955 		
       
   956 		r = DObjectNameTest();
       
   957 		Kern::RequestComplete(s, r);
       
   958 		break;
       
   959 		
       
   960 	default:
       
   961 		r = KErrNotSupported;
       
   962 		break;
       
   963 		}
       
   964 	return r;
       
   965 	}