sl@0: // Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // t_shbuf_perfserver.cpp sl@0: // sl@0: // sl@0: sl@0: /** sl@0: * @file sl@0: * sl@0: * Test server used for Performance Testing of shared buffers. sl@0: */ sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: #include "t_shbuf_perfserver.h" sl@0: sl@0: sl@0: /** sl@0: * Second phase constructor for sessions. Called by the CServer2 framework sl@0: * when a session is created (e.g. a connection is made to the server). sl@0: */ sl@0: void CShBufTestServerSession::CreateL() sl@0: { sl@0: Server().AddSessionL(this); sl@0: } // CShBufTestServerSession::CreateL() sl@0: sl@0: sl@0: /** sl@0: * Destructor for session classes. When this is called it indicates that sl@0: * a session is closing its connection with the server. sl@0: */ sl@0: CShBufTestServerSession::~CShBufTestServerSession() sl@0: { sl@0: Server().DropSession(this); sl@0: } // CShBufTestServerSession::~CShBufTestServerSession() sl@0: sl@0: sl@0: /** sl@0: * Handle message requests for this session. Leaving is handled by sl@0: * CShBufTestServer::RunError() which reports the error code to the client. sl@0: * sl@0: * @param aMessage RMessage2 reference which encapsulates a client request. sl@0: */ sl@0: void CShBufTestServerSession::ServiceL(const RMessage2& aMessage) sl@0: sl@0: { sl@0: switch (aMessage.Function()) sl@0: { sl@0: case EShBufServerShutdownServer: sl@0: { sl@0: ShutdownServerL(aMessage); sl@0: } sl@0: break; sl@0: sl@0: case EShBufServerFromTPtr8ProcessAndReturn: sl@0: { sl@0: FromTPtr8ProcessAndReturnL(aMessage); sl@0: } sl@0: break; sl@0: sl@0: case EShBufServerFromTPtr8ProcessAndRelease: sl@0: { sl@0: FromTPtr8ProcessAndReleaseL(aMessage); sl@0: } sl@0: break; sl@0: sl@0: case EShBufServerOpenRShBufPool: sl@0: { sl@0: OpenRShBufPoolL(aMessage); sl@0: } sl@0: break; sl@0: sl@0: case EShBufServerCloseRShBufPool: sl@0: { sl@0: CloseRShBufPoolL(aMessage); sl@0: } sl@0: break; sl@0: sl@0: case EShBufServerFromRShBufProcessAndReturn: sl@0: { sl@0: FromRShBufProcessAndReturnL(aMessage); sl@0: } sl@0: break; sl@0: sl@0: case EShBufServerFromRShBufProcessAndRelease: sl@0: { sl@0: FromRShBufProcessAndReleaseL(aMessage); sl@0: } sl@0: break; sl@0: sl@0: case EShBufServerDbgMarkHeap: sl@0: { sl@0: DbgMarkHeapL(aMessage); sl@0: } sl@0: break; sl@0: sl@0: case EShBufServerDbgCheckHeap: sl@0: { sl@0: DbgCheckHeapL(aMessage); sl@0: } sl@0: break; sl@0: sl@0: case EShBufServerDbgMarkEnd: sl@0: { sl@0: DbgMarkEndL(aMessage); sl@0: } sl@0: break; sl@0: sl@0: case EShBufServerDbgFailNext: sl@0: { sl@0: DbgFailNextL(aMessage); sl@0: } sl@0: break; sl@0: sl@0: default: sl@0: { sl@0: aMessage.Panic(KRShBufTestServerName, 999); sl@0: } sl@0: break; sl@0: } sl@0: } // CShBufTestServerSession::ServiceL() sl@0: sl@0: sl@0: /** sl@0: * Completes a client request. This function provides a single point of sl@0: * message completion which benefits debugging and maintenance. sl@0: * sl@0: * @param aMessage The RMessage2 client request. sl@0: * @param aResult Result of the request. sl@0: */ sl@0: void CShBufTestServerSession::CompleteRequest(const RMessage2& aMessage, sl@0: TInt aResult) const sl@0: { sl@0: if (aMessage.IsNull() == EFalse) sl@0: { sl@0: aMessage.Complete(aResult); sl@0: } sl@0: } // CShBufTestServerSession::CompleteRequest() sl@0: sl@0: sl@0: /** sl@0: * Takes a buffer from the client, sends to the driver and back to the client. sl@0: * sl@0: * @param aMessage RMessage2 client request. sl@0: */ sl@0: void CShBufTestServerSession::FromTPtr8ProcessAndReturnL(const RMessage2& aMessage) sl@0: { sl@0: // sl@0: // Read the client buffer... sl@0: // sl@0: TPtr8 bufPtr(iSessionTempBuffer, sizeof(iSessionTempBuffer)); sl@0: sl@0: aMessage.ReadL(0, bufPtr); sl@0: sl@0: TUint bufSize; sl@0: sl@0: bufSize = aMessage.Int1(); sl@0: sl@0: // sl@0: // Pass to the server to pass to the driver and back... sl@0: // sl@0: TInt result; sl@0: sl@0: result = Server().FromTPtr8ProcessAndReturn(bufPtr, bufSize); sl@0: sl@0: // sl@0: // Write the client buffer back... sl@0: // sl@0: aMessage.WriteL(0, bufPtr); sl@0: sl@0: // sl@0: // Complete the request... sl@0: // sl@0: CompleteRequest(aMessage, result); sl@0: } // CShBufTestServerSession::FromTPtr8ProcessAndReturnL sl@0: sl@0: sl@0: /** sl@0: * Takes a buffer from the client and sends to the driver. sl@0: * sl@0: * @param aMessage RMessage2 client request. sl@0: */ sl@0: void CShBufTestServerSession::FromTPtr8ProcessAndReleaseL(const RMessage2& aMessage) sl@0: { sl@0: // sl@0: // Read the client buffer... sl@0: // sl@0: TPtr8 bufPtr(iSessionTempBuffer, sizeof(iSessionTempBuffer)); sl@0: sl@0: aMessage.ReadL(0, bufPtr); sl@0: sl@0: // sl@0: // Pass to the server to pass to the driver and back... sl@0: // sl@0: TInt result; sl@0: sl@0: result = Server().FromTPtr8ProcessAndRelease(bufPtr); sl@0: sl@0: // sl@0: // Complete the request... sl@0: // sl@0: CompleteRequest(aMessage, result); sl@0: } // CShBufTestServerSession::FromTPtr8ProcessAndReleaseL sl@0: sl@0: sl@0: /** sl@0: * Allows the client to ask the test server to open a buffer pool. sl@0: * sl@0: * @param aMessage RMessage2 client request. sl@0: */ sl@0: void CShBufTestServerSession::OpenRShBufPoolL(const RMessage2& aMessage) sl@0: { sl@0: // sl@0: // Read the handle... sl@0: // sl@0: TInt poolHandle = aMessage.Int0(); sl@0: sl@0: // sl@0: // Read the pool info... sl@0: // sl@0: TShPoolInfo shPoolInfo; sl@0: TPckg shPoolInfoPckg(shPoolInfo); sl@0: sl@0: aMessage.ReadL(1, shPoolInfoPckg); sl@0: sl@0: // sl@0: // Pass to the server to open the pool... sl@0: // sl@0: TInt result = Server().OpenRShBufPool(poolHandle, shPoolInfo); sl@0: sl@0: // sl@0: // Complete the request... sl@0: // sl@0: CompleteRequest(aMessage, result); sl@0: } // CShBufTestServerSession::OpenRShBufPoolL sl@0: sl@0: sl@0: /** sl@0: * Allows the client to ask the test server to close a buffer pool. sl@0: * sl@0: * @param aMessage RMessage2 client request. sl@0: */ sl@0: void CShBufTestServerSession::CloseRShBufPoolL(const RMessage2& aMessage) sl@0: { sl@0: // sl@0: // Pass to the server to close the pool... sl@0: // sl@0: TInt result = Server().CloseRShBufPool(); sl@0: sl@0: // sl@0: // Complete the request... sl@0: // sl@0: CompleteRequest(aMessage, result); sl@0: } // CShBufTestServerSession::CloseRShBufPoolL sl@0: sl@0: sl@0: /** sl@0: * Takes a buffer from the client, sends to the driver and back to the client. sl@0: * sl@0: * @param aMessage RMessage2 client request. sl@0: */ sl@0: void CShBufTestServerSession::FromRShBufProcessAndReturnL(const RMessage2& aMessage) sl@0: { sl@0: // sl@0: // Read the client handle buffer... sl@0: // sl@0: RShBuf shBuf; sl@0: TUint bufSize; sl@0: sl@0: bufSize = aMessage.Int1(); sl@0: sl@0: // sl@0: // Pass to the server to pass to the driver and back... sl@0: // sl@0: TInt result; sl@0: sl@0: result = Server().FromRShBufProcessAndReturn(shBuf, bufSize); sl@0: sl@0: // sl@0: // Write the client buffer handle back... sl@0: // sl@0: #ifdef CAN_TRANSFER_SHBUF_TO_ANOTHER_PROCESS sl@0: // TDBD aMessage.Complete(shbuf->Handle()); sl@0: #else sl@0: TPckg handlePckg(shBuf.Handle()); sl@0: aMessage.WriteL(0, handlePckg); sl@0: #endif sl@0: sl@0: // sl@0: // Complete the request... sl@0: // sl@0: CompleteRequest(aMessage, result); sl@0: } // CShBufTestServerSession::FromRShBufProcessAndReturnL sl@0: sl@0: sl@0: /** sl@0: * Takes a buffer from the client and sends to the driver. sl@0: * sl@0: * @param aMessage RMessage2 client request. sl@0: */ sl@0: void CShBufTestServerSession::FromRShBufProcessAndReleaseL(const RMessage2& aMessage) sl@0: { sl@0: // sl@0: // Read the client buffer handle... sl@0: // sl@0: sl@0: RShBuf shBuf; sl@0: sl@0: #ifdef CAN_TRANSFER_SHBUF_TO_ANOTHER_PROCESS sl@0: // TBD RShBuf.Open(aMessage, 0); sl@0: #else sl@0: shBuf.SetReturnedHandle(aMessage.Int0()); sl@0: #endif sl@0: sl@0: // sl@0: // Pass to the server to pass to the driver and back... sl@0: // sl@0: TInt result; sl@0: sl@0: result = Server().FromRShBufProcessAndRelease(shBuf); sl@0: sl@0: // sl@0: // Complete the request... sl@0: // sl@0: CompleteRequest(aMessage, result); sl@0: } // CShBufTestServerSession::FromRShBufProcessAndReleaseL sl@0: sl@0: sl@0: /** sl@0: * Requests the server to mark the start of checking the server's heap. sl@0: * This function only works in debug releases and is a synchronous request sl@0: * which will be completed when the procedure returns. sl@0: * sl@0: * @param aMessage RMessage2 client request. sl@0: */ sl@0: void CShBufTestServerSession::DbgMarkHeapL(const RMessage2& aMessage) sl@0: { sl@0: TInt result; sl@0: sl@0: result = Server().DbgMarkHeap(); sl@0: sl@0: // sl@0: // Complete the request... sl@0: // sl@0: CompleteRequest(aMessage, result); sl@0: } // CShBufTestServerSession::DbgMarkHeapL() sl@0: sl@0: sl@0: /** sl@0: * Requests the server to check that the number of allocated cells at the sl@0: * current nested level on the server's heap is the same as the specified value. sl@0: * This function only works for debug builds and is a synchronous request sl@0: * which will be completed when the procedure returns. sl@0: * sl@0: * @param aMessage RMessage2 client request. sl@0: */ sl@0: void CShBufTestServerSession::DbgCheckHeapL(const RMessage2& aMessage) sl@0: { sl@0: TInt count = aMessage.Int0(); sl@0: TInt result; sl@0: sl@0: result = Server().DbgCheckHeap(count); sl@0: sl@0: // sl@0: // Complete the request... sl@0: // sl@0: CompleteRequest(aMessage, result); sl@0: } // CShBufTestServerSession::DbgCheckHeapL() sl@0: sl@0: sl@0: /** sl@0: * Requests the server to mark the end of checking the server's heap. This sl@0: * function must match an earlier call to DbgMarkHeap() and only functions sl@0: * on debug releases. This is a synchronous request which will be completed sl@0: * when the procedure returns. sl@0: * sl@0: * @param aMessage RMessage2 client request. sl@0: */ sl@0: void CShBufTestServerSession::DbgMarkEndL(const RMessage2& aMessage) sl@0: { sl@0: TInt count = aMessage.Int0(); sl@0: TInt result; sl@0: sl@0: result = Server().DbgMarkEnd(count); sl@0: sl@0: // sl@0: // Complete the request... sl@0: // sl@0: CompleteRequest(aMessage, result); sl@0: } // CShBufTestServerSession::DbgMarkEndL() sl@0: sl@0: sl@0: /** sl@0: * Simulates heap allocation failure for the sever. The failure occurs on sl@0: * the next call to new or any of the functions which allocate memory from sl@0: * the heap. This is defined only for debug builds and is a synchronous sl@0: * request which will be completed when the procedure returns. sl@0: * sl@0: * @param aMessage RMessage2 client request. sl@0: */ sl@0: void CShBufTestServerSession::DbgFailNextL(const RMessage2& aMessage) sl@0: { sl@0: TInt count = aMessage.Int0(); sl@0: TInt result; sl@0: sl@0: result = Server().DbgFailNext(count); sl@0: sl@0: // sl@0: // Complete the request... sl@0: // sl@0: CompleteRequest(aMessage, result); sl@0: } // CShBufTestServerSession::DbgFailNextL() sl@0: sl@0: sl@0: /** sl@0: * Requests the server to shut down when it no longer has any connected sl@0: * sessions. This procedure is only premitted in debug builds for security sl@0: * reasons (e.g. to prevent a denial of service attack) and is provided sl@0: * for testing purposes. This is a synchronous request which will be sl@0: * completed when the procedure returns. The server will shutdown when the sl@0: * last session disconnects. sl@0: * sl@0: * @param aMessage RMessage2 client request. sl@0: */ sl@0: void CShBufTestServerSession::ShutdownServerL(const RMessage2& aMessage) sl@0: { sl@0: TInt result = Server().ShutdownServer(); sl@0: sl@0: // sl@0: // Complete the request... sl@0: // sl@0: CompleteRequest(aMessage, result); sl@0: } // CShBufTestServerSession::ShutdownServerL() sl@0: sl@0: sl@0: /** sl@0: * Static factory method used to create a CShBufTestServer object. sl@0: * sl@0: * @return Pointer to the created CShBufTestServer object, or NULL. sl@0: */ sl@0: CShBufTestServer* CShBufTestServer::NewL() sl@0: { sl@0: CShBufTestServer* self = new (ELeave) CShBufTestServer(); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(); sl@0: CleanupStack::Pop(self); sl@0: sl@0: return self; sl@0: } // CShBufTestServer::NewL sl@0: sl@0: sl@0: /** sl@0: * Standard constructor. sl@0: */ sl@0: CShBufTestServer::CShBufTestServer() sl@0: : CServer2(EPriorityNormal), sl@0: iShouldShutdownServer(EFalse) sl@0: { sl@0: __DECLARE_NAME(_L("CShBufTestServer")); sl@0: } // CShBufTestServer::CShBufTestServer sl@0: sl@0: sl@0: /** sl@0: * Second phase constructor. Ensures the server is created and ready to run. sl@0: */ sl@0: void CShBufTestServer::ConstructL() sl@0: { sl@0: // sl@0: // Open the driver... sl@0: // sl@0: TInt ret; sl@0: sl@0: ret = User::LoadLogicalDevice(_L("D_SHBUF_CLIENT.LDD")); sl@0: if (ret != KErrAlreadyExists) sl@0: { sl@0: User::LeaveIfError(ret); sl@0: } sl@0: sl@0: ret = User::LoadLogicalDevice(_L("D_SHBUF_OWN.LDD")); sl@0: if (ret != KErrAlreadyExists) sl@0: { sl@0: User::LeaveIfError(ret); sl@0: } sl@0: sl@0: User::LeaveIfError(iShBufLdd.Open(RShBufTestChannel::EClientThread)); sl@0: sl@0: StartL(KRShBufTestServerName); sl@0: } // CShBufTestServer::ConstructL sl@0: sl@0: sl@0: /** sl@0: * Destructor. sl@0: */ sl@0: CShBufTestServer::~CShBufTestServer() sl@0: { sl@0: iSessionArray.Reset(); sl@0: iShBufLdd.Close(); sl@0: } // CShBufTestServer::~CShBufTestServer sl@0: sl@0: sl@0: /** sl@0: * Create a new client session. sl@0: */ sl@0: CSession2* CShBufTestServer::NewSessionL(const TVersion&, const RMessage2& /*aMessage*/) const sl@0: { sl@0: return new(ELeave) CShBufTestServerSession(); sl@0: } // CShBufTestServer::NewSessionL sl@0: sl@0: sl@0: /** sl@0: * Called by the session class when it is being created. sl@0: * sl@0: * @param aSession Server side session. sl@0: */ sl@0: void CShBufTestServer::AddSessionL(CShBufTestServerSession* aSession) sl@0: { sl@0: // sl@0: // Store this session in the list of sessions... sl@0: // sl@0: iSessionArray.Append(aSession); sl@0: } // CShBufTestServer::AddSessionL sl@0: sl@0: sl@0: /** sl@0: * Called by the session class when it is being destroyed. sl@0: * sl@0: * @param aSession Server side session. sl@0: */ sl@0: void CShBufTestServer::DropSession(CShBufTestServerSession* aSession) sl@0: { sl@0: // sl@0: // Remove this session from the session array list... sl@0: // sl@0: TInt position; sl@0: sl@0: position = iSessionArray.Find(aSession); sl@0: if (position != KErrNotFound) sl@0: { sl@0: iSessionArray.Remove(position); sl@0: } sl@0: sl@0: // sl@0: // If we are shuting down then unconfigure and stop... sl@0: // sl@0: if (iSessionArray.Count() == 0 && iShouldShutdownServer) sl@0: { sl@0: CActiveScheduler::Stop(); sl@0: } sl@0: } // CShBufTestServer::DropSession sl@0: sl@0: sl@0: TInt CShBufTestServer::FromTPtr8ProcessAndReturn(TDes8& aBuf, TUint aBufSize) sl@0: { sl@0: // clear cache sl@0: memset(iClearCache, 0xFF, sizeof(iClearCache)); sl@0: sl@0: return iShBufLdd.FromTPtr8ProcessAndReturn(aBuf, aBufSize); sl@0: } // CShBufTestServer::FromTPtr8ProcessAndReturn sl@0: sl@0: sl@0: TInt CShBufTestServer::FromTPtr8ProcessAndRelease(TDes8& aBuf) sl@0: { sl@0: return iShBufLdd.FromTPtr8ProcessAndRelease(aBuf); sl@0: } // CShBufTestServer::FromTPtr8ProcessAndRelease sl@0: sl@0: sl@0: TInt CShBufTestServer::OpenRShBufPool(TInt aHandle, const TShPoolInfo& aPoolInfo) sl@0: { sl@0: return iShBufLdd.OpenUserPool(aHandle, aPoolInfo); sl@0: } // CShBufTestServer::OpenRShBufPool sl@0: sl@0: sl@0: TInt CShBufTestServer::CloseRShBufPool() sl@0: { sl@0: return iShBufLdd.CloseUserPool(); sl@0: } // CShBufTestServer::CloseRShBufPool sl@0: sl@0: sl@0: TInt CShBufTestServer::FromRShBufProcessAndReturn(RShBuf& aShBuf, TUint aBufSize) sl@0: { sl@0: TInt ret; sl@0: sl@0: // clear cache sl@0: memset(iClearCache, 0xFF, sizeof(iClearCache)); sl@0: sl@0: ret = iShBufLdd.FromRShBufProcessAndReturn(aBufSize); sl@0: sl@0: if (ret > 0) sl@0: { sl@0: aShBuf.SetReturnedHandle(ret); sl@0: return KErrNone; sl@0: } sl@0: sl@0: return ret; sl@0: } // CShBufTestServer::FromRShBufProcessAndReturn sl@0: sl@0: sl@0: TInt CShBufTestServer::FromRShBufProcessAndRelease(RShBuf& aShBuf) sl@0: { sl@0: return iShBufLdd.FromRShBufProcessAndRelease(aShBuf.Handle()); sl@0: } // CShBufTestServer::FromRShBufProcessAndRelease sl@0: sl@0: sl@0: /** sl@0: * Marks the start of checking the server's heap. This function only works sl@0: * in debug releases. sl@0: * sl@0: * Calls to this function can be nested but each call must be matched by sl@0: * corresponding DbgMarkEnd(). sl@0: * sl@0: * @return KErrNone. sl@0: */ sl@0: TInt CShBufTestServer::DbgMarkHeap() const sl@0: { sl@0: #ifdef _DEBUG sl@0: __UHEAP_MARK; sl@0: #endif sl@0: sl@0: return(KErrNone); sl@0: } // CShBufTestServer::DbgMarkHeap sl@0: sl@0: sl@0: /** sl@0: * Checks that the number of allocated cells at the current nested level on sl@0: * the server's heap is the same as the specified value. This function only sl@0: * works for debug builds. sl@0: * sl@0: * @param aCount The number of heap cells expected to be allocated at sl@0: * the current nest level. sl@0: * sl@0: * @return KErrNone. sl@0: */ sl@0: TInt CShBufTestServer::DbgCheckHeap(TInt aCount) const sl@0: { sl@0: #ifdef _DEBUG sl@0: __UHEAP_CHECK(aCount); sl@0: #else sl@0: (void) aCount; sl@0: #endif sl@0: sl@0: return(KErrNone); sl@0: } // CShBufTestServer::DbgCheckHeap sl@0: sl@0: sl@0: /** sl@0: * Marks the end of checking the current server's heap. sl@0: * sl@0: * The function expects aCount heap cells to remain allocated at the sl@0: * current nest level. This function must match an earlier call to sl@0: * DbgMarkHeap() and only functions on debug releases. sl@0: * sl@0: * @param aCount The number of heap cells expected to remain allocated sl@0: * at the current nest level. sl@0: * sl@0: * @return KErrNone. sl@0: */ sl@0: TInt CShBufTestServer::DbgMarkEnd(TInt aCount) const sl@0: { sl@0: #ifdef _DEBUG sl@0: __UHEAP_MARKENDC(aCount); sl@0: #else sl@0: (void) aCount; sl@0: #endif sl@0: sl@0: return(KErrNone); sl@0: } // CShBufTestServer::DbgMarkEnd sl@0: sl@0: sl@0: /** sl@0: * Simulates heap allocation failure for the server. sl@0: * sl@0: * The failure occurs on the next call to new or any of the functions which sl@0: * allocate memory from the heap. This is defined only for debug builds. sl@0: * sl@0: * @param aCount Determines when the allocation will fail. sl@0: * sl@0: * @return KErrNone. sl@0: */ sl@0: TInt CShBufTestServer::DbgFailNext(TInt aCount) const sl@0: { sl@0: #ifdef _DEBUG sl@0: if (aCount == 0) sl@0: { sl@0: __UHEAP_RESET; sl@0: } sl@0: else sl@0: { sl@0: __UHEAP_FAILNEXT(aCount); sl@0: } sl@0: #else sl@0: (void) aCount; sl@0: #endif sl@0: sl@0: return(KErrNone); sl@0: } // CShBufTestServer::DbgFailNext sl@0: sl@0: sl@0: /** sl@0: * Requests the server to shut down when it no longer has any connected sl@0: * sessions. This procedure is only premitted in debug builds and is provided sl@0: * for testing purposes. sl@0: * sl@0: * The server will shutdown when the last session disconnects. sl@0: * sl@0: * @return KErrNone if the shutdown request was accepted, otherwise returns sl@0: * an error. sl@0: */ sl@0: TInt CShBufTestServer::ShutdownServer() sl@0: { sl@0: iShouldShutdownServer = ETrue; sl@0: sl@0: return(KErrNone); sl@0: } // CShBufTestServer::ShutdownServer sl@0: sl@0: sl@0: sl@0: /** sl@0: * Standard Active Object RunError() method, called when the RunL() method sl@0: * leaves, which will be when the CShBufTestServerSession::ServiceL() leaves. sl@0: * sl@0: * Find the current message and complete it before restarting the server. sl@0: * sl@0: * @param aError Leave code from CShBufTestServerSession::ServiceL(). sl@0: * sl@0: * @return KErrNone sl@0: */ sl@0: TInt CShBufTestServer::RunError(TInt aError) sl@0: { sl@0: // sl@0: // Complete the request with the available error code. sl@0: // sl@0: if (Message().IsNull() == EFalse) sl@0: { sl@0: Message().Complete(aError); sl@0: } sl@0: sl@0: // sl@0: // The leave will result in an early return from CServer::RunL(), skipping sl@0: // the call to request another message. So do that now in order to keep the sl@0: // server running. sl@0: // sl@0: ReStart(); sl@0: sl@0: return KErrNone; sl@0: } // CShBufTestServer::RunError sl@0: sl@0: sl@0: /** sl@0: * Perform all server initialisation, in particular creation of the sl@0: * scheduler and server and then run the scheduler. sl@0: */ sl@0: static void RunServerL() sl@0: { sl@0: // sl@0: // Naming the server thread after the server helps to debug panics. sl@0: // sl@0: User::LeaveIfError(User::RenameThread(KRShBufTestServerName)); sl@0: sl@0: // sl@0: // Increase priority so that requests are handled promptly... sl@0: // sl@0: RThread().SetPriority(EPriorityMuchMore); sl@0: sl@0: // sl@0: // Create a new Active Scheduler... sl@0: // sl@0: CActiveScheduler* scheduler = new CActiveScheduler(); sl@0: CleanupStack::PushL(scheduler); sl@0: CActiveScheduler::Install(scheduler); sl@0: sl@0: // sl@0: // Create a new PhoneBookServer... sl@0: // sl@0: CShBufTestServer* server = CShBufTestServer::NewL(); sl@0: CleanupStack::PushL(server); sl@0: sl@0: // sl@0: // Initialisation complete, now signal the client thread... sl@0: // sl@0: #ifdef CAN_TRANSFER_SHBUF_TO_ANOTHER_PROCESS sl@0: RProcess::Rendezvous(KErrNone); sl@0: #else sl@0: RThread::Rendezvous(KErrNone); sl@0: #endif sl@0: sl@0: // sl@0: // Run the server... sl@0: // sl@0: CActiveScheduler::Start(); sl@0: sl@0: CleanupStack::PopAndDestroy(2, scheduler); sl@0: } // RunServerL sl@0: sl@0: sl@0: /** sl@0: * Server process entry-point. sl@0: * sl@0: * @return KErrNone or a standard Symbian error code. sl@0: */ sl@0: #ifdef CAN_TRANSFER_SHBUF_TO_ANOTHER_PROCESS sl@0: TInt E32Main() sl@0: #else sl@0: TInt RShBufTestServerThread(TAny* /*aPtr*/) sl@0: #endif sl@0: { sl@0: __UHEAP_MARK; sl@0: sl@0: CTrapCleanup* cleanup = CTrapCleanup::New(); sl@0: TInt ret(KErrNoMemory); sl@0: sl@0: if (cleanup) sl@0: { sl@0: TRAP(ret, RunServerL()); sl@0: delete cleanup; sl@0: } sl@0: sl@0: __UHEAP_MARKEND; sl@0: sl@0: return ret; sl@0: } // E32Main sl@0: sl@0: sl@0: