--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/bench/t_svr2.cpp Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,367 @@
+// Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// e32test\bench\t_svr2.cpp
+// Overview:
+// Tests the Client/Server architecture of the Symbian platform.
+// Tests that messages are completed when a server terminates.
+// API Information:
+// CSession2, CServer2, RSessionBase.
+// Details:
+// - Create and start a server thread. Verify results are as expected.
+// - Create and close client sessions to enforce granularity expansion.
+// - Open and close a session and verify that the heap is OK.
+// - Open a connection specifying 0 message slots for the session and verify
+// that the server returns KErrNone.
+// - Create lot of timers to eliminate kernel granularities.
+// - Create a client session and validate kernel heap is ok if client is killed.
+// - Create a client session and validate kernel heap is ok if server is killed
+// when client has outstanding request to server.
+// Platforms/Drives/Compatibility:
+// All
+// Assumptions/Requirement/Pre-requisites:
+// Failures and causes:
+// Base Port information:
+//
+//
+
+#include <e32base.h>
+#include <e32base_private.h>
+#include <e32test.h>
+#include <e32def.h>
+#include <e32def_private.h>
+
+const TInt KHeapSize=0x4000;
+const TInt KMajorVersionNumber=1;
+const TInt KMinorVersionNumber=0;
+const TInt KBuildVersionNumber=1;
+
+_LIT(KServerName,"MyServer");
+
+class CMySession : public CSession2
+ {
+public:
+ enum {ETest, ENeverComplete};
+public:
+ CMySession();
+ virtual void ServiceL(const RMessage2& aMessage);//Overloading pure virtual
+ };
+
+class CMyServer : public CServer2
+ {
+public:
+ CMyServer(TInt aPriority);
+ static CMyServer *New(TInt aPriority);
+ virtual CSession2* NewSessionL(const TVersion& aVersion,const RMessage2& aMessage) const ;
+};
+
+class CMyActiveScheduler : public CActiveScheduler
+ {
+public:
+ virtual void Error(TInt anError) const; //Overloading pure virtual
+ };
+
+
+class RMySessionBase : public RSessionBase
+ {
+public:
+ TInt Open();
+ TInt Test();
+ TInt NeverComplete();
+ TVersion Version();
+ };
+
+_LIT(KSvrSemName, "svrSem");
+_LIT(KSvrSem2Name, "svrSem2");
+_LIT(KClientSemName, "clientSem");
+
+CMySession::CMySession()
+ {}
+
+void CMySession::ServiceL(const RMessage2& aMessage)
+//
+// Handle messages for this server.
+//
+ {
+ RSemaphore svrSem;
+
+ //CMySession &c=(CMySession &)aClient;// passed as CSession2 since fn overloads pure virtual fn
+ TInt r=KErrNone;
+ switch (aMessage.Function())
+ {
+ case ETest:
+ break;
+ case ENeverComplete:
+ r = svrSem.OpenGlobal(KSvrSemName);
+ if (r != KErrNone)
+ break;
+ svrSem.Signal(); // all ready for the server to be killed
+ svrSem.Close();
+ return;
+ default:
+ r=KErrNotSupported;
+ }
+ aMessage.Complete(r);
+ }
+
+CMyServer* CMyServer::New(TInt aPriority)
+//
+// Create a new CMyServer.
+//
+ {
+
+ return new CMyServer(aPriority);
+ }
+
+CMyServer::CMyServer(TInt aPriority)
+//
+// Constructor.
+//
+ : CServer2(aPriority)
+ {}
+
+CSession2* CMyServer::NewSessionL(const TVersion&, const RMessage2&) const
+//
+// Create a new client for this server.
+//
+ {
+ return new(ELeave) CMySession();
+ }
+
+void CMyActiveScheduler::Error(TInt anError) const
+//
+// Called if any Run() method leaves.
+//
+ {
+ RTest testSvr(_L("Server"));
+ testSvr.Panic(anError,_L("CMyActiveScheduler::Error"));
+ }
+
+
+TInt RMySessionBase::Open()
+//
+// Open the server.
+//
+ {
+ return CreateSession(KServerName,Version(),0);
+ }
+
+TInt RMySessionBase::Test()
+//
+// Send a message and wait for completion.
+//
+ {
+ return SendReceive(CMySession::ETest, TIpcArgs());
+ }
+
+TInt RMySessionBase::NeverComplete()
+//
+// Send a message and wait for completion.
+//
+ {
+ return SendReceive(CMySession::ENeverComplete, TIpcArgs());
+ }
+
+TVersion RMySessionBase::Version()
+//
+// Return the current version.
+//
+ {
+ TVersion v(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
+ return v;
+ }
+
+LOCAL_C TInt serverThreadEntryPoint(TAny*)
+//
+// The entry point for the server thread.
+//
+ {
+ CMyActiveScheduler *pR = new CMyActiveScheduler;
+ if (pR == NULL)
+ return KErrNoMemory;
+ CActiveScheduler::Install(pR);
+
+ CMyServer* pS = CMyServer::New(0);
+ if (pS == NULL)
+ return KErrNoMemory;
+ TInt r = pS->Start(KServerName);
+ if (r != KErrNone)
+ return r;
+
+ RSemaphore svrSem2;
+ r = svrSem2.OpenGlobal(KSvrSem2Name);
+ if (r != KErrNone)
+ return r;
+ svrSem2.Signal();
+ svrSem2.Close();
+ CActiveScheduler::Start();
+ return KErrNone;
+ }
+
+
+LOCAL_C TInt clientThreadEntryPoint(TAny *param)
+//
+// The entry point for the client thread.
+//
+ {
+ RSemaphore svrSem2;
+ RSemaphore clientSem;
+ TInt r = clientSem.OpenGlobal(KClientSemName);
+ if (r != KErrNone)
+ return r;
+ RMySessionBase t;
+ RMySessionBase t2;
+// RTimer rt[40];
+// TUint c;
+
+ switch ((TUint32)param)
+ {
+ case 1:
+ r=t.Open();
+ if (r != KErrNone)
+ break;
+ clientSem.Signal();
+ clientSem.Close();
+ FOREVER
+ ;
+ case 2:
+ // Now create a lot of timers to eliminate kernel granularities
+/* for (c=0;c<40;c++)
+ {
+ TInt r=rt[c].CreateLocal();
+ test(r==KErrNone);
+ }
+ for (c=0;c<39;c++)
+ rt[c].Close();
+*/
+ r=svrSem2.OpenGlobal(KSvrSem2Name);
+ if (r != KErrNone)
+ break;
+ clientSem.Signal();
+ svrSem2.Wait();
+ svrSem2.Close();
+ User::After(2000000);
+ r=t2.Open();
+ if (r != KErrNone)
+ break;
+ r=t2.NeverComplete(); // r should be KErrServerTerminated
+ if (r != KErrServerTerminated)
+ break;
+ t2.Close();
+ clientSem.Signal();
+ clientSem.Close();
+ FOREVER
+ ;
+ default:
+ break;
+ }
+ return r;
+ }
+
+GLDEF_C TInt E32Main()
+//
+// Test server & session cleanup.
+//
+ {
+ RSemaphore svrSem;
+ RSemaphore svrSem2;
+ RSemaphore clientSem;
+ RTest test(_L("T_SVR2"));
+ test.Title();
+
+ __KHEAP_MARK;
+
+ test.Start(_L("Creating server semaphore"));
+ TInt r=svrSem.CreateGlobal(KSvrSemName, 0);
+ test(r==KErrNone);
+ test.Next(_L("Creating server semaphore 2"));
+ r=svrSem2.CreateGlobal(KSvrSem2Name, 0);
+ test(r==KErrNone);
+ test.Next(_L("Creating client semaphore"));
+ r=clientSem.CreateGlobal(KClientSemName, 0);
+ test(r==KErrNone);
+
+ test.Next(_L("Creating server"));
+ RThread server;
+ r=server.Create(_L("MyServer"),serverThreadEntryPoint,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)1);
+ test(r==KErrNone);
+ server.Resume();
+ svrSem2.Wait(); // server up & running
+
+ test.Next(_L("Forcing granularity expansion"));
+ const TInt KNumberOfSessions=10;
+ TInt i;
+ RMySessionBase ts[KNumberOfSessions];
+ for (i=0; i<KNumberOfSessions; i++)
+ ts[i].Open();
+ for (i=0; i<KNumberOfSessions; i++)
+ ts[i].Close();
+
+ test.Next(_L("Opening a session and closing it"));
+ RMySessionBase t;
+ r=t.Open();
+ test(r==KErrNone);
+ t.Close();
+ RThread clientx;
+ r=clientx.Create(_L("MyClientx"),clientThreadEntryPoint,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)1);
+ test(r==KErrNone);
+ clientx.Resume();
+ clientSem.Wait(); // client connected
+
+ test.Next(_L("Creating client & killing it"));
+
+ RThread client;
+ r=client.Create(_L("MyClient"),clientThreadEntryPoint,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)1);
+ test(r==KErrNone);
+ client.Resume();
+ clientSem.Wait(); // client connected
+ User::After(1000000);
+ client.Kill(666); // kill the client
+
+ clientx.Kill(666); // kill the client
+ CLOSE_AND_WAIT(clientx);
+ CLOSE_AND_WAIT(client);
+
+ test.Next(_L("Creating client and killing server"));
+ server.Kill(0); // first kill the existing server
+ CLOSE_AND_WAIT(server);
+ RThread client2; // and create the client so the heap is in a good state for the mark
+ r=client2.Create(_L("MyClient"),clientThreadEntryPoint,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)2);
+ test(r==KErrNone);
+ client2.Resume();
+ clientSem.Wait(); // client running but not connected
+
+ RThread server2;
+ r=server2.Create(_L("MyServer"),serverThreadEntryPoint,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)2);
+ test(r==KErrNone);
+ server2.Resume();
+ svrSem.Wait(); // client has request outstanding to server
+ server2.Kill(666); // kill the server
+ clientSem.Wait(); // client's request has completed & client has closed session
+ User::After(1000000);
+ client2.Kill(666);
+ CLOSE_AND_WAIT(client2);
+ CLOSE_AND_WAIT(server2);
+
+ svrSem.Close();
+ svrSem2.Close();
+ clientSem.Close();
+
+ __KHEAP_MARKEND; // and check the kernel's heap is OK
+
+ test.End();
+ return(KErrNone);
+ }
+
+
+