kerneltest/e32test/mqueue/t_mqueue.cpp
changeset 0 a41df078684a
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     1 // Copyright (c) 2002-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\mqueue\t_mqueue.cpp
       
    15 // Overview:
       
    16 // Test message queuing
       
    17 // API Information:
       
    18 // RMsgQueue, RMsgQueueBase
       
    19 // Details:
       
    20 // - Create various illegal and legal private message queues and verify 
       
    21 // results are as expected. Test private message queue functionality in
       
    22 // both single threaded tests and multi-threaded tests.
       
    23 // - Create various illegal and legal global named message queues and verify 
       
    24 // results are as expected. Test global named message queue functionality
       
    25 // in both single threaded tests and multi-threaded tests.
       
    26 // - Test multi-process queues and template based queues, verify results are 
       
    27 // as expected.
       
    28 // Platforms/Drives/Compatibility:
       
    29 // All.
       
    30 // Assumptions/Requirement/Pre-requisites:
       
    31 // Failures and causes:
       
    32 // Base Port information:
       
    33 // 
       
    34 //
       
    35 
       
    36 #include <e32test.h>
       
    37 #include <e32svr.h>
       
    38 #include <e32msgqueue.h>
       
    39 #include <f32file.h>
       
    40 
       
    41 LOCAL_D RTest test(_L("t_mqueue"));
       
    42 
       
    43 //if the test is to run under the debugger, uncomment the following line
       
    44 //#define _DEBUGGER_BUILD
       
    45 
       
    46 const TInt KHeapSize=0x2000;
       
    47 const TInt KTestValue = 42;
       
    48 _LIT8(KFillPattern, "1234567890");
       
    49 
       
    50 _LIT(KGLobalName1, "GlobalMessageQueue1");
       
    51 
       
    52 
       
    53 LOCAL_C void SingleThreadedTests(RMsgQueueBase& aQueue, TInt aSlots, TInt aSize)
       
    54 	{
       
    55 	test.Printf(_L("Single Threaded Tests"));
       
    56 
       
    57 
       
    58 	TRequestStatus stat;
       
    59 	test.Next(_L("test CancelDataAvailable"));
       
    60 	aQueue.NotifyDataAvailable(stat);
       
    61 	test (stat == KRequestPending);
       
    62 	aQueue.CancelDataAvailable();
       
    63 	User::WaitForRequest(stat);
       
    64 	test (stat == KErrCancel);
       
    65 
       
    66 	TUint8 * pSourceData = (TUint8*)User::Alloc(aSize*2);
       
    67 	test(pSourceData != NULL);	
       
    68 	TPtr8 pS(pSourceData, aSize*2, aSize*2);
       
    69 	pS.Repeat(KFillPattern);
       
    70 
       
    71 	TUint8 * pDestinationData = (TUint8*)User::Alloc(aSize*2);
       
    72 	test(pDestinationData != NULL);
       
    73 	TPtr8 pD(pDestinationData, aSize*2, aSize*2);
       
    74 	pD.FillZ();
       
    75 
       
    76 
       
    77 	test.Next(_L("test MessageSize"));
       
    78 	test(aQueue.MessageSize() == aSize);
       
    79 
       
    80 
       
    81 	test.Next(_L("Send a legal message through"));
       
    82 	TInt ret = aQueue.Send(pSourceData, aSize);
       
    83 	test(ret == KErrNone);
       
    84 
       
    85 	test.Next(_L("Receive legal message"));
       
    86 	ret = aQueue.Receive(pDestinationData, aSize);
       
    87 	test(ret == KErrNone);
       
    88 	TPtr8 p(pS);
       
    89 	p.SetLength(aSize);
       
    90 	pD.SetLength(aSize);
       
    91 	test(p == pD);
       
    92 	pD.FillZ();
       
    93 
       
    94 	test.Next(_L("Send a short message through"));
       
    95 	ret = aQueue.Send(pSourceData, aSize/2);
       
    96 	test(ret == KErrNone);
       
    97 
       
    98 	test.Next(_L("Receive legal message"));
       
    99 	ret = aQueue.Receive(pDestinationData, aSize);
       
   100 	test(ret == KErrNone);
       
   101 	p.SetLength(aSize/2);
       
   102 	pD.SetLength(aSize/2);
       
   103 	test(p == pD);
       
   104 	pD.FillZ();
       
   105 
       
   106 	test.Next(_L("Test Receive with no message"));
       
   107 	ret = aQueue.Receive(pDestinationData, aSize);
       
   108 	test(ret == KErrUnderflow);
       
   109 
       
   110 	if (aSlots >= 2)
       
   111 		{	
       
   112 		test.Next(_L("Send two legal messages through"));
       
   113 		pS[0] = 0;
       
   114 		ret = aQueue.Send(pSourceData, aSize);
       
   115 		test(ret == KErrNone);
       
   116 		pS[0] = 1;
       
   117 		ret = aQueue.Send(pSourceData, aSize);
       
   118 		test(ret == KErrNone);
       
   119 
       
   120 		test.Next(_L("Receive two legal messages in tx order"));
       
   121 		ret = aQueue.Receive(pDestinationData, aSize);
       
   122 		test(ret == KErrNone);
       
   123 		test(pD[0] == 0);
       
   124 		pD.FillZ();
       
   125 		ret = aQueue.Receive(pDestinationData, aSize);
       
   126 		test(ret == KErrNone);
       
   127 		test(pD[0] == 1);
       
   128 		pD.FillZ();
       
   129 
       
   130 		}
       
   131 	
       
   132 	test.Next(_L("Test filling the queue to the max"));
       
   133 	TInt x;
       
   134 	for (x = 0; x < aSlots; x++)
       
   135 		{
       
   136 		pS[0] = (TUint8)x;
       
   137 		ret = aQueue.Send(pSourceData, aSize);
       
   138 		test(ret == KErrNone);
       
   139 		}
       
   140 
       
   141 	test.Next(_L("Test one too many sends"));
       
   142 	ret = aQueue.Send(pSourceData, aSize);
       
   143 	test(ret == KErrOverflow);
       
   144 
       
   145 	test.Next(_L("test cancel SpaceAvailable"));
       
   146 	aQueue.NotifySpaceAvailable(stat);
       
   147 	test (stat == KRequestPending);
       
   148 	aQueue.CancelSpaceAvailable();
       
   149 	User::WaitForRequest(stat);
       
   150 	test (stat == KErrCancel);
       
   151 
       
   152 
       
   153 	test.Next(_L("Test emptying the queue"));
       
   154 
       
   155 	for (x = 0; x < aSlots; x++)
       
   156 		{
       
   157 		ret = aQueue.Receive(pDestinationData, aSize);
       
   158 		test(ret == KErrNone);
       
   159 		test(pD[0] == (TUint8)x );
       
   160 		pD.FillZ();
       
   161 		}
       
   162 
       
   163 	test.Next(_L("test cancel DataAvailable"));
       
   164 	aQueue.NotifyDataAvailable(stat);
       
   165 	test (stat == KRequestPending);
       
   166 	aQueue.CancelDataAvailable();
       
   167 	User::WaitForRequest(stat);
       
   168 	test (stat == KErrCancel);
       
   169 
       
   170 	test.Next(_L("Test one too many receives"));
       
   171 	ret = aQueue.Receive(pDestinationData, aSize);
       
   172 	test(ret == KErrUnderflow);
       
   173 
       
   174 
       
   175 	test.Next(_L("Test wrap around"));
       
   176 	test.Printf(_L("fill queue to max\n"));
       
   177 	for (x = 0; x < aSlots; x++)
       
   178 		{
       
   179 		pS[0] = (TUint8)x;
       
   180 		ret = aQueue.Send(pSourceData, aSize);
       
   181 		test(ret == KErrNone);
       
   182 		}
       
   183 
       
   184 	test.Printf(_L("half empty the queue\n"));
       
   185 	for (x = 0; x < aSlots/2; x++)
       
   186 		{
       
   187 		ret = aQueue.Receive(pDestinationData, aSize);
       
   188 		test(ret == KErrNone);
       
   189 		test(pD[0] == (TUint8)x);
       
   190 		pD.FillZ();
       
   191 		}
       
   192 
       
   193 	test.Printf(_L("fill queue to max\n"));
       
   194 	for (x = 0; x < aSlots/2; x++)
       
   195 		{
       
   196 		pS[0] = (TUint8)x;
       
   197 		ret = aQueue.Send(pSourceData, aSize);
       
   198 		test (ret == KErrNone);
       
   199 		}
       
   200 		ret = aQueue.Send(pSourceData, aSize);
       
   201 		test (ret == KErrOverflow);
       
   202 
       
   203 	test.Printf(_L("empty the queue\n"));
       
   204 	for (x = aSlots/2; x < aSlots; x++)
       
   205 		{
       
   206 		ret = aQueue.Receive(pDestinationData, aSize);
       
   207 		test(ret == KErrNone);
       
   208 		test(pD[0] == (TUint8)x);
       
   209 		}
       
   210 	for (x = 0; x < aSlots/2; x++)
       
   211 		{
       
   212 		ret = aQueue.Receive(pDestinationData, aSize);
       
   213 		test(ret == KErrNone);
       
   214 		test(pD[0] == (TUint8)x);
       
   215 		}
       
   216 
       
   217 	test.Next(_L("Test queue is empty"));
       
   218 	ret = aQueue.Receive(pDestinationData, aSize);
       
   219 	test(ret == KErrUnderflow);
       
   220 
       
   221 	User::Free(pSourceData);
       
   222 	User::Free(pDestinationData);
       
   223 	}
       
   224 
       
   225 
       
   226 _LIT(KThread2Name, "thread2");
       
   227 _LIT(KThread3Name, "thread3");
       
   228 _LIT(KThread4Name, "thread4");
       
   229 
       
   230 
       
   231 class TData 
       
   232 	{
       
   233 public:
       
   234 	TData(RMsgQueueBase* aQ, TInt aSize, TInt aSlots,TInt aTest=0, TAny* aData=NULL);
       
   235 	RMsgQueueBase* iQueue;
       
   236 	TInt iSize;
       
   237 	TInt iSlots;
       
   238 	TInt iTest;
       
   239 	TAny* iData;
       
   240 	};
       
   241 
       
   242 TData::TData(RMsgQueueBase* aQ, TInt aSize, TInt aSlots, TInt aTest, TAny* aData) :	iQueue(aQ), iSize(aSize),
       
   243 																		iSlots(aSlots), iTest(aTest), iData(aData)
       
   244 	{
       
   245 	//empty
       
   246 	};
       
   247 
       
   248 
       
   249 
       
   250 LOCAL_C TInt illegalSendEntryPoint(TAny* aData)
       
   251 	{
       
   252 	
       
   253 	TData& data = *(TData *)aData;
       
   254 
       
   255 	switch (data.iTest)
       
   256 		{
       
   257 	case 0:
       
   258 		data.iQueue->Send(data.iData, data.iSize*2);	//should panic, message size incorrect
       
   259 		break;
       
   260 
       
   261 	case 1:
       
   262 #ifdef _DEBUGGER_BUILD
       
   263 		#pragma message ("BUILT FOR DEBUGGER")
       
   264 		User::Panic(_L("test"),ECausedException);
       
   265 #else
       
   266 		data.iQueue->Send((TAny*)0xfeed, data.iSize);	//should panic
       
   267 #endif
       
   268 	break;
       
   269 
       
   270 	case 2:
       
   271 #ifdef _DEBUGGER_BUILD
       
   272 		#pragma message ("BUILT FOR DEBUGGER")
       
   273 		User::Panic(_L("test"),ECausedException);
       
   274 #else
       
   275 		data.iQueue->Send((TAny*)0xDEDEDEDE, data.iSize);	//dodgy address
       
   276 #endif	
       
   277 		break;
       
   278 		}
       
   279 
       
   280 	test(0);	//should never get here.  This'll make a Kern Exec 0! as tries to use console from different thread
       
   281 	return 0;
       
   282 	}
       
   283 
       
   284 
       
   285 LOCAL_C TInt illegalReceiveEntryPoint(TAny* aData)
       
   286 	{
       
   287 	
       
   288 	TData& data = *(TData *)aData;
       
   289 	TUint8 buf[256];
       
   290 
       
   291 	switch (data.iTest)
       
   292 		{
       
   293 	case 0:
       
   294 		data.iQueue->Receive(buf, data.iSize*2);	//should panic, message size incorrect
       
   295 		break;
       
   296 
       
   297 	case 1:
       
   298 #ifdef _DEBUGGER_BUILD
       
   299 		#pragma message ("BUILT FOR DEBUGGER")
       
   300 		User::Panic(_L("test"),ECausedException);
       
   301 #else
       
   302 		data.iQueue->Receive((TAny*)0xfeed, data.iSize);	//should panic
       
   303 #endif
       
   304 		break;
       
   305 
       
   306 	case 2:
       
   307 #ifdef _DEBUGGER_BUILD
       
   308 		#pragma message ("BUILT FOR DEBUGGER")
       
   309 		User::Panic(_L("test"),ECausedException);
       
   310 #else
       
   311 		data.iQueue->Receive((TAny*)0xDEDEDEDE, data.iSize);	//dodgy address
       
   312 #endif
       
   313 		break;
       
   314 
       
   315 		}
       
   316 
       
   317 	test(0);	//should never get here.  This'll make a Kern Exec 0!
       
   318 	return 0;
       
   319 	}
       
   320 
       
   321 
       
   322 
       
   323 LOCAL_C TInt sendBlockingEntryPoint(TAny* aData)
       
   324 	{
       
   325 	TData& data = *(TData *)aData;
       
   326 
       
   327 	TInt d = KTestValue;
       
   328 	data.iQueue->SendBlocking(&d, 4);
       
   329 	return KErrNone;
       
   330 	}
       
   331 
       
   332 LOCAL_C TInt receiveBlockingEntryPoint(TAny* aData)
       
   333 	{
       
   334 	TData& data = *(TData *)aData;
       
   335 
       
   336 	TUint8  pData[256];
       
   337 	TPtr8 pD(pData, data.iSize, data.iSize);
       
   338 	pD.FillZ();
       
   339 	data.iQueue->ReceiveBlocking(pData, data.iSize);
       
   340 	test (*(TInt*)pData == KTestValue);
       
   341 	return KErrNone;
       
   342 	}
       
   343 
       
   344 
       
   345 LOCAL_C TInt notifyDataAvailableEntryPoint(TAny* aData)
       
   346 	{
       
   347 	TData& data = *(TData *)aData;
       
   348 
       
   349 	//check size as well
       
   350 	test(data.iQueue->MessageSize() == data.iSize);
       
   351 
       
   352 	TRequestStatus stat;
       
   353 	data.iQueue->NotifyDataAvailable(stat);
       
   354 	User::WaitForRequest(stat);
       
   355 	return KErrNone;
       
   356 	}
       
   357 
       
   358 LOCAL_C TInt notifySpaceAvailableEntryPoint(TAny* aData)
       
   359 	{
       
   360 	TData& data = *(TData *)aData;
       
   361 
       
   362 	TRequestStatus stat;
       
   363 	data.iQueue->NotifySpaceAvailable(stat);
       
   364 	User::WaitForRequest(stat);
       
   365 	return KErrNone;
       
   366 	}
       
   367 
       
   368 
       
   369 
       
   370 LOCAL_C void MultiThreadedTests(RMsgQueueBase& aQueue, TInt aSlots, TInt aSize)
       
   371 	{
       
   372 	test.Next(_L("multi threaded tests"));
       
   373 	RThread thread2;
       
   374 	TInt ret = KErrNone;
       
   375 
       
   376 	TAny* ptr = User::Alloc(aSize);
       
   377 
       
   378 	test.Next(_L("test Send with illegal parameters"));
       
   379 	TInt testnum;
       
   380 	TBool jit = User::JustInTime();
       
   381 	User::SetJustInTime(EFalse);
       
   382 	for (testnum = 0; testnum < 3; testnum++)	//testnum range is determined by the number of tests in illegalSendEntryPoint
       
   383 		{
       
   384 		TData data(&aQueue, aSize, aSlots, testnum, ptr);
       
   385 		ret = thread2.Create(KThread2Name, illegalSendEntryPoint, KDefaultStackSize, KHeapSize, KHeapSize, &data);
       
   386 		test(KErrNone == ret);
       
   387 		TRequestStatus thread2stat;
       
   388 		thread2.Logon(thread2stat);
       
   389 		thread2.Resume();
       
   390 		User::WaitForRequest(thread2stat);
       
   391 		test (thread2.ExitType() == EExitPanic);
       
   392 		switch (testnum)
       
   393 		{
       
   394 		case 0:
       
   395 		test (thread2.ExitReason() == EMsgQueueInvalidLength);
       
   396 		break;
       
   397 		case 1:
       
   398 		test (thread2.ExitReason() == ECausedException);
       
   399 		break;
       
   400 		case 2:
       
   401 		test (thread2.ExitReason() == ECausedException);
       
   402 		break;
       
   403 		}
       
   404 
       
   405 		CLOSE_AND_WAIT(thread2);
       
   406 		}
       
   407 
       
   408 	
       
   409 	User::SetJustInTime(jit);
       
   410 
       
   411 	
       
   412 	test.Next(_L("test Receive with illegal parameters"));
       
   413 	jit = User::JustInTime();
       
   414 	User::SetJustInTime(EFalse);
       
   415 
       
   416 
       
   417 	for (testnum = 0; testnum < 3; testnum++)	//testnum range is determined by the number of tests in illegalReceiveEntryPoint
       
   418 		{
       
   419 	//put something in the queue
       
   420 		aQueue.Send(&testnum, 4);
       
   421 		TData data(&aQueue, aSize, aSlots, testnum, ptr);
       
   422 		ret = thread2.Create(KThread2Name, illegalReceiveEntryPoint, KDefaultStackSize, KHeapSize, KHeapSize, &data);
       
   423 		test(KErrNone == ret);
       
   424 		TRequestStatus thread2stat;
       
   425 		thread2.Logon(thread2stat);
       
   426 		thread2.Resume();
       
   427 		User::WaitForRequest(thread2stat);
       
   428 		test (thread2.ExitType() == EExitPanic);
       
   429 		
       
   430 		switch (testnum)
       
   431 		{
       
   432 		case 0:
       
   433 		test (thread2.ExitReason() == EMsgQueueInvalidLength);
       
   434 		break;
       
   435 		case 1:
       
   436 		test (thread2.ExitReason() == ECausedException);
       
   437 		break;
       
   438 		case 2:
       
   439 		test (thread2.ExitReason() == ECausedException);
       
   440 		break;
       
   441 		}
       
   442 
       
   443 		CLOSE_AND_WAIT(thread2);
       
   444 		}
       
   445 
       
   446 	
       
   447 	User::SetJustInTime(jit);
       
   448 
       
   449 	while(KErrNone == aQueue.Receive(ptr, aSize))	//empty the queue
       
   450 		{
       
   451 		//empty,
       
   452 		}
       
   453 	
       
   454 	test.Next(_L("multi threaded NotifySpaceAvailable"));
       
   455 
       
   456 	TInt dummydata = KTestValue;
       
   457 	//fill the queue
       
   458 	while (KErrNone == aQueue.Send(&dummydata, sizeof (TInt)))
       
   459 		{
       
   460 		//empty
       
   461 		}
       
   462 
       
   463 	TData data(&aQueue, aSize, aSlots);
       
   464 	ret = thread2.Create(KThread2Name, notifySpaceAvailableEntryPoint, KDefaultStackSize, KHeapSize, KHeapSize, &data);
       
   465 	test(KErrNone == ret);
       
   466 	TRequestStatus thread2stat;
       
   467 	thread2.Logon(thread2stat);
       
   468 	thread2.Resume();
       
   469 
       
   470 	//thread2 should be waiting for space available
       
   471 	test (thread2stat == KRequestPending);
       
   472 	aQueue.ReceiveBlocking(ptr, aSize);
       
   473 	User::WaitForRequest(thread2stat);
       
   474 	test (thread2stat == KErrNone);
       
   475 	test (thread2.ExitType() == EExitKill);
       
   476 	CLOSE_AND_WAIT(thread2);
       
   477 	//thread 2 has exited OK
       
   478 
       
   479 	//empty the queue
       
   480 	while (KErrNone == aQueue.Receive(ptr, aSize))
       
   481 		{
       
   482 		//empty
       
   483 		}
       
   484 
       
   485 	
       
   486 	test.Next(_L("multi threaded SendBlocking, ReceiveBlocking"));
       
   487 	ret = thread2.Create(KThread2Name, receiveBlockingEntryPoint, KDefaultStackSize, KHeapSize, KHeapSize, &data);
       
   488 	test(KErrNone == ret);
       
   489 	thread2.Logon(thread2stat);
       
   490 	thread2.Resume();
       
   491 
       
   492 	aQueue.SendBlocking(&dummydata, sizeof (TInt));
       
   493 
       
   494 	User::WaitForRequest(thread2stat);
       
   495 	test (thread2.ExitType() == EExitKill);
       
   496 	CLOSE_AND_WAIT(thread2);
       
   497 
       
   498 
       
   499 	test.Next(_L("multiple ReceiveBlocking"));
       
   500 	ret = thread2.Create(KThread2Name, receiveBlockingEntryPoint, KDefaultStackSize, KHeapSize, KHeapSize, &data);
       
   501 	test(KErrNone == ret);
       
   502 
       
   503 	RThread thread3;
       
   504 	ret = thread3.Create(KThread3Name, receiveBlockingEntryPoint, KDefaultStackSize, KHeapSize, KHeapSize, &data);
       
   505 	test(KErrNone == ret);
       
   506 
       
   507 	RThread thread4;
       
   508 	ret = thread4.Create(KThread4Name, receiveBlockingEntryPoint, KDefaultStackSize, KHeapSize, KHeapSize, &data);
       
   509 	test(KErrNone == ret);
       
   510 
       
   511 	thread2.Logon(thread2stat);
       
   512 
       
   513 	TRequestStatus thread3stat;
       
   514 	thread3.Logon(thread3stat);
       
   515 	
       
   516 	TRequestStatus thread4stat;
       
   517 	thread4.Logon(thread4stat);
       
   518 
       
   519 	thread2.Resume();
       
   520 	User::After(500000);
       
   521 
       
   522 	jit = User::JustInTime();
       
   523 	User::SetJustInTime(EFalse);
       
   524 
       
   525 	thread3.Resume();
       
   526 	thread4.Resume();
       
   527 
       
   528 	
       
   529 	User::WaitForRequest(thread3stat, thread4stat);
       
   530 	if (thread3stat != KRequestPending)
       
   531 		User::WaitForRequest(thread4stat);
       
   532 	else
       
   533 		User::WaitForRequest(thread3stat);
       
   534 	User::SetJustInTime(jit);
       
   535 
       
   536 	//threads 3 and 4 have exited
       
   537 	test (thread3.ExitType() == EExitPanic);
       
   538 	test (thread3.ExitReason() == EMsgQueueRequestPending);
       
   539 	test (thread4.ExitType() == EExitPanic);
       
   540 	test (thread4.ExitReason() == EMsgQueueRequestPending);
       
   541 	
       
   542 	test (thread2stat == KRequestPending);
       
   543 	aQueue.SendBlocking(&dummydata, sizeof (TInt));
       
   544 	User::WaitForRequest(thread2stat);
       
   545 	test (thread2stat == KErrNone);
       
   546 	test (thread2.ExitType() == EExitKill);
       
   547 
       
   548 	CLOSE_AND_WAIT(thread2);
       
   549 	CLOSE_AND_WAIT(thread3);
       
   550 	CLOSE_AND_WAIT(thread4);
       
   551 
       
   552 
       
   553 	//fill the queue
       
   554 	while (KErrNone == aQueue.Send(&dummydata, sizeof (TInt)))
       
   555 		{
       
   556 		//empty
       
   557 		}
       
   558 
       
   559 	test.Next(_L("multiple sendblocking"));
       
   560 	ret = thread2.Create(KThread2Name, sendBlockingEntryPoint, KDefaultStackSize, KHeapSize, KHeapSize, &data);
       
   561 	test(KErrNone == ret);
       
   562 	ret = thread3.Create(KThread3Name, sendBlockingEntryPoint, KDefaultStackSize, KHeapSize, KHeapSize, &data);
       
   563 	test(KErrNone == ret);
       
   564 	ret = thread4.Create(KThread4Name, sendBlockingEntryPoint, KDefaultStackSize, KHeapSize, KHeapSize, &data);
       
   565 	test(KErrNone == ret);
       
   566 
       
   567 	thread2.Logon(thread2stat);
       
   568 	thread3.Logon(thread3stat);
       
   569 	thread4.Logon(thread4stat);
       
   570 
       
   571 	thread2.Resume();
       
   572 	User::After(500000);
       
   573 
       
   574 	jit = User::JustInTime();
       
   575 	User::SetJustInTime(EFalse);
       
   576 	thread3.Resume();
       
   577 	thread4.Resume();
       
   578 	User::WaitForRequest(thread3stat, thread4stat);
       
   579 	if (thread3stat != KRequestPending)
       
   580 		User::WaitForRequest(thread4stat);
       
   581 	else
       
   582 		User::WaitForRequest(thread3stat);
       
   583 	User::SetJustInTime(jit);
       
   584 
       
   585 	//threads 3 and 4 have exited
       
   586 	test (thread3.ExitType() == EExitPanic);
       
   587 	test (thread3.ExitReason() == EMsgQueueRequestPending);
       
   588 	test (thread4.ExitType() == EExitPanic);
       
   589 	test (thread4.ExitReason() == EMsgQueueRequestPending);
       
   590 	
       
   591 	test (thread2stat == KRequestPending);
       
   592 
       
   593 	//consume one to allow the blocking write
       
   594 	test(KErrNone == aQueue.Receive(ptr, aSize));
       
   595 
       
   596 	User::WaitForRequest(thread2stat);
       
   597 	test (thread2stat == KErrNone);
       
   598 	test (thread2.ExitType() == EExitKill);
       
   599 
       
   600 	//consume the rest of the queue
       
   601 	while (KErrNone == aQueue.Receive(ptr, aSize))
       
   602 		{
       
   603 		// empty
       
   604 		}
       
   605 
       
   606 	CLOSE_AND_WAIT(thread2);
       
   607 	CLOSE_AND_WAIT(thread3);
       
   608 	CLOSE_AND_WAIT(thread4);
       
   609 
       
   610 	
       
   611 	test.Next(_L("multi threaded NotifyDataAvailable"));
       
   612 	ret = thread2.Create(KThread2Name, notifyDataAvailableEntryPoint, KDefaultStackSize, KHeapSize, KHeapSize, &data);
       
   613 	test(KErrNone == ret);
       
   614 	thread2.Logon(thread2stat);
       
   615 	thread2.Resume();
       
   616 
       
   617 	//thread2 should be waiting for data available
       
   618 	test (thread2stat == KRequestPending);
       
   619 	aQueue.SendBlocking(&dummydata, sizeof (TInt));
       
   620 	User::WaitForRequest(thread2stat);
       
   621 	test (thread2stat == KErrNone);
       
   622 	test (thread2.ExitType() == EExitKill);
       
   623 	CLOSE_AND_WAIT(thread2);
       
   624 	//thread 2 has exited OK
       
   625 
       
   626 	//empty the queue
       
   627 	aQueue.ReceiveBlocking(ptr, aSize);
       
   628 	test (*(TInt*)ptr == dummydata);
       
   629 
       
   630 	//create thread 2 again 
       
   631 	ret = thread2.Create(KThread2Name, notifyDataAvailableEntryPoint, KDefaultStackSize, KHeapSize, KHeapSize, &data);
       
   632 	test(KErrNone == ret);
       
   633 	thread2.Logon(thread2stat);
       
   634 	thread2.Resume();
       
   635 
       
   636 	//create thread3
       
   637 	ret = thread3.Create(KThread3Name, notifyDataAvailableEntryPoint, KDefaultStackSize, KHeapSize, KHeapSize, &data);
       
   638 	test(KErrNone == ret);
       
   639 	thread3.Logon(thread3stat);
       
   640 	User::SetJustInTime(EFalse);
       
   641 	User::After(10000);
       
   642 	thread3.Resume();
       
   643 
       
   644 	User::WaitForRequest(thread3stat);
       
   645 	User::SetJustInTime(jit);
       
   646 	
       
   647 	test (thread3.ExitType() == EExitPanic);
       
   648 	test (thread3.ExitReason() == EMsgQueueRequestPending);
       
   649 	CLOSE_AND_WAIT(thread3);
       
   650 
       
   651 	aQueue.SendBlocking(&dummydata, sizeof (TInt));
       
   652 	User::WaitForRequest(thread2stat);
       
   653 	test (thread2stat == KErrNone);
       
   654 	test (thread2.ExitType() == EExitKill);
       
   655 	CLOSE_AND_WAIT(thread2);
       
   656 
       
   657 	//empty the queue
       
   658 	aQueue.ReceiveBlocking(ptr, aSize);
       
   659 	test (*(TInt*)ptr == dummydata);
       
   660 
       
   661 	User::Free(ptr);
       
   662 	}
       
   663 
       
   664 
       
   665 class TTemplateTestData
       
   666 	{
       
   667 public:
       
   668 	TTemplateTestData();
       
   669 	TTemplateTestData(TInt a, TUint b, TUint8 c, TBool d, TInt e);
       
   670 	TInt first;
       
   671 	TUint second;
       
   672 	TUint8 bob;
       
   673 	TBool fred;
       
   674 	TInt chipper;
       
   675 	};
       
   676 
       
   677 TTemplateTestData::TTemplateTestData()  : first(0), second(0), bob(0), fred(0), chipper(0)
       
   678 	{
       
   679 	}
       
   680 
       
   681 TTemplateTestData::TTemplateTestData(TInt a, TUint b, TUint8 c, TBool d, TInt e) : first(a), second(b), bob(c), fred(d), chipper(e)
       
   682 	{
       
   683 	}
       
   684 
       
   685 
       
   686 enum TQueueType {ECreateLocal, ECreateGlobal};
       
   687 
       
   688 LOCAL_C TInt illegalQueueCreation(TAny* aData)
       
   689 	{
       
   690 	TData& data = *(TData *)aData;
       
   691 	switch (data.iTest)
       
   692 		{
       
   693 		case ECreateLocal:	//CreateLocal
       
   694 			{
       
   695 			RMsgQueueBase queue;
       
   696 			queue.CreateLocal(data.iSlots, data.iSize);
       
   697 			break;
       
   698 			}
       
   699 		case ECreateGlobal:	//create global named
       
   700 			{
       
   701 			RMsgQueueBase queue;
       
   702 			queue.CreateGlobal(KGLobalName1,  data.iSlots, data.iSize);
       
   703 			break;
       
   704 			}
       
   705 		}
       
   706 	test(0);	//should never get here.  This'll make a Kern Exec 0! as tries to use console from different thread
       
   707 	return 0;
       
   708 	}
       
   709 
       
   710 
       
   711 LOCAL_C void TestIllegalCreation(TInt aSlots, TInt aSize, TQueueType aQueueType, TInt aExpectedReason)
       
   712 		{
       
   713 		RThread thread;
       
   714 		TData data(NULL, aSize, aSlots, aQueueType, NULL);
       
   715 		TRequestStatus threadstat;
       
   716 		TBool jit = User::JustInTime();
       
   717 		User::SetJustInTime(EFalse);
       
   718 		TInt ret = thread.Create(KThread2Name, illegalQueueCreation, KDefaultStackSize, KHeapSize, KHeapSize, &data);
       
   719 		test(KErrNone == ret);
       
   720 		thread.Logon(threadstat);
       
   721 		thread.Resume();
       
   722 		User::WaitForRequest(threadstat);
       
   723 		test (thread.ExitType() == EExitPanic);
       
   724 		test (thread.ExitReason() == aExpectedReason);
       
   725 		CLOSE_AND_WAIT(thread);
       
   726 		User::SetJustInTime(jit);
       
   727 		}
       
   728 
       
   729 TInt DyingDataAvailableThread( TAny* )
       
   730 	{
       
   731 	RMsgQueue<TInt>	theQ;
       
   732 	if( KErrNone != theQ.OpenGlobal(_L("TestNotifiedThreadDied")) )
       
   733 		User::Panic( _L("TESTTH"), 0 );
       
   734 
       
   735 	TRequestStatus stat;
       
   736 	theQ.NotifyDataAvailable( stat );
       
   737 	// now just exit
       
   738 	return KErrNone;
       
   739 	}
       
   740 
       
   741 TInt DyingSpaceAvailableThread( TAny* )
       
   742 	{
       
   743 	RMsgQueue<TInt>	theQ;
       
   744 	if( KErrNone != theQ.OpenGlobal(_L("TestNotifiedThreadDied")) )
       
   745 		User::Panic( _L("TESTTH"), 0 );
       
   746 
       
   747 	TRequestStatus stat;
       
   748 	theQ.NotifySpaceAvailable( stat );
       
   749 	// now just exit
       
   750 	return KErrNone;
       
   751 	}
       
   752 
       
   753 struct TThreadParams
       
   754 	{
       
   755 	TInt imyQHandle;
       
   756 	TRequestStatus* iRequest;
       
   757 	};
       
   758 	
       
   759 TInt DyingRequestDataNotification(TAny* aThreadParams)
       
   760 	{
       
   761 	CTrapCleanup* trapHandler = CTrapCleanup::New();
       
   762 	if(!trapHandler)
       
   763 		return KErrNoMemory;
       
   764 
       
   765 	TThreadParams* tp = reinterpret_cast<TThreadParams*>(aThreadParams);
       
   766 	
       
   767 	RMsgQueue<TInt> msgQue2;
       
   768 	msgQue2.SetHandle(tp->imyQHandle);
       
   769 	msgQue2.NotifyDataAvailable(*tp->iRequest);
       
   770 	
       
   771 	delete trapHandler;
       
   772 	return KErrNone;
       
   773 	}
       
   774 
       
   775 void TestNotifiedThreadDied()
       
   776 {
       
   777 	RThread th;
       
   778 	TRequestStatus stat;
       
   779 	RMsgQueue<TInt>	myQ;
       
   780 	test( KErrNone == myQ.CreateGlobal( _L("TestNotifiedThreadDied"), 1 ) );
       
   781 
       
   782 	//Test when thread waiting on data available dies
       
   783 	test( KErrNone == th.Create( _L("DyingDataAvailableThread"), DyingDataAvailableThread, 1024, 1024, 8192, NULL ) );
       
   784 	th.Logon( stat );
       
   785 	th.Resume();
       
   786 	User::WaitForRequest( stat );
       
   787 	test(stat.Int()==KErrNone);
       
   788 	
       
   789 	User::After( 1000000 );
       
   790 
       
   791 	myQ.NotifyDataAvailable( stat );
       
   792 	myQ.CancelDataAvailable();
       
   793 	CLOSE_AND_WAIT(th);
       
   794 
       
   795 	//Test when thread waiting on space available dies
       
   796 	myQ.Send(0);//This will fill in the whole message queue and block any thread waiting on space available.
       
   797 
       
   798 	test( KErrNone == th.Create( _L("DyingSpaceAvailableThread"), DyingSpaceAvailableThread, 1024, 1024, 8192, NULL ) );
       
   799 	th.Logon( stat );
       
   800 	th.Resume();
       
   801 	User::WaitForRequest( stat );
       
   802 	test(stat.Int()==KErrNone);
       
   803 	
       
   804 	User::After( 1000000 );
       
   805 
       
   806 	myQ.NotifySpaceAvailable( stat );
       
   807 	myQ.CancelSpaceAvailable();
       
   808 	myQ.Close();
       
   809 	CLOSE_AND_WAIT(th);
       
   810 
       
   811 	// Calling cancel notification should not crash as the thread that requested notification dies
       
   812 	test( KErrNone == myQ.CreateLocal(1, EOwnerProcess));
       
   813 
       
   814 	TThreadParams tp;
       
   815 	tp.imyQHandle = myQ.Handle();
       
   816 	tp.iRequest = &stat;
       
   817 
       
   818 	test( KErrNone == th.Create(_L("DyingRequestDataNotificationThread"), DyingRequestDataNotification, KDefaultStackSize, 
       
   819 									KHeapSize, KHeapSize, reinterpret_cast<TAny*>(&tp)));
       
   820 	TRequestStatus status;
       
   821 	th.Logon(status);
       
   822 	th.Resume();
       
   823 	th.Close();
       
   824 
       
   825 	User::WaitForRequest(status);
       
   826 	test(status.Int() == KErrNone);
       
   827 
       
   828 	myQ.CancelDataAvailable();
       
   829 	myQ.Close();
       
   830 
       
   831 }
       
   832 
       
   833 LOCAL_C void RunTests(void)
       
   834 	{
       
   835 	TInt ret = KErrNone;
       
   836 	test.Start(_L("Testing"));
       
   837 
       
   838 
       
   839 	RMsgQueueBase mqueue;
       
   840 
       
   841 //	LOCAL message queues
       
   842 
       
   843 
       
   844 	test.Next(_L("Check when thread dies waiting to be notified."));
       
   845 	TestNotifiedThreadDied();
       
   846 
       
   847 	test.Next(_L("Create private message queue with 0 length params"));
       
   848 	TestIllegalCreation(0,0,ECreateLocal, EMsgQueueInvalidLength);
       
   849 
       
   850 	test.Next(_L("Create private message queue with 0  slots"));
       
   851 	TestIllegalCreation(0,4,ECreateLocal, EMsgQueueInvalidSlots);
       
   852 
       
   853 	test.Next(_L("Create private message queue with 0 size message"));
       
   854 	TestIllegalCreation(5, 0, ECreateLocal, EMsgQueueInvalidLength);
       
   855 
       
   856 	test.Next(_L("Create private message queue with none multiple of 4 size message"));
       
   857 	TestIllegalCreation(5, 9, ECreateLocal, EMsgQueueInvalidLength);
       
   858 
       
   859 	test.Next(_L("Create private message queue with illegal max length "));
       
   860 	TestIllegalCreation(8,RMsgQueueBase::KMaxLength+1, ECreateLocal, EMsgQueueInvalidLength);
       
   861 
       
   862 
       
   863 	test.Next(_L("Create private message queue, 43 slots, length 8"));
       
   864 	ret = mqueue.CreateLocal(43,8, EOwnerThread);
       
   865 	test (KErrNone == ret);
       
   866 	mqueue.Close();
       
   867 
       
   868 	test.Next(_L("Create private message queue with max length "));
       
   869 	ret = mqueue.CreateLocal(8, RMsgQueueBase::KMaxLength, EOwnerProcess);
       
   870 	test (KErrNone == ret);
       
   871 	mqueue.Close();
       
   872 
       
   873 	test.Next(_L("test private message queue functionality"));
       
   874 	
       
   875 	test.Printf(_L("two slots, small queue"));
       
   876 	ret = mqueue.CreateLocal(2, 4);
       
   877 	test(KErrNone == ret);
       
   878 	SingleThreadedTests(mqueue, 2, 4);
       
   879 	MultiThreadedTests(mqueue, 2, 4);
       
   880 	mqueue.Close();
       
   881 
       
   882 	test.Printf(_L("16 slots, max queue"));
       
   883 	ret = mqueue.CreateLocal(16, RMsgQueueBase::KMaxLength);
       
   884 	test(KErrNone == ret);
       
   885 	SingleThreadedTests(mqueue, 16, RMsgQueueBase::KMaxLength);
       
   886 	MultiThreadedTests(mqueue, 16, RMsgQueueBase::KMaxLength);
       
   887 	mqueue.Close();
       
   888 
       
   889 	test.Printf(_L("big slots, max queue"));
       
   890 	ret = mqueue.CreateLocal(KMaxTInt, RMsgQueueBase::KMaxLength);
       
   891 	test(KErrNoMemory == ret);
       
   892 
       
   893 
       
   894 	/**************************************************************************/
       
   895 //	GLOBAL Named message queues
       
   896 	test.Next(_L("Create global named message queue with 0 length params"));
       
   897 	TestIllegalCreation(0, 0, ECreateGlobal, EMsgQueueInvalidLength);
       
   898 
       
   899 	test.Next(_L("Create global named message queue with 0  slots"));
       
   900 	TestIllegalCreation(0, 4, ECreateGlobal, EMsgQueueInvalidSlots);
       
   901 
       
   902 	test.Next(_L("Create global message queue with 0 size message"));
       
   903 	TestIllegalCreation(5, 0, ECreateGlobal, EMsgQueueInvalidLength);
       
   904 
       
   905 	test.Next(_L("Create global message queue with none multiple of 4 size message"));
       
   906 	TestIllegalCreation(5, 9, ECreateGlobal, EMsgQueueInvalidLength);
       
   907 
       
   908 	test.Next(_L("Create global named message queue with illegal max length "));
       
   909 	TestIllegalCreation(8, RMsgQueueBase::KMaxLength+1, ECreateGlobal, EMsgQueueInvalidLength);
       
   910 
       
   911 	test.Next(_L("Create global named message queue"));
       
   912 	ret = mqueue.CreateGlobal(KGLobalName1, 10,8, EOwnerThread);
       
   913 	test (KErrNone == ret);
       
   914 	mqueue.Close();
       
   915 
       
   916 	test.Next(_L("Create global named message queue with max length "));
       
   917 	ret = mqueue.CreateGlobal(KGLobalName1, 8, RMsgQueueBase::KMaxLength, EOwnerProcess);
       
   918 	test (KErrNone == ret);
       
   919 	mqueue.Close();
       
   920 
       
   921 	test.Next(_L("test global named message queue functionality"));
       
   922 	
       
   923 	test.Printf(_L("small queue, two slots"));
       
   924 	ret = mqueue.CreateGlobal(KGLobalName1, 2, 4);
       
   925 	test(KErrNone == ret);
       
   926 	SingleThreadedTests(mqueue, 2, 4);
       
   927 	MultiThreadedTests(mqueue, 2, 4);
       
   928 	mqueue.Close();
       
   929 
       
   930 	test.Printf(_L("max queue, 16 slots"));
       
   931 	ret = mqueue.CreateGlobal(KGLobalName1, 16, RMsgQueueBase::KMaxLength);
       
   932 	test(KErrNone == ret);
       
   933 	SingleThreadedTests(mqueue, 16, RMsgQueueBase::KMaxLength);
       
   934 	MultiThreadedTests(mqueue, 16, RMsgQueueBase::KMaxLength);
       
   935 	mqueue.Close();
       
   936 
       
   937 	test.Printf(_L("32byte queue, 1000 slots"));
       
   938 	ret = mqueue.CreateGlobal(KGLobalName1, 1000, 32);
       
   939 	test(KErrNone == ret);
       
   940 	SingleThreadedTests(mqueue, 1000, 32);
       
   941 	MultiThreadedTests(mqueue, 1000, 32);
       
   942 	mqueue.Close();
       
   943 
       
   944 	test.Printf(_L("12 byte queue, 1 slot"));
       
   945 	ret = mqueue.CreateGlobal(KGLobalName1, 1, 12);
       
   946 	test(KErrNone == ret);
       
   947 	SingleThreadedTests(mqueue, 1, 12);
       
   948 	MultiThreadedTests(mqueue, 1, 12);
       
   949 	mqueue.Close();
       
   950 
       
   951 
       
   952 	test.Printf(_L("max queue, maxint! slots"));
       
   953 	ret = mqueue.CreateGlobal(KGLobalName1, KMaxTInt, RMsgQueueBase::KMaxLength);
       
   954 	test(KErrNoMemory == ret);
       
   955 
       
   956 	_LIT(KNonQueueName,"non-queue name");
       
   957 	test.Printf(_L("open a non-existant queue"));
       
   958 	ret = mqueue.OpenGlobal(KNonQueueName, EOwnerProcess);
       
   959 	test(ret == KErrNotFound);
       
   960 
       
   961 
       
   962 	ret = mqueue.CreateGlobal(KGLobalName1, 16, 4);
       
   963 	test(KErrNone == ret);
       
   964 	SingleThreadedTests(mqueue, 16, 4);
       
   965 	MultiThreadedTests(mqueue, 16, 4);
       
   966 	RMsgQueueBase open;
       
   967 
       
   968 	ret = open.OpenGlobal(KGLobalName1);
       
   969 	test(KErrNone == ret);
       
   970 	SingleThreadedTests(open, 16,4);
       
   971 	MultiThreadedTests(open, 16, 4);
       
   972 
       
   973 
       
   974 	test.Next(_L("Send a legal message through"));
       
   975 	TInt src = 45;
       
   976 	TInt dst = 0;
       
   977 	ret = mqueue.Send(&src, sizeof (TInt));
       
   978 	test(ret == KErrNone);
       
   979 
       
   980 	test.Next(_L("Receive legal message"));
       
   981 	ret = open.Receive(&dst, 4);
       
   982 	test(ret == KErrNone);
       
   983 	test (src == dst);
       
   984 
       
   985 	test.Next(_L("Send a legal message through"));
       
   986 	ret = mqueue.Send(&src, sizeof (TInt));
       
   987 	test(ret == KErrNone);
       
   988 
       
   989 	open.Close();
       
   990 	mqueue.Close();
       
   991 	
       
   992 
       
   993 	ret = mqueue.CreateGlobal(KNullDesC, 5, 4);
       
   994 	test(KErrNone == ret);
       
   995 	SingleThreadedTests(mqueue, 5,4);
       
   996 	MultiThreadedTests(mqueue, 5, 4);
       
   997 
       
   998 	ret = open.OpenGlobal(KNullDesC);
       
   999 	test(KErrNotFound == ret);
       
  1000 
       
  1001 	mqueue.Close();
       
  1002 	
       
  1003 
       
  1004 	test.Next(_L("Multi Process Queue Tests"));
       
  1005 	
       
  1006 _LIT(KQueueA, "A");
       
  1007 _LIT(KQueueB, "B");
       
  1008 _LIT(KProcessName, "T_MQUEUEECHO.EXE");
       
  1009 
       
  1010 	RMsgQueueBase inQueue;
       
  1011 	RMsgQueueBase outQueue;
       
  1012 
       
  1013 	TInt sizes[6] = {4,8,16,32,100,256};
       
  1014 
       
  1015 	TInt x;
       
  1016 	for (x = 0; x < 6; x++)
       
  1017 		{
       
  1018 		TUint8* p = (TUint8*)User::Alloc(sizes[x]);
       
  1019 		TRequestStatus stat;
       
  1020 		test (p != NULL);
       
  1021 		ret = inQueue.CreateGlobal(KQueueB, 1, sizes[x]);
       
  1022 		test (KErrNone == ret);
       
  1023 		ret = outQueue.CreateGlobal(KQueueA, 1, sizes[x]);
       
  1024 		test (KErrNone == ret);
       
  1025 
       
  1026 		//start other process
       
  1027 		RProcess proc;
       
  1028 		ret = proc.Create(KProcessName, KNullDesC);
       
  1029 		test (KErrNone == ret);
       
  1030 
       
  1031 		//logon to it
       
  1032 		proc.Logon(stat);
       
  1033 
       
  1034 		proc.Resume();
       
  1035 
       
  1036 		TInt y[64] = {1000};
       
  1037 
       
  1038 		while (--y[0] >= 0)
       
  1039 			{
       
  1040 			outQueue.SendBlocking(&y,sizes[x]);
       
  1041 			inQueue.ReceiveBlocking(p, sizes[x]);
       
  1042 			test (y[0] == *(TInt*)p);
       
  1043 			}
       
  1044 		
       
  1045 		User::Free(p);
       
  1046 		inQueue.Close();
       
  1047 		outQueue.Close();
       
  1048 
       
  1049 		//wait for the process to terminate
       
  1050 		User::WaitForRequest(stat);
       
  1051 		test(stat == KErrNone);
       
  1052 		CLOSE_AND_WAIT(proc);
       
  1053 		}
       
  1054 
       
  1055 	test.Next(_L("test templated queue"));
       
  1056 	RMsgQueue<TTemplateTestData> templateQueue;
       
  1057 	TTemplateTestData ch(1,2,3,ETrue,4);
       
  1058 	TTemplateTestData ch2;
       
  1059 	TTemplateTestData ch3;
       
  1060 
       
  1061 	test(KErrNone == templateQueue.CreateLocal(12));
       
  1062 
       
  1063 	test (KErrNone == templateQueue.Send(ch));
       
  1064 	test (ch.first != ch2.first);
       
  1065 	test (ch.chipper != ch2.chipper);
       
  1066 	test (KErrNone == templateQueue.Receive(ch2));
       
  1067 	test (ch.first == ch2.first);
       
  1068 	test (ch.chipper == ch2.chipper);
       
  1069 
       
  1070 	templateQueue.SendBlocking(ch);
       
  1071 	test (ch.first != ch3.first);
       
  1072 	test (ch.chipper != ch3.chipper);
       
  1073 	templateQueue.ReceiveBlocking(ch3);
       
  1074 	test (ch.first == ch3.first);
       
  1075 	test (ch.chipper == ch3.chipper);
       
  1076 
       
  1077 	templateQueue.Close();
       
  1078 
       
  1079 	test(KErrNone == templateQueue.CreateGlobal(KNullDesC, 79));
       
  1080 	templateQueue.Close();
       
  1081 
       
  1082 _LIT(KTestName, "testQueue");
       
  1083 
       
  1084 	test(KErrNone == templateQueue.CreateGlobal(KTestName, 986));
       
  1085 
       
  1086 	RMsgQueue<TTemplateTestData> templateQueue2;
       
  1087 	test(KErrNone == templateQueue2.OpenGlobal(KTestName));
       
  1088 	templateQueue.Close();
       
  1089 	templateQueue2.Close();
       
  1090 
       
  1091 	
       
  1092 	test.Next(_L("Ending test.\n"));
       
  1093 	test.End();
       
  1094 	
       
  1095 	test.Close();
       
  1096 	}
       
  1097 
       
  1098 GLDEF_C TInt E32Main()
       
  1099 //
       
  1100 //
       
  1101     {
       
  1102 	test.Title();
       
  1103 
       
  1104 	// Turn off evil lazy dll unloading
       
  1105 	RLoader l;
       
  1106 	test(l.Connect()==KErrNone);
       
  1107 	test(l.CancelLazyDllUnload()==KErrNone);
       
  1108 	l.Close();
       
  1109 	
       
  1110 	RunTests();
       
  1111 	return KErrNone;
       
  1112     }
       
  1113