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