os/kernelhwsrv/kerneltest/e32test/misc/t_svrstress.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Copyright (c) 2008-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\misc\t_svrstress.cpp
sl@0
    15
// This is a stress test for client server session connect and disconnect
sl@0
    16
//
sl@0
    17
sl@0
    18
#include <e32base.h>
sl@0
    19
#include <e32base_private.h>
sl@0
    20
#define __E32TEST_EXTENSION__
sl@0
    21
#include <e32test.h>
sl@0
    22
#include <e32svr.h>
sl@0
    23
#include "u32std.h"
sl@0
    24
#include <e32atomics.h>
sl@0
    25
#include <e32panic.h>
sl@0
    26
#include <e32def.h>
sl@0
    27
#include <e32def_private.h>
sl@0
    28
sl@0
    29
RTest test(_L("T_SVRSTRESS"));
sl@0
    30
sl@0
    31
RSemaphore SyncSemaphore;
sl@0
    32
TUint32 WaitABit;
sl@0
    33
sl@0
    34
TInt NumMessageSlots;
sl@0
    35
TInt UseGlobalMessagePool;
sl@0
    36
sl@0
    37
const TInt BigDesLength = 256 * 1024;
sl@0
    38
sl@0
    39
#if 1
sl@0
    40
#define TRACE(t) RDebug::RawPrint(_L8(t))
sl@0
    41
#else
sl@0
    42
#define TRACE(t)
sl@0
    43
#endif
sl@0
    44
sl@0
    45
//
sl@0
    46
// utility functions...
sl@0
    47
//
sl@0
    48
sl@0
    49
void WaitForRequest()
sl@0
    50
	{
sl@0
    51
	User::WaitForAnyRequest();
sl@0
    52
	RThread().RequestSignal(); // put request semaphore count back
sl@0
    53
	}
sl@0
    54
sl@0
    55
sl@0
    56
TInt WaitForRequest(TRequestStatus& aStatus,TTimeIntervalMicroSeconds32 aTimeout=2*1000000)
sl@0
    57
	{
sl@0
    58
	RTimer timer;
sl@0
    59
	test_Equal(KErrNone,timer.CreateLocal());
sl@0
    60
sl@0
    61
	TRequestStatus timeoutStatus;
sl@0
    62
	timer.After(timeoutStatus,aTimeout);
sl@0
    63
sl@0
    64
	User::WaitForRequest(aStatus,timeoutStatus);
sl@0
    65
sl@0
    66
	TInt r;
sl@0
    67
	if(aStatus.Int()==KRequestPending)
sl@0
    68
		{
sl@0
    69
		r = KErrTimedOut;
sl@0
    70
		}
sl@0
    71
	else
sl@0
    72
		{
sl@0
    73
		r = KErrNone;
sl@0
    74
		timer.Cancel();
sl@0
    75
		User::WaitForRequest(timeoutStatus);
sl@0
    76
		}
sl@0
    77
sl@0
    78
	CLOSE_AND_WAIT(timer);
sl@0
    79
sl@0
    80
	return r;
sl@0
    81
	}
sl@0
    82
sl@0
    83
sl@0
    84
//
sl@0
    85
// CMyServer
sl@0
    86
//
sl@0
    87
sl@0
    88
_LIT(KMyServerName,"StressSvr");
sl@0
    89
sl@0
    90
class CMyServer : public CServer2
sl@0
    91
	{
sl@0
    92
public:
sl@0
    93
	CMyServer(TInt aPriority);
sl@0
    94
	static CMyServer* New(TInt aPriority);
sl@0
    95
	virtual CSession2* NewSessionL(const TVersion&, const RMessage2&) const;
sl@0
    96
	};
sl@0
    97
sl@0
    98
sl@0
    99
class CMySession : public CSession2
sl@0
   100
	{
sl@0
   101
public:
sl@0
   102
	virtual void ServiceL(const RMessage2& aMessage);
sl@0
   103
	};
sl@0
   104
sl@0
   105
sl@0
   106
CMyServer* CMyServer::New(TInt aPriority)
sl@0
   107
	{
sl@0
   108
	return new CMyServer(aPriority);
sl@0
   109
	}
sl@0
   110
sl@0
   111
