os/kernelhwsrv/kerneltest/e32test/active/t_cact.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 1995-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\active\t_cact.cpp
    15 // Overview:
    16 // Test the CActiveScheduler class, including scheduling priority, thread 
    17 // panics and cancelling objects attached to the scheduler. 
    18 // API Information:
    19 // CActiveScheduler 
    20 // Details:
    21 // - Verify the thread is panicked when one of the following programming errors occurs:
    22 // - start an uninstalled scheduler
    23 // - install a scheduler twice
    24 // - stop the scheduler twice 
    25 // - stop an uninstalled scheduler
    26 // - set active an active object twice
    27 // - add an active object to an uninstalled scheduler
    28 // - add a NULL pointer to the scheduler
    29 // - add an active object twice
    30 // - thread gets a stray signal
    31 // - make request on an un-added active object
    32 // - Create timers with different priorities
    33 // - Check the timers are scheduled according to expiration time
    34 // - Check the timers are scheduled in order of their priority when they expire at the
    35 // same time
    36 // - Check the timers are scheduled in order of the addition to the scheduler when
    37 // they expire at the same time and they have the same priority
    38 // - Verify that a leave in RunL method not handled by the active object calls the active 
    39 // scheduler's Error method
    40 // - Test a cancelled timer will not be scheduled 
    41 // - Create a thread with its own heap and test that timers are scheduled in the order of
    42 // their expiration time, priority and order of addition to the scheduler
    43 // - Check the heap is not corrupted by all the tests
    44 // Platforms/Drives/Compatibility:
    45 // All
    46 // Assumptions/Requirement/Pre-requisites:
    47 // Failures and causes:
    48 // Base Port information:
    49 // 
    50 //
    51 
    52 #include <e32test.h>
    53 #include <e32panic.h>
    54 
    55 const TInt KmyErrorNum=999;
    56 const TInt KLeaveCode=1234;  
    57 const TInt KgTimerID=4321;
    58 const TInt KCancelCode=1111;
    59 const TInt KTestArraySize=10;
    60 const TInt KPanicThreadRet=2222;
    61 const TInt KHeapSize=0x2000;
    62 
    63 enum TActivePriority {eLowest=-100,eLow=-1,eNone=0,eHigh=1,eHighest=100};
    64 enum TDirective {EStartUninstalled,EInstallTwice,EStopTwice,EStopUninstalled,ESetActiveTwice,
    65 				 EAddToUninstalled,EAddNull,EAddTwice,ECreateStray,ERequestUnadded,EStraySignalNoKRequestPending,EStraySignalNoSetActive,ENormal};
    66 
    67 class TSecdulerTester
    68 	{
    69 public:
    70 	void Test1();
    71 	void Test2();
    72 	void Test3();
    73 	void Test4();
    74 	};
    75 
    76 class MyManager : public CActiveScheduler
    77 	{
    78 public:
    79 	virtual void Error(TInt anError) const {CActiveScheduler::Halt(anError);}
    80 	};
    81 
    82 class myTimer : public CTimer
    83 	{
    84 public:
    85 	myTimer(const TInt aPriority, const TInt anIdentifier):CTimer(aPriority){iIdentifier=anIdentifier;}
    86 	virtual void RunL();
    87 	void Start();		  
    88 	void Setactive() {SetActive();}
    89 	static void SetNum(const TInt aNum) {iNum=aNum; iCount=0;}
    90 private:   
    91 	TInt iIdentifier;
    92 	static TInt iCount;
    93 	static TInt iNum;
    94 	};
    95 
    96 class myThreadTimer : public CTimer
    97 	{
    98 public:
    99 	myThreadTimer(const TInt aPriority, const TInt anIdentifier):CTimer(aPriority){iIdentifier=anIdentifier;}
   100 	virtual void RunL();
   101 	static void SetNum(const TInt aNum) {iNum=aNum; iCount=0;}
   102 	void Start();
   103 private:
   104 	TInt iIdentifier;
   105 	static TInt iCount;
   106 	static TInt iNum;
   107 	};
   108 
   109 class CreateStray : public CActive
   110 	{
   111 public:
   112 	CreateStray(TInt aPriority);
   113 	void DoCancel() {}
   114 	void RunL() {}
   115 private:
   116 	RTimer iTimer;
   117 	};
   118 
   119 class myStray : public CActive
   120 	{
   121 public:
   122 	myStray(TInt aPriority) : CActive(aPriority) {};
   123 	void DoCancel() {}
   124 	void RunL() { CActiveScheduler::Stop(); }
   125 	void Start1();
   126 	void Start2();
   127 	};
   128 
   129 void myStray::Start1()
   130 	{
   131 	TRequestStatus* s=&iStatus;
   132 	SetActive();
   133 	RThread().RequestComplete(s,KErrNone);
   134 	}
   135 
   136 void myStray::Start2()
   137 	{
   138 	TRequestStatus* s=&iStatus;
   139 	iStatus=KRequestPending;
   140 	User::RequestComplete(s,KErrNone);
   141 	}
   142 
   143 TInt myTimer::iCount;
   144 TInt myTimer::iNum;
   145 TInt myThreadTimer::iCount;
   146 TInt myThreadTimer::iNum;
   147 
   148 LOCAL_D RTest test(_L("T_CACT"));
   149 LOCAL_D myTimer* gTimer; // This is cancelled from within the run method 
   150 LOCAL_D RSemaphore threadSemaphore;
   151 LOCAL_D myTimer* pLowest=NULL;
   152 LOCAL_D myTimer* pLow=NULL;
   153 LOCAL_D myTimer* pNone=NULL;
   154 LOCAL_D myTimer* pHigh=NULL;
   155 LOCAL_D myTimer* pHigh2=NULL;
   156 LOCAL_D myTimer* pHigh3=NULL;
   157 LOCAL_D myTimer* pHighest=NULL;
   158 LOCAL_D TInt order[KTestArraySize]; // When a timer expires its identifier is placed in here
   159 LOCAL_D TInt threadArray[KTestArraySize];
   160 
   161 LOCAL_C TInt myThreadEntryPoint(TAny*)
   162 //
   163 // myThread tests 
   164 //
   165 	{
   166 
   167 	__UHEAP_MARK;
   168 	RTest test(_L("Separate thread tests"));
   169 	test.Title();
   170 	test.Start(_L("Create semaphore"));
   171 	RTimer t;
   172 	TInt ret=t.CreateLocal();
   173 	test(ret==KErrNone);
   174 //
   175 	test.Next(_L("Install scheduler"));
   176 	MyManager* pManager=new MyManager;
   177 	CActiveScheduler::Install(pManager);
   178 //
   179 	test.Next(_L("Create active objects"));
   180 	myThreadTimer* pLowest=new myThreadTimer(eLowest, eLowest);
   181 	test(pLowest!=NULL);
   182 	myThreadTimer* pLow=new myThreadTimer(eLow, eLow);
   183 	test(pLow!=NULL);
   184 	myThreadTimer* pNone=new myThreadTimer(eNone, eNone);
   185 	test(pNone!=NULL);
   186 	myThreadTimer* pHigh=new myThreadTimer(eHigh, eHigh);
   187 	test(pHigh!=NULL);
   188 	myThreadTimer* pHigh2=new myThreadTimer(eHigh, eHigh+2);
   189 	test(pHigh2!=NULL);
   190 	myThreadTimer* pHigh3=new myThreadTimer(eHigh, eHigh+3);
   191 	test(pHigh3!=NULL);
   192 	myThreadTimer* pHighest=new myThreadTimer(eHighest, eHighest);
   193 	test(pHighest!=NULL);
   194 //
   195 	test.Next(_L("Test low is scheduled before lowest"));
   196 	myThreadTimer::SetNum(2);
   197 	pLowest->Start();
   198 	pLowest->After(0);
   199 	pLow->Start();
   200 	pLow->After(0);
   201 	TRequestStatus s;
   202 	t.After(s,100000);
   203 	test(s==KRequestPending);
   204 	User::WaitForRequest(s);
   205 	CActiveScheduler::Start();
   206 	test(threadArray[0]==eLow && threadArray[1]==eLowest);
   207 //
   208 	test.Next(_L("Test none is scheduled before low"));
   209 	myThreadTimer::SetNum(2);
   210 	pLow->After(0);
   211 	pNone->Start();
   212 	pNone->After(0);
   213 	t.After(s,100000);
   214 	test(s==KRequestPending);
   215 	User::WaitForRequest(s);
   216 	CActiveScheduler::Start();
   217 	test(threadArray[0]==eNone && threadArray[1]==eLow);
   218 //
   219 	test.Next(_L("Test high is scheduled before none"));
   220 	myThreadTimer::SetNum(2);
   221 	pHigh->Start();
   222 	pHigh->After(0);
   223 	pNone->After(0);
   224 	t.After(s, 100000);
   225 	test(s==KRequestPending);
   226 	User::WaitForRequest(s);
   227 	CActiveScheduler::Start();
   228 	test(threadArray[0]==eHigh && threadArray[1]==eNone);
   229 //
   230 	test.Next(_L("Test highest is scheduled before high"));
   231 	myThreadTimer::SetNum(2);
   232 	pHighest->Start();
   233 	pHighest->After(0);
   234 	pHigh->After(0);
   235 	t.After(s, 100000);
   236 	test(s==KRequestPending);
   237 	User::WaitForRequest(s);
   238 	CActiveScheduler::Start();
   239 	test(threadArray[0]==eHighest && threadArray[1]==eHigh);
   240 //
   241 	test.Next(_L("Test objects are scheduled according to priority"));
   242 	myThreadTimer::SetNum(5);
   243 	pLowest->After(0);
   244 	pLow->After(0);
   245 	pNone->After(0);
   246 	pHigh->After(0);
   247 	pHighest->After(0);
   248 	t.After(s, 100000);
   249 	test(s==KRequestPending);
   250 	User::WaitForRequest(s);
   251 	CActiveScheduler::Start();
   252 	test(threadArray[0]==eHighest && threadArray[1]==eHigh && threadArray[2]==eNone && 
   253 		 threadArray[3]==eLow && threadArray[4]==eLowest);
   254 //
   255 	test.Next(_L("Test objects are scheduled according to timer expiry"));
   256 	myThreadTimer::SetNum(5);
   257 	pLowest->After(0);
   258 	pLow->After(500000);
   259 	pNone->After(1000000);
   260 	pHigh->After(1500000);
   261 	pHighest->After(2000000);
   262 	CActiveScheduler::Start();
   263 	test(threadArray[4]==eHighest && threadArray[3]==eHigh && threadArray[2]==eNone && 
   264 		 threadArray[1]==eLow && threadArray[0]==eLowest);
   265 //
   266 	test.Next(_L("Test with some objects having the same priority"));
   267 	myThreadTimer::SetNum(7);
   268 	pLowest->After(0);
   269 	pLow->After(0);
   270 	pNone->After(0);
   271 	pHigh->After(0);
   272 	pHigh2->Start();
   273 	pHigh2->After(0);
   274 	pHigh3->Start();
   275 	pHigh3->After(0);
   276 	pHighest->After(0);
   277 	t.After(s, 100000);
   278 	test(s==KRequestPending);
   279 	User::WaitForRequest(s);
   280 	CActiveScheduler::Start();
   281 	test(threadArray[0]==eHighest && threadArray[1]==eHigh && threadArray[2]==eHigh+2 && 
   282 		 threadArray[3]==eHigh+3 && threadArray[4]==eNone && threadArray[5]==eLow && threadArray[6]==eLowest);
   283 //
   284 	test.Next(_L("Tidying up"));
   285 	delete pManager;
   286 	delete pLowest;
   287 	delete pLow;
   288 	delete pNone;
   289 	delete pHigh;
   290 	delete pHigh2;
   291 	delete pHigh3;
   292 	delete pHighest;
   293 	test.Close();
   294 	__UHEAP_MARKEND;
   295 	threadSemaphore.Signal();
   296 	return(KErrNone);
   297 	}
   298 
   299 LOCAL_D TInt panicThread(TAny* aDirective)
   300 //
   301 // Test thread which panics
   302 //
   303 	{
   304 	// cause panics in various ways depending upon aDirective
   305 	MyManager* pManager=new MyManager;
   306 	
   307 	switch((TInt)aDirective)
   308 		{
   309 	case EStartUninstalled:
   310 		CActiveScheduler::Start(); // Start an uninstalled active schedler
   311 		break;
   312 	case EInstallTwice:
   313 		CActiveScheduler::Install(pManager); // Install the scheduler twice
   314 		CActiveScheduler::Install(pManager);
   315 		break;
   316 	case EStopTwice:
   317 		CActiveScheduler::Install(pManager); // Stop a scheduler twice
   318 		CActiveScheduler::Stop();
   319 		CActiveScheduler::Stop();
   320 		break;
   321 	case EStopUninstalled:
   322 		CActiveScheduler::Stop(); // Stop an uninstalled active scheduler
   323 		break;
   324 	case ESetActiveTwice:
   325 		{
   326 //
   327 // Set an active object to active twice
   328 //
   329 		myTimer* pTimer=new myTimer(eNone,eNone);
   330 		CActiveScheduler::Install(pManager);
   331 		CActiveScheduler::Add(pTimer);
   332 		pTimer->Setactive();
   333 		pTimer->Setactive();
   334 		}
   335 		break;
   336 	case EAddToUninstalled:
   337 		{
   338 //
   339 // Add an active object to an uninstalled scheduler
   340 //
   341 		myTimer* pTimer=new myTimer(eNone,eNone);
   342 		CActiveScheduler::Add(pTimer); 
   343 		}
   344 		break;
   345 	case EAddNull:
   346 //
   347 // Add Null to the scheduling queue
   348 //
   349 		CActiveScheduler::Install(pManager);  
   350 		CActiveScheduler::Add(NULL);
   351 		break;
   352 	case EAddTwice:
   353 		{
   354 //
   355 // Add the same object twice to the scheduling queue
   356 //
   357 		myTimer* pTimer=new myTimer(eNone,eNone);
   358 		CActiveScheduler::Install(pManager);  
   359 		CActiveScheduler::Add(pTimer);
   360 		CActiveScheduler::Add(pTimer);
   361 		}
   362 		break;
   363 	case ECreateStray:
   364 		{
   365 //
   366 // Create a stray signal
   367 //
   368 		CActiveScheduler::Install(pManager); 
   369 		new CreateStray(1);
   370 		CActiveScheduler::Start();
   371 		}
   372 		break;
   373 	case ERequestUnadded:
   374 		{
   375 //
   376 // Make a request of an active object not added to the scheduling queue
   377 //
   378 		CActiveScheduler::Install(pManager);
   379 		myTimer* pTimer=new myTimer(eNone,eNone);
   380 		pTimer->Setactive();
   381 		}
   382 		break;
   383 	case EStraySignalNoKRequestPending:
   384 		{
   385 		CActiveScheduler::Install(pManager);
   386 		myStray* pStray = new myStray(eNone);
   387 		CActiveScheduler::Add(pStray);
   388 		pStray->Start1();
   389 		CActiveScheduler::Start();
   390 		}
   391 		break;
   392 	case EStraySignalNoSetActive:
   393 		{
   394 		CActiveScheduler::Install(pManager);
   395 		myStray* pStray = new myStray(eNone);
   396 		CActiveScheduler::Add(pStray);
   397 		pStray->Start2();
   398 		CActiveScheduler::Start();
   399 		}
   400 		break;
   401 	case ENormal:
   402 	default:
   403 		break;
   404 		}
   405 	delete pManager;
   406 	return(KPanicThreadRet);
   407 	}
   408 
   409 void myTimer::RunL()
   410 //
   411 // Handle the timer completion
   412 //
   413 	{
   414 
   415 	if (iIdentifier==KLeaveCode)	// Used to test that the request manager error() method is called
   416 		User::Leave(KmyErrorNum);
   417 	if (iIdentifier==KCancelCode) // Used to test cancelling an object
   418 		gTimer->Cancel();
   419 	order[iCount++]=iIdentifier;
   420 	if (iCount>=iNum)
   421 		CActiveScheduler::Stop();
   422 	}
   423 
   424 void myTimer::Start()
   425 //
   426 // Start a timer
   427 //
   428 	{
   429 
   430 	ConstructL();
   431 	CActiveScheduler::Add(this);
   432 	}
   433 
   434 void myThreadTimer::RunL()
   435 //
   436 // Handle timer completion
   437 //
   438 	{
   439 	
   440 	threadArray[iCount++]=iIdentifier;
   441 	if(iCount>=iNum)
   442 		CActiveScheduler::Stop();
   443 	}
   444 
   445 void myThreadTimer::Start()
   446 //
   447 // Start a timer
   448 //
   449 	{
   450 
   451 	ConstructL();
   452 	CActiveScheduler::Add(this);
   453 	}
   454 
   455 CreateStray::CreateStray(TInt aPriority)
   456 //
   457 // Constructor
   458 //
   459 	: CActive(aPriority)
   460 	{
   461 
   462 	iTimer.CreateLocal();
   463 	CActiveScheduler::Add(this);
   464 	iTimer.After(iStatus, 1000000);
   465 	}
   466 
   467 void TSecdulerTester::Test1()
   468 //
   469 // Test 1
   470 //
   471 	{
   472 
   473 //
   474 // Test the panics
   475 //
   476 
   477 	RThread thread;
   478 	TRequestStatus stat;
   479 //
   480 	test.Start(_L("First test normal thread termination"));
   481 	TInt r=thread.Create(_L("myThread"),panicThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)ENormal);
   482 	test(r==KErrNone);
   483 	thread.Logon(stat);
   484 	thread.Resume();
   485 	User::WaitForRequest(stat);
   486 	test(thread.ExitCategory().Compare(_L("Kill"))==0);
   487 	test(thread.ExitReason()==KPanicThreadRet);	  
   488 	test(thread.ExitType()==EExitKill);
   489 	CLOSE_AND_WAIT(thread);
   490 //
   491 	test.Next(_L("Starting an uninstalled scheduler panics"));
   492 	r=thread.Create(_L("myThread"),panicThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)EStartUninstalled);
   493 	test(r==KErrNone);
   494 	thread.Logon(stat);
   495 	thread.Resume();
   496 	User::WaitForRequest(stat);
   497 	test(thread.ExitReason()==EReqManagerDoesNotExist);
   498 	test(thread.ExitType()==EExitPanic);
   499 	CLOSE_AND_WAIT(thread);
   500 //
   501 	test.Next(_L("Installing the scheduler twice panics"));
   502 	r=thread.Create(_L("myThread"),panicThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)EInstallTwice);
   503 	test(r==KErrNone);
   504 	thread.Logon(stat);
   505 	thread.Resume();
   506 	User::WaitForRequest(stat);
   507 	test(thread.ExitReason()==EReqManagerAlreadyExists);
   508 	test(thread.ExitType()==EExitPanic);
   509 	CLOSE_AND_WAIT(thread);
   510 //
   511 	test.Next(_L("Stopping the scheduler twice panics"));
   512 	r=thread.Create(_L("myThread"),panicThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)EStopTwice);
   513 	test(r==KErrNone);
   514 	thread.Logon(stat);
   515 	thread.Resume();
   516 	User::WaitForRequest(stat);
   517 	test(thread.ExitReason()==EReqTooManyStops);
   518 	test(thread.ExitType()==EExitPanic);
   519 	CLOSE_AND_WAIT(thread);
   520 //
   521 	test.Next(_L("Stopping an uninstalled scheduler panics"));
   522 	r=thread.Create(_L("myThread"),panicThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)EStopUninstalled);
   523 	test(r==KErrNone);
   524 	thread.Logon(stat);
   525 	thread.Resume();
   526 	User::WaitForRequest(stat);
   527 	test(thread.ExitReason()==EReqManagerDoesNotExist);
   528 	test(thread.ExitType()==EExitPanic);
   529 	CLOSE_AND_WAIT(thread);
   530 //
   531 	test.Next(_L("Setting an active object to active twice panics"));
   532 	r=thread.Create(_L("myThread"),panicThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)ESetActiveTwice);
   533 	test(r==KErrNone);
   534 	thread.Logon(stat);
   535 	thread.Resume();
   536 	User::WaitForRequest(stat);
   537 	test(thread.ExitReason()==EReqAlreadyActive);
   538 	test(thread.ExitType()==EExitPanic);
   539 	CLOSE_AND_WAIT(thread);
   540 //
   541 	test.Next(_L("Adding an active object to an uninstalled scheduler panics"));
   542 	r=thread.Create(_L("myThread"),panicThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)EAddToUninstalled);
   543 	test(r==KErrNone);
   544 	thread.Logon(stat);
   545 	thread.Resume();
   546 	User::WaitForRequest(stat);
   547 	test(thread.ExitReason()==EReqManagerDoesNotExist);
   548 	test(thread.ExitType()==EExitPanic);
   549 	CLOSE_AND_WAIT(thread);
   550 //
   551 	test.Next(_L("Adding NULL panics"));
   552 	r=thread.Create(_L("myThread"),panicThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)EAddNull);
   553 	test(r==KErrNone);
   554 	thread.Logon(stat);
   555 	thread.Resume();
   556 	User::WaitForRequest(stat);
   557 	test(thread.ExitReason()==EReqNull);
   558 	test(thread.ExitType()==EExitPanic);
   559 	CLOSE_AND_WAIT(thread);
   560 //
   561 	test.Next(_L("Adding an active object twice panics"));
   562 	r=thread.Create(_L("myThread"),panicThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)EAddTwice);
   563 	test(r==KErrNone);
   564 	thread.Logon(stat);
   565 	thread.Resume();
   566 	User::WaitForRequest(stat);
   567 	test(thread.ExitReason()==EReqAlreadyAdded);
   568 	test(thread.ExitType()==EExitPanic);
   569 	CLOSE_AND_WAIT(thread);
   570 //
   571 	test.Next(_L("A stray signal causes a panic"));
   572 	r=thread.Create(_L("myThread"),panicThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)ECreateStray);
   573 	test(r==KErrNone);
   574 	thread.Logon(stat);
   575 	thread.Resume();
   576 	User::WaitForRequest(stat);
   577 	test(thread.ExitReason()==EReqStrayEvent);
   578 	test(thread.ExitType()==EExitPanic);
   579 	CLOSE_AND_WAIT(thread);
   580 //
   581 	test.Next(_L("Making a request on an unadded active object panics"));
   582 	r=thread.Create(_L("myThread"),panicThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)ERequestUnadded);
   583 	test(r==KErrNone);
   584 	thread.Logon(stat);
   585 	thread.Resume();
   586 	User::WaitForRequest(stat);
   587 	test(thread.ExitReason()==EActiveNotAdded);
   588 	test(thread.ExitType()==EExitPanic);
   589 	CLOSE_AND_WAIT(thread);
   590 //
   591 	test.Next(_L("The service provider does not set the status to KRequestPending"));
   592 	r=thread.Create(_L("myThread"),panicThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)EStraySignalNoKRequestPending);
   593 	test(r==KErrNone);
   594 	thread.Logon(stat);
   595 	thread.Resume();
   596 	User::WaitForRequest(stat);
   597 #ifdef _DEBUG
   598 	//this might fail if we're using a UREL euser
   599 	test(thread.ExitReason()==EReqStrayEvent);
   600 	test(thread.ExitType()==EExitPanic);
   601 #else
   602 	test(thread.ExitCategory().Compare(_L("Kill"))==0);
   603 	test(thread.ExitReason()==KPanicThreadRet);	  
   604 	test(thread.ExitType()==EExitKill);
   605 #endif 
   606 	CLOSE_AND_WAIT(thread);
   607 //
   608 #ifdef _DEBUG
   609 	//this might fail if we're using a UREL euser
   610 	test.Next(_L("The active object does not call SetActive"));
   611 	r=thread.Create(_L("myThread"),panicThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)EStraySignalNoSetActive);
   612 	test(r==KErrNone);
   613 	thread.Logon(stat);
   614 	thread.Resume();
   615 	User::WaitForRequest(stat);
   616 	test(thread.ExitReason()==EReqStrayEvent);
   617 	test(thread.ExitType()==EExitPanic);
   618 	CLOSE_AND_WAIT(thread);
   619 #endif
   620 //
   621 	test.End();
   622 	}
   623 
   624 void TSecdulerTester::Test2()
   625 //
   626 // Test 2
   627 //
   628 	{
   629 
   630 	test.Start(_L("Create timer"));
   631 	RTimer t;
   632 	TInt ret=t.CreateLocal();
   633 	test(ret==KErrNone);
   634 	TRequestStatus s;
   635 //
   636 	test.Next(_L("Test low is scheduled before lowest when timing equal"));
   637 	myTimer::SetNum(2);
   638 	pLowest->After(0);
   639 	pLow->After(0);
   640 	t.After(s, 100000);
   641 	test(s==KRequestPending);
   642 	User::WaitForRequest(s);
   643 	CActiveScheduler::Start();
   644 	test(order[0]==eLow && order[1]==eLowest);
   645 //
   646 	test.Next(_L("Test low is not before lowest when it expires later"));
   647 	myTimer::SetNum(2);
   648 	pLowest->After(0);
   649 	pLow->After(1000000);
   650 	CActiveScheduler::Start();
   651 	test(order[0]==eLowest && order[1]==eLow);
   652 //
   653 	test.Next(_L("Test none is scheduled before low"));
   654 	myTimer::SetNum(2);
   655 	pLow->After(0);
   656 	pNone->After(0);
   657 	t.After(s, 100000);
   658 	test(s==KRequestPending);
   659 	User::WaitForRequest(s);
   660 	CActiveScheduler::Start();
   661 	test(order[0]==eNone && order[1]==eLow);
   662 //
   663 	test.Next(_L("Test none is not before low when it expires later"));
   664 	myTimer::SetNum(2);
   665 	pLow->After(0);
   666 	pNone->After(1000000);
   667 	CActiveScheduler::Start();
   668 	test(order[0]==eLow && order[1]==eNone);
   669 //
   670 	test.Next(_L("Test high is scheduled before none"));
   671 	myTimer::SetNum(2);
   672 	pHigh->After(0);
   673 	pNone->After(0);
   674 	t.After(s, 100000);
   675 	test(s==KRequestPending);
   676 	User::WaitForRequest(s);
   677 	CActiveScheduler::Start();
   678 	test(order[0]==eHigh && order[1]==eNone);
   679 //
   680 	test.Next(_L("Test high is not before none when it expires later"));
   681 	myTimer::SetNum(2);
   682 	pHigh->After(1000000);
   683 	pNone->After(0);
   684 	CActiveScheduler::Start();
   685 	test(order[0]==eNone && order[1]==eHigh);
   686 //
   687 	test.Next(_L("Test highest is scheduled before high"));
   688 	myTimer::SetNum(2);
   689 	pHighest->After(0);
   690 	pHigh->After(0);
   691 	t.After(s, 100000);
   692 	test(s==KRequestPending);
   693 	User::WaitForRequest(s);
   694 	CActiveScheduler::Start();
   695 	test(order[0]==eHighest && order[1]==eHigh);
   696 //
   697 	test.Next(_L("Test highest is not before high when it expires later"));
   698 	myTimer::SetNum(2);
   699 	pHighest->After(1000000);
   700 	pHigh->After(0);
   701 	CActiveScheduler::Start();
   702 	test(order[0]==eHigh && order[1]==eHighest);
   703 //			  
   704 	test.Next(_L("Test all objects are scheduled in priority order"));
   705 	myTimer::SetNum(5);
   706 	pLowest->After(0);
   707 	pLow->After(0);
   708 	pNone->After(0);
   709 	pHigh->After(0);
   710 	pHighest->After(0);
   711 	t.After(s, 100000);
   712 	test(s==KRequestPending);
   713 	User::WaitForRequest(s);
   714 	CActiveScheduler::Start();
   715 	test(order[0]==eHighest && order[1]==eHigh && order[2]==eNone && order[3]==eLow && order[4]==eLowest);
   716 //
   717 	test.Next(_L("Test objects are scheduled according to expiry of timers"));
   718 	myTimer::SetNum(5);
   719 	pLowest->After(0);
   720 	pLow->After(500000);
   721 	pNone->After(1000000);
   722 	pHigh->After(1500000);
   723 	pHighest->After(2000000);
   724 	CActiveScheduler::Start();
   725 	test(order[4]==eHighest && order[3]==eHigh && order[2]==eNone && order[1]==eLow && order[0]==eLowest);
   726 //
   727 	test.Next(_L("Test with some objects having the same priority"));
   728 	myTimer::SetNum(7);
   729 	pLowest->After(0);
   730 	pLow->After(0);
   731 	pNone->After(0);
   732 	pHigh->After(0);
   733 	pHigh2->After(0);
   734 	pHigh3->After(0);
   735 	pHighest->After(0);	  
   736 	t.After(s, 100000);
   737 	test(s==KRequestPending);
   738 	User::WaitForRequest(s);
   739 	CActiveScheduler::Start();
   740 	test(order[0]==eHighest && order[1]==eHigh && order[2]==eHigh+2 && order[3]==eHigh+3 && order[4]==eNone && order[5]==eLow && order[6]==eLowest);
   741 //
   742 	test.End();
   743 	}
   744 
   745 void TSecdulerTester::Test3()
   746 //
   747 // Test 3
   748 //
   749 	{
   750 
   751 //
   752 // Test that a leave in a Run method calls the requestmanager error() method
   753 //
   754 	myTimer* pTimer=new myTimer(0, KLeaveCode);
   755 	pTimer->Start();
   756 	pTimer->After(100000);
   757 	TRAPD(ret,CActiveScheduler::Start());
   758 	test(ret==KmyErrorNum);		
   759 //
   760 // Test cancelling an object
   761 // Without the cancel the schedule order should be: pTimer1, gTimer, pTimer3
   762 // gTimer is cancelled so should not be scheduled 
   763 //
   764 	myTimer::SetNum(2);
   765 	myTimer* pTimer2=new myTimer(eHighest,KCancelCode);
   766 	myTimer* pTimer3=new myTimer(eLowest,eLowest);
   767 	pTimer2->Start();
   768 	pTimer2->After(100000);
   769 	gTimer->Start();
   770 	gTimer->After(1000000);
   771 	pTimer3->Start();
   772 	pTimer3->After(2000000);
   773 	CActiveScheduler::Start();
   774 	test(order[0]==KCancelCode && order[1]==eLowest);
   775 	delete pTimer;
   776 	delete pTimer2;
   777 	delete pTimer3;
   778 	}
   779 
   780 void TSecdulerTester::Test4()
   781 //
   782 // Create a thread with its own scheduler
   783 //
   784 	{	  
   785 
   786 	threadSemaphore.CreateLocal(0);
   787 	RThread myThread;
   788 	test(myThread.Create(_L("myThread"),myThreadEntryPoint,KDefaultStackSize,KHeapSize,KHeapSize,NULL)==KErrNone);
   789 	myThread.Resume();
   790 	myThread.Close();
   791 	Test2();
   792 	threadSemaphore.Wait();
   793 	User::After(100000);
   794 	}
   795 
   796 GLDEF_C TInt E32Main()
   797     {
   798 
   799 	// don't want just in time debugging as we trap panics
   800 	TBool justInTime=User::JustInTime(); 
   801 	User::SetJustInTime(EFalse); 
   802 
   803 	test.Title();
   804 	__UHEAP_MARK;
   805 //
   806 	test.Start(_L("Test1"));
   807 	TSecdulerTester sched;
   808 	sched.Test1();
   809 	MyManager* pManager=new MyManager;
   810 	test(pManager!=NULL);
   811 	CActiveScheduler::Install(pManager);
   812 	test(CActiveScheduler::Current()==pManager);
   813 	MyManager* pManager2=new MyManager;
   814 	test(pManager2!=NULL);
   815 	delete pManager2;
   816 	test(CActiveScheduler::Current()==pManager);
   817 	pLowest=new myTimer(eLowest,eLowest);
   818 	test(pLowest!=NULL);
   819 	pLow=new myTimer(eLow,eLow);
   820 	test(pLow!=NULL);
   821 	pNone=new myTimer(eNone,eNone);
   822 	test(pNone!=NULL);
   823 	pHigh=new myTimer(eHigh,eHigh);
   824 	test(pHigh!=NULL);
   825 	pHigh2=new myTimer(eHigh,eHigh+2);
   826 	test(pHigh2!=NULL);
   827 	pHigh3=new myTimer(eHigh,eHigh+3);
   828 	test(pHigh3!=NULL);
   829 	pHighest=new myTimer(eHighest,eHighest);
   830 	test(pHighest!=NULL);
   831 	pLowest->Start();
   832 	pLow->Start();
   833 	pNone->Start();
   834 	pHigh->Start();
   835 	pHigh2->Start();
   836 	pHigh3->Start();
   837 	pHighest->Start();
   838 //
   839 	test.Next(_L("Test2"));
   840 	sched.Test2();	
   841 	User::Check();
   842 //
   843 	test.Next(_L("Test3"));
   844 	gTimer=new myTimer(eNone, KgTimerID);
   845 	sched.Test3();
   846 //
   847 	test.Next(_L("Test4"));
   848 	sched.Test4();
   849 	delete gTimer;
   850 	User::Check();
   851 	delete pManager;
   852 	delete pLowest;
   853 	delete pLow;
   854 	delete pNone;
   855 	delete pHigh;
   856 	delete pHigh2;
   857 	delete pHigh3;
   858 	delete pHighest;
   859 //
   860 	test.End();
   861 	__UHEAP_MARKEND;
   862 
   863 	User::SetJustInTime(justInTime);
   864 	return(KErrNone);
   865     }