sl@0
   112
CMyServer::CMyServer(TInt aPriority)
sl@0
   113
	: CServer2(aPriority, ESharableSessions)
sl@0
   114
	{}
sl@0
   115
sl@0
   116
sl@0
   117
CSession2* CMyServer::NewSessionL(const TVersion&, const RMessage2&) const
sl@0
   118
	{
sl@0
   119
	TRACE("O");
sl@0
   120
	return new(ELeave) CMySession;
sl@0
   121
	}
sl@0
   122
sl@0
   123
sl@0
   124
TBool RestartServer;
sl@0
   125
sl@0
   126
TInt MyServerThread(TAny*)
sl@0
   127
	{
sl@0
   128
	CActiveScheduler* pR=new CActiveScheduler;
sl@0
   129
	if(!pR)
sl@0
   130
		return KErrNoMemory;
sl@0
   131
	CActiveScheduler::Install(pR);
sl@0
   132
	RestartServer = ETrue;
sl@0
   133
sl@0
   134
	while(RestartServer)
sl@0
   135
		{
sl@0
   136
		__UHEAP_MARK;
sl@0
   137
		CMyServer* pS=CMyServer::New(0);
sl@0
   138
		if(!pS)
sl@0
   139
			return KErrNoMemory;
sl@0
   140
		TInt r = pS->Start(KMyServerName);
sl@0
   141
		if(r!=KErrNone)
sl@0
   142
			return r;
sl@0
   143
sl@0
   144
		TRACE("S");
sl@0
   145
		RThread::Rendezvous(KErrNone);
sl@0
   146
sl@0
   147
		CActiveScheduler::Start();
sl@0
   148
sl@0
   149
		delete pS;
sl@0
   150
		__UHEAP_MARKEND;
sl@0
   151
		}
sl@0
   152
sl@0
   153
	delete pR;
sl@0
   154
	return KErrNone;
sl@0
   155
	}
sl@0
   156
sl@0
   157
sl@0
   158
//
sl@0
   159
// RMyServer
sl@0
   160
//
sl@0
   161
sl@0
   162
class RMyServer : public RSessionBase
sl@0
   163
	{
sl@0
   164
public:
sl@0
   165
	enum TFunction
sl@0
   166
		{
sl@0
   167
		EStop,
sl@0
   168
		ESync,
sl@0
   169
		EPing,
sl@0
   170
		EShutdown,
sl@0
   171
		ECompleteWhileCopying
sl@0
   172
		};
sl@0
   173
public:
sl@0
   174
	TInt Connect();
sl@0
   175
sl@0
   176
	inline TInt Send(TFunction aFunction) const
sl@0
   177
		{ return SendReceive(aFunction); }
sl@0
   178
sl@0
   179
	inline TInt Send(TFunction aFunction, const TIpcArgs& aArgs) const
sl@0
   180
		{ return SendReceive(aFunction, aArgs); }
sl@0
   181
sl@0
   182
	inline void Send(TFunction aFunction, TRequestStatus& aStatus) const
sl@0
   183
		{ SendReceive(aFunction, aStatus); }
sl@0
   184
sl@0
   185
	inline void Send(TFunction aFunction, const TIpcArgs& aArgs, TRequestStatus& aStatus) const
sl@0
   186
		{ SendReceive(aFunction, aArgs, aStatus); }
sl@0
   187
	};
sl@0
   188
sl@0
   189
sl@0
   190
TInt RMyServer::Connect()
sl@0
   191
	{
sl@0
   192
	RMyServer temp;
sl@0
   193
	TInt r = temp.CreateSession(KMyServerName, TVersion(), UseGlobalMessagePool ? -1 : NumMessageSlots);
sl@0
   194
	if(r!=KErrNone)
sl@0
   195
		return r;
sl@0
   196
sl@0
   197
	// turn handle into process owned...
sl@0
   198
	RMyServer temp2(temp);
sl@0
   199
	r = temp2.Duplicate(RThread());
sl@0
   200
	temp.Close();
sl@0
   201
sl@0
   202
	*this = temp2;
sl@0
   203
	return r;
sl@0
   204
	}
sl@0
   205
sl@0
   206
sl@0
   207
sl@0
   208
//
sl@0
   209
// CMySession
sl@0
   210
//
sl@0
   211
sl@0
   212
TInt CopierThread(TAny* aPtr)
sl@0
   213
	{
sl@0
   214
	RMessage2& msg = *(RMessage2*)aPtr;
sl@0
   215
	HBufC* bigdes = HBufC::NewMax(BigDesLength);
sl@0
   216
	if (bigdes == NULL)
sl@0
   217
		return KErrNoMemory;
sl@0
   218
	TPtr ptr = bigdes->Des();
sl@0
   219
	RThread().Rendezvous(KErrNone);
sl@0
   220
	RDebug::Print(_L("START\n"));
sl@0
   221
	TInt r = msg.Read(2, ptr);
sl@0
   222
	RDebug::Print(_L("DONE\n"));
sl@0
   223
	delete bigdes;
sl@0
   224
	return r;
sl@0
   225
	}
sl@0
   226
sl@0
   227
void CMySession::ServiceL(const RMessage2& aMessage)
sl@0
   228
	{
sl@0
   229
	RThread client;
sl@0
   230
	RThread copier;
sl@0
   231
	aMessage.Client(client);
sl@0
   232
	TRequestStatus* s;
sl@0
   233
	TRequestStatus* s2;
sl@0
   234
	TRequestStatus logon, rendez;
sl@0
   235
	TInt r;
sl@0
   236
	s = (TRequestStatus*)aMessage.Ptr0();
sl@0
   237
sl@0
   238
	switch(aMessage.Function())
sl@0
   239
		{
sl@0
   240
	case RMyServer::EStop:
sl@0
   241
		TRACE("E");
sl@0
   242
		CActiveScheduler::Stop();
sl@0
   243
		break;
sl@0
   244
sl@0
   245
	case RMyServer::ESync:
sl@0
   246
		TRACE("Y");
sl@0
   247
		client.RequestComplete(s,KErrNone);		// let client know we've received the message
sl@0
   248
		SyncSemaphore.Wait();					// wait for signal from client
sl@0
   249
		s = (TRequestStatus*)aMessage.Ptr1();	// use second status for later end signal
sl@0
   250
		aMessage.Complete(KErrNone);			// complete the message
sl@0
   251
		break;
sl@0
   252
sl@0
   253
	case RMyServer::EPing:
sl@0
   254
		TRACE("P");
sl@0
   255
		aMessage.Complete(KErrNone);
sl@0
   256
		break;
sl@0
   257
sl@0
   258
	case RMyServer::EShutdown:
sl@0
   259
		TRACE("D");
sl@0
   260
		RestartServer = EFalse;
sl@0
   261
		CActiveScheduler::Stop();
sl@0
   262
		break;
sl@0
   263
sl@0
   264
	case RMyServer::ECompleteWhileCopying:
sl@0
   265
		s2 = (TRequestStatus*)aMessage.Ptr1();
sl@0
   266
		r = copier.Create(_L("Copier"),CopierThread,KDefaultStackSize,&User::Allocator(),(TAny*)&aMessage);
sl@0
   267
		if (r == KErrNone)
sl@0
   268
			{
sl@0
   269
			copier.Logon(logon);
sl@0
   270
			copier.Rendezvous(rendez);
sl@0
   271
			copier.SetPriority(EPriorityLess);
sl@0
   272
			copier.Resume();
sl@0
   273
			User::WaitForRequest(rendez);
sl@0
   274
			User::AfterHighRes(5000); // 5ms delay to let copy actually start
sl@0
   275
			RDebug::Print(_L("COMPLETING\n"));
sl@0
   276
			aMessage.Complete(KErrNone);
sl@0
   277
			User::WaitForRequest(logon);
sl@0
   278
			copier.Close();
sl@0
   279
			}
sl@0
   280
		client.RequestComplete(s,r);
sl@0
   281
		s = s2;
sl@0
   282
		break;
sl@0
   283
sl@0
   284
	default:
sl@0
   285
		TRACE("?");
sl@0
   286
		aMessage.Complete(KErrNotSupported);
sl@0
   287
		break;
sl@0
   288
		}
sl@0
   289
sl@0
   290
	// let client know we've completed the message...
sl@0
   291
	TRACE("X");
sl@0
   292
	client.RequestComplete(s,KErrNone);
sl@0
   293
sl@0
   294
	client.Close();
sl@0
   295
	}
sl@0
   296
sl@0
   297
sl@0
   298
sl@0
   299
//
sl@0
   300
// RStressThread
sl@0
   301
//
sl@0
   302
sl@0
   303
class RStressThread
sl@0
   304
	{
sl@0
   305
public:
sl@0
   306
	RStressThread(TThreadFunction aThreadFunction, const char* aName, TInt aDelay=-1);
sl@0
   307
	~RStressThread();
sl@0
   308
	void Start();
sl@0
   309
	void Restart();
sl@0
   310
	void Stop();
sl@0
   311
	// for use by thread...
sl@0
   312
	static RStressThread& Begin(TAny* aInfo);
sl@0
   313
	TBool Loop();
sl@0
   314
private:
sl@0
   315
	TThreadFunction iThreadFunction;
sl@0
   316
	const char* iName;
sl@0
   317
	RThread iThread;
sl@0
   318
	TRequestStatus iLogon;
sl@0
   319
	TUint iCount;
sl@0
   320
	TBool iStop;
sl@0
   321
	TInt iDelay;
sl@0
   322
sl@0
   323
private:
sl@0
   324
	static TInt iInstanceCounter;
sl@0
   325
	};
sl@0
   326
sl@0
   327
sl@0
   328
TInt RStressThread::iInstanceCounter = 0;
sl@0
   329
sl@0
   330
sl@0
   331
RStressThread::RStressThread(TThreadFunction aThreadFunction, const char* aName, TInt aDelay)
sl@0
   332
	: iThreadFunction(aThreadFunction), iName(aName), iLogon(KErrNone), iDelay(aDelay)
sl@0
   333
	{
sl@0
   334
	iThread.SetHandle(0);
sl@0
   335
	}
sl@0
   336
sl@0
   337
sl@0
   338
RStressThread::~RStressThread()
sl@0
   339
	{
sl@0
   340
	Stop();
sl@0
   341
	}
sl@0
   342
sl@0
   343
sl@0
   344
void RStressThread::Start()
sl@0
   345
	{
sl@0
   346
	iStop = false;
sl@0
   347
	iCount = 0;
sl@0
   348
sl@0
   349
	TBuf<KMaxKernelName> name;
sl@0
   350
	name.Copy(TPtrC8((const TUint8*)iName));
sl@0
   351
	name.Append((TText)'-');
sl@0
   352
	name.AppendNum(iInstanceCounter++);
sl@0
   353
	test_Equal(KErrNone,iThread.Create(name,iThreadFunction,KDefaultStackSize,&User::Allocator(),this));
sl@0
   354
sl@0
   355
	iThread.Logon(iLogon);
sl@0
   356
	test_Equal(KRequestPending,iLogon.Int());
sl@0
   357
sl@0
   358
	TRequestStatus rendezvous;
sl@0
   359
	iThread.Rendezvous(rendezvous);
sl@0
   360
sl@0
   361
	iThread.Resume();
sl@0
   362
sl@0
   363
	User::WaitForRequest(rendezvous);
sl@0
   364
	test_Equal(KErrNone,rendezvous.Int());
sl@0
   365
	}
sl@0
   366
sl@0
   367
sl@0
   368
void RStressThread::Stop()
sl@0
   369
	{
sl@0
   370
	if(!iThread.Handle())
sl@0
   371
		return; // thread not running
sl@0
   372
sl@0
   373
	iStop = true;
sl@0
   374
	RDebug::Printf("RStressThread::Stop %s (count=%d)",iName,iCount);
sl@0
   375
	if(WaitForRequest(iLogon,10*1000000)!=KErrNone)
sl@0
   376
		test(0);
sl@0
   377
	CLOSE_AND_WAIT(iThread);
sl@0
   378
	}
sl@0
   379
sl@0
   380
sl@0
   381
void RStressThread::Restart()
sl@0
   382
	{
sl@0
   383
	if(iThread.Handle())
sl@0
   384
		{
sl@0
   385
		if(iLogon==KRequestPending)
sl@0
   386
			return; // thread still running
sl@0
   387
sl@0
   388
		User::WaitForRequest(iLogon);
sl@0
   389
		CLOSE_AND_WAIT(iThread);
sl@0
   390
		}
sl@0
   391
sl@0
   392
	Start();
sl@0
   393
	}
sl@0
   394
sl@0
   395
sl@0
   396
TBool RStressThread::Loop()
sl@0
   397
	{
sl@0
   398
	if(iDelay>=0)
sl@0
   399
		User::AfterHighRes(iDelay);
sl@0
   400
	++iCount;
sl@0
   401
	return !iStop;
sl@0
   402
	}
sl@0
   403
sl@0
   404
sl@0
   405
RStressThread& RStressThread::Begin(TAny* aInfo)
sl@0
   406
	{
sl@0
   407
	RStressThread& t = *(RStressThread*)aInfo;
sl@0
   408
	if(t.iDelay>=0)
sl@0
   409
		RThread().SetPriority(EPriorityMore); // so this preempts threads after delay
sl@0
   410
	RThread::Rendezvous(KErrNone);
sl@0
   411
	return t;
sl@0
   412
	}
sl@0
   413
sl@0
   414
//
sl@0
   415
//
sl@0
   416
//
sl@0
   417
sl@0
   418
sl@0
   419
RMyServer Session;
sl@0
   420
RThread ServerThread;
sl@0
   421
sl@0
   422
sl@0
   423
void NewSession()
sl@0
   424
	{
sl@0
   425
	RMyServer newSession;
sl@0
   426
	TRACE("o");
sl@0
   427
	test_Equal(KErrNone,newSession.Connect());
sl@0
   428
sl@0
   429
	RMyServer oldSession(Session);
sl@0
   430
	Session = newSession;
sl@0
   431
sl@0
   432
	TRACE("c");
sl@0
   433
	if(oldSession.Handle())
sl@0
   434
		CLOSE_AND_WAIT(oldSession);
sl@0
   435
	}
sl@0
   436
sl@0
   437
sl@0
   438
TInt SessionCloserThread(TAny* aInfo)
sl@0
   439
	{
sl@0
   440
	RStressThread& t = RStressThread::Begin(aInfo);
sl@0
   441
	do
sl@0
   442
		{
sl@0
   443
		NewSession();
sl@0
   444
		}
sl@0
   445
	while(t.Loop());
sl@0
   446
	return KErrNone;
sl@0
   447
	}
sl@0
   448
sl@0
   449
sl@0
   450
TInt ServerStopperThread(TAny* aInfo)
sl@0
   451
	{
sl@0
   452
	RStressThread& t = RStressThread::Begin(aInfo);
sl@0
   453
	do
sl@0
   454
		{
sl@0
   455
		TRACE("s");
sl@0
   456
		TRequestStatus rendezvous;
sl@0
   457
		ServerThread.Rendezvous(rendezvous);
sl@0
   458
sl@0
   459
		TRequestStatus s1 = KRequestPending;
sl@0
   460
		TRequestStatus s2;
sl@0
   461
		Session.Send(RMyServer::EStop,TIpcArgs(&s1),s2);
sl@0
   462
		User::WaitForRequest(s1,s2);
sl@0
   463
		if(s2!=KRequestPending)
sl@0
   464
			{
sl@0
   465
			test_Equal(KErrServerTerminated,s2.Int());
sl@0
   466
			User::WaitForRequest(s1);
sl@0
   467
			}
sl@0
   468
sl@0
   469
		User::WaitForRequest(rendezvous);
sl@0
   470
		NewSession();
sl@0
   471
		}
sl@0
   472
	while(t.Loop());
sl@0
   473
	return KErrNone;
sl@0
   474
	}
sl@0
   475
sl@0
   476
sl@0
   477
TInt SessionPingerThread(TAny* aInfo)
sl@0
   478
	{
sl@0
   479
	RStressThread& t = RStressThread::Begin(aInfo);
sl@0
   480
	do
sl@0
   481
		{
sl@0
   482
		TRACE("p");
sl@0
   483
		TRequestStatus s1 = KRequestPending;
sl@0
   484
		TRequestStatus s2;
sl@0
   485
		Session.Send(RMyServer::EPing,TIpcArgs(&s1),s2);
sl@0
   486
		User::WaitForRequest(s1,s2);
sl@0
   487
		if(s2.Int()==KErrNone)
sl@0
   488
			{
sl@0
   489
			// message completed OK, wait for servers extra signal
sl@0
   490
			User::WaitForRequest(s1);
sl@0
   491
			}
sl@0
   492
		else if(s2.Int()==KErrServerTerminated)
sl@0
   493
			{
sl@0
   494
			// server died before message processed, there shouldn't be an extra signal
sl@0
   495
			test_Equal(KRequestPending,s1.Int());
sl@0
   496
			}
sl@0
   497
		else
sl@0
   498
			{
sl@0
   499
			// assume message was completed by server, but we didn't get signalled because session was closed
sl@0
   500
			test_Equal(KRequestPending,s2.Int());
sl@0
   501
			test_Equal(KErrNone,s1.Int());
sl@0
   502
			}
sl@0
   503
		}
sl@0
   504
	while(t.Loop());
sl@0
   505
	return KErrNone;
sl@0
   506
	}
sl@0
   507
sl@0
   508
sl@0
   509
void TestInit()
sl@0
   510
	{
sl@0
   511
	RThread().SetPriority(EPriorityMuchMore); // so this main thread is higher priority than workers
sl@0
   512
sl@0
   513
	test_Equal(KErrNone,SyncSemaphore.CreateLocal(0,EOwnerProcess));
sl@0
   514
sl@0
   515
	// calculate async cleanup timeout value...
sl@0
   516
	TInt factor = UserSvr::HalFunction(EHalGroupVariant, EVariantHalTimeoutExpansion, 0, 0);
sl@0
   517
	if (factor<=0)
sl@0
   518
		factor = 1;
sl@0
   519
	if (factor>1024)
sl@0
   520
		factor = 1024;
sl@0
   521
	WaitABit = 200000 * (TUint32)factor;
sl@0
   522
	}
sl@0
   523
sl@0
   524
sl@0
   525
void StartServer()
sl@0
   526
	{
sl@0
   527
	// start test server...
sl@0
   528
	test_Equal(KErrNone,ServerThread.Create(_L("Server"),MyServerThread,KDefaultStackSize,1<<12,1<<20,0));
sl@0
   529
	TRequestStatus rendezvous;
sl@0
   530
	ServerThread.Rendezvous(rendezvous);
sl@0
   531
	ServerThread.Resume();
sl@0
   532
	User::WaitForRequest(rendezvous);
sl@0
   533
	test_Equal(KErrNone,rendezvous.Int());
sl@0
   534
	test_Equal(EExitPending,ServerThread.ExitType());
sl@0
   535
	}
sl@0
   536
sl@0
   537
sl@0
   538
void StopServer()
sl@0
   539
	{
sl@0
   540
	TRequestStatus logon;
sl@0
   541
	NewSession();
sl@0
   542
	TRequestStatus s1 = KRequestPending;
sl@0
   543
	TRequestStatus s2;
sl@0
   544
	ServerThread.Logon(logon);
sl@0
   545
	Session.Send(RMyServer::EShutdown,TIpcArgs(&s1),s2);
sl@0
   546
	User::WaitForRequest(s1,s2);
sl@0
   547
	if(s2!=KRequestPending)
sl@0
   548
		{
sl@0
   549
		test_Equal(KErrServerTerminated,s2.Int());
sl@0
   550
		User::WaitForRequest(s1);
sl@0
   551
		}
sl@0
   552
	CLOSE_AND_WAIT(Session);
sl@0
   553
	User::WaitForRequest(logon);
sl@0
   554
	test_KErrNone(logon.Int());
sl@0
   555
	test_Equal(EExitKill, ServerThread.ExitType());
sl@0
   556
	CLOSE_AND_WAIT(ServerThread);
sl@0
   557
	}
sl@0
   558
sl@0
   559
sl@0
   560
void TestMessageCompleteOnClosedSession()
sl@0
   561
	{
sl@0
   562
	__KHEAP_MARK;
sl@0
   563
sl@0
   564
	test.Start(_L("Start server"));
sl@0
   565
	StartServer();
sl@0
   566
sl@0
   567
	test.Next(_L("Connect"));
sl@0
   568
	test_Equal(KErrNone,Session.Connect());
sl@0
   569
sl@0
   570
	test.Next(_L("Send message"));
sl@0
   571
	TRequestStatus s1 = KRequestPending;
sl@0
   572
	TRequestStatus s2 = KRequestPending;
sl@0
   573
	TRequestStatus s3;
sl@0
   574
	Session.Send(RMyServer::ESync,TIpcArgs(&s1,&s2),s3);
sl@0
   575
	test_Equal(KRequestPending,s3.Int());
sl@0
   576
sl@0
   577
	test.Next(_L("Wait for s1"));
sl@0
   578
	test_Equal(KErrNone,WaitForRequest(s1));
sl@0
   579
	test_Equal(KErrNone,s1.Int());
sl@0
   580
	test_Equal(KRequestPending,s2.Int());
sl@0
   581
	test_Equal(KRequestPending,s3.Int());
sl@0
   582
sl@0
   583
	test.Next(_L("Close session"));
sl@0
   584
	Session.Close();
sl@0
   585
	test_Equal(KRequestPending,s2.Int());
sl@0
   586
	test_Equal(KRequestPending,s3.Int());
sl@0
   587
sl@0
   588
	test.Next(_L("Trigger message completion"));
sl@0
   589
	SyncSemaphore.Signal();
sl@0
   590
sl@0
   591
	test.Next(_L("Wait for s2"));
sl@0
   592
	test_Equal(KErrNone,WaitForRequest(s2));
sl@0
   593
	test_Equal(KErrNone,s2.Int());
sl@0
   594
	test_Equal(KRequestPending,s3.Int());
sl@0
   595
sl@0
   596
	test.Next(_L("Stop server"));
sl@0
   597
	StopServer();
sl@0
   598
sl@0
   599
	test.End();
sl@0
   600
sl@0
   601
	User::After(WaitABit);	// allow asynchronous cleanup to happen
sl@0
   602
sl@0
   603
	__KHEAP_MARKEND;
sl@0
   604
	}
sl@0
   605
sl@0
   606
sl@0
   607
void TestMessageCompleteWhileCopying()
sl@0
   608
	{
sl@0
   609
	__KHEAP_MARK;
sl@0
   610
sl@0
   611
	test.Start(_L("Start server"));
sl@0
   612
	StartServer();
sl@0
   613
sl@0
   614
	test.Next(_L("Connect"));
sl@0
   615
	test_Equal(KErrNone,Session.Connect());
sl@0
   616
sl@0
   617
	test.Next(_L("Create large descriptor"));
sl@0
   618
	HBufC* bigdes = HBufC::NewMax(BigDesLength);
sl@0
   619
	test_NotNull(bigdes);
sl@0
   620
	TPtr ptr = bigdes->Des();
sl@0
   621
sl@0
   622
	test.Next(_L("Send message"));
sl@0
   623
	TRequestStatus s1 = KRequestPending;
sl@0
   624
	TRequestStatus s2 = KRequestPending;
sl@0
   625
	TRequestStatus s3;
sl@0
   626
	Session.Send(RMyServer::ECompleteWhileCopying,TIpcArgs(&s1,&s2,&ptr),s3);
sl@0
   627
sl@0
   628
	test.Next(_L("Wait for s3"));
sl@0
   629
	test_Equal(KErrNone,WaitForRequest(s3,10*1000000));
sl@0
   630
	test_Equal(KErrNone,s3.Int());
sl@0
   631
sl@0
   632
	test.Next(_L("Wait for s2"));
sl@0
   633
	test_Equal(KErrNone,WaitForRequest(s2,10*1000000));
sl@0
   634
	test_Equal(KErrNone,s2.Int());
sl@0
   635
sl@0
   636
	test.Next(_L("Wait for s1"));
sl@0
   637
	test_Equal(KErrNone,WaitForRequest(s1,10*1000000));
sl@0
   638
	test_Equal(KErrNone,s1.Int());
sl@0
   639
sl@0
   640
	test.Next(_L("Close session"));
sl@0
   641
	Session.Close();
sl@0
   642
sl@0
   643
	test.Next(_L("Stop server"));
sl@0
   644
	StopServer();
sl@0
   645
sl@0
   646
	test.End();
sl@0
   647
sl@0
   648
	User::After(WaitABit);	// allow asynchronous cleanup to happen
sl@0
   649
sl@0
   650
	__KHEAP_MARKEND;
sl@0
   651
	}
sl@0
   652
sl@0
   653
sl@0
   654
void RunStressThreads(RStressThread& aThread1, RStressThread& aThread2, TInt aTimeout=1000000)
sl@0
   655
	{
sl@0
   656
	__KHEAP_MARK;
sl@0
   657
sl@0
   658
	StartServer();
sl@0
   659
sl@0
   660
	NewSession();
sl@0
   661
sl@0
   662
	aThread1.Start();
sl@0
   663
	aThread2.Start();
sl@0
   664
sl@0
   665
	RTimer timer;
sl@0
   666
	test_Equal(KErrNone,timer.CreateLocal());
sl@0
   667
	TRequestStatus timeoutStatus;
sl@0
   668
	timer.After(timeoutStatus,aTimeout);
sl@0
   669
	do
sl@0
   670
		{
sl@0
   671
		aThread1.Restart();
sl@0
   672
		aThread2.Restart();
sl@0
   673
		WaitForRequest();
sl@0
   674
		}
sl@0
   675
	while(timeoutStatus==KRequestPending);
sl@0
   676
	User::WaitForRequest(timeoutStatus);
sl@0
   677
	CLOSE_AND_WAIT(timer);
sl@0
   678
sl@0
   679
	aThread2.Stop();
sl@0
   680
	aThread1.Stop();
sl@0
   681
sl@0
   682
	CLOSE_AND_WAIT(Session);
sl@0
   683
	StopServer();
sl@0
   684
sl@0
   685
	User::After(WaitABit);	// allow asynchronous cleanup to happen
sl@0
   686
	__KHEAP_MARKEND;
sl@0
   687
	}
sl@0
   688
sl@0
   689
sl@0
   690
GLDEF_C TInt E32Main()
sl@0
   691
	{
sl@0
   692
	TInt i;
sl@0
   693
sl@0
   694
	test.Title();
sl@0
   695
sl@0
   696
	test.Start(_L("Initialise"));
sl@0
   697
	TestInit();
sl@0
   698
sl@0
   699
	for(UseGlobalMessagePool=0; UseGlobalMessagePool<2; ++UseGlobalMessagePool)
sl@0
   700
		{
sl@0
   701
		if(UseGlobalMessagePool)
sl@0
   702
			test.Next(_L("Tests using global message pool"));
sl@0
   703
		else
sl@0
   704
			test.Next(_L("Tests using local message pool"));
sl@0
   705
sl@0
   706
		NumMessageSlots = 1;
sl@0
   707
sl@0
   708
		test.Start(_L("Check completing messages on dead session"));
sl@0
   709
		TestMessageCompleteOnClosedSession();
sl@0
   710
sl@0
   711
		for (i=0; i<10; i++)
sl@0
   712
			{
sl@0
   713
			test.Next(_L("Check completing message while IPC copying"));
sl@0
   714
			TestMessageCompleteWhileCopying();
sl@0
   715
			}
sl@0
   716
sl@0
   717
		test.Next(_L("Stress closing session whilst in use"));
sl@0
   718
		RStressThread closer(SessionCloserThread,"SessionCloser",0);
sl@0
   719
		RStressThread pinger1(SessionPingerThread,"Pinger");
sl@0
   720
		RunStressThreads(closer, pinger1);
sl@0
   721
sl@0
   722
		NumMessageSlots = 2;
sl@0
   723
sl@0
   724
		test.Next(_L("Stress stopping server whilst in use"));
sl@0
   725
		RStressThread stopper(ServerStopperThread,"ServerStopper",0);
sl@0
   726
		RStressThread pinger2(SessionPingerThread,"Pinger");
sl@0
   727
		RunStressThreads(stopper, pinger2);
sl@0
   728
sl@0
   729
		test.End();
sl@0
   730
		}
sl@0
   731
sl@0
   732
	test.End();
sl@0
   733
	return(0);
sl@0
   734
	}
sl@0
   735