Update contrib.
1 // Copyright (c) 1998-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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // e32test\thread\t_threadedserver.cpp
15 // Tests the multi-threaded server/session support in CServer2/CSession2
17 // Tests the CServer2::SetMaster and CSession2:SetServer functions
19 // CServer2, CSession2
21 // - Test creating multiple sessions with a single-threaded server
22 // - Test creating multiple sessions with a multi-threaded server
23 // - Verify that requests to a multi-threaded server can run in parallel and complete out-of-order
24 // Platforms/Drives/Compatibility:
26 // Assumptions/Requirement/Pre-requisites:
27 // Failures and causes:
28 // Base Port information:
33 #define __E32TEST_EXTENSION__
38 _LIT(KMyName, "T_THREADEDSERVER");
39 _LIT(KServerName,"MyServer");
40 const TInt KHeapSize = 4096;
42 LOCAL_D RTest test(KMyName);
44 class CMySession : public CSession2
47 enum TMyRequests { EFinish, EDelay5, EPing };
49 virtual void ServiceL(const RMessage2& aMessage);
54 CMySession::CMySession(TInt aId) :
59 void CMySession::ServiceL(const RMessage2& aMessage)
61 TInt err = KErrNotSupported;
63 RDebug::Printf("Session %d: received message %d", iD, aMessage.Function());
64 switch (aMessage.Function())
67 CActiveScheduler::Stop();
85 RDebug::Printf("Session %d: completing message %d, err %d", iD, aMessage.Function(), err);
87 aMessage.Complete(err);
89 aMessage.Panic(KServerName, err);
93 class CMyServer : public CServer2
97 virtual CSession2* NewSessionL(const TVersion& aVersion, const RMessage2& aMessage) const;
102 static CMyServer* TheMaster = NULL;
103 static CMyServer* TheSlave = NULL;
105 CMyServer::CMyServer() :
111 CSession2* CMyServer::NewSessionL(const TVersion&, const RMessage2&) const
113 RDebug::Printf("Server: creating session, slave is $%x", TheSlave);
115 CSession2* mySession = new (ELeave) CMySession(iCount);
116 if (iCount > 1 && TheSlave != NULL)
117 mySession->SetServer(TheSlave);
118 RDebug::Printf("Server: created session %d", iCount);
122 TInt RunServerCode(TAny* aFlag)
124 TInt mode = (TInt)aFlag;
125 TInt r = KErrNoMemory;
126 RDebug::Printf("Server: start, mode %d", mode);
128 CTrapCleanup* cleanup = CTrapCleanup::New();
132 CActiveScheduler* pR = new CActiveScheduler;
136 CActiveScheduler::Install(pR);
137 CMyServer* pS = new CMyServer();
144 r = pS->Start(KServerName);
148 pS->SetMaster(TheMaster);
149 r = pS->Start(KServerName);
153 pS->SetMaster(TheMaster);
154 r = pS->Start(KNullDesC);
160 RThread::Rendezvous(KErrNone);
161 TRAP(r, CActiveScheduler::Start());
169 RDebug::Printf("Server: exit");
174 class RSession : public RSessionBase
178 void Request(TInt aRequest, TRequestStatus& aStatus);
179 void Request(TInt aRequest);
182 TInt RSession::Create()
184 return CreateSession(KServerName, TVersion());
187 void RSession::Request(TInt aRequest, TRequestStatus& aStatus)
189 SendReceive(aRequest, TIpcArgs(), aStatus);
192 void RSession::Request(TInt aRequest)
194 SendReceive(aRequest, TIpcArgs());
197 TInt RunClientCode(TAny* aFlag)
199 TInt mode = (TInt)aFlag;
200 RDebug::Printf("Client: open sessions");
201 RSession session1, session2;
206 TRequestStatus status1 (KRequestPending), status2 (KRequestPending);
207 RDebug::Printf("Client: send request 1");
208 session1.Request(CMySession::EDelay5, status1);
209 User::After(1000000);
210 RDebug::Printf("Client: send request 2");
211 session2.Request(CMySession::EPing, status2);
213 User::WaitForRequest(status1, status2);
214 if (status1 == KRequestPending)
216 // request2 finished first ...
218 RDebug::Printf("Client: request 2 completed %d", status2.Int());
219 User::WaitForRequest(status1);
223 RDebug::Printf("Client: request 1 completed %d", status1.Int());
224 User::WaitForRequest(status2);
226 RDebug::Printf("Client: status1 %d status2 %d OOC %d", status1.Int(), status2.Int(), ooc);
227 test_KErrNone(status1.Int());
228 test_KErrNone(status2.Int());
229 test_Equal(ooc, mode > 0);
232 session2.Request(CMySession::EFinish);
233 session1.Request(CMySession::EFinish);
234 RDebug::Printf("Client: exit");
239 void TestSequential()
241 TRequestStatus status;
243 RDebug::Printf("Main: start server");
244 RThread serverThread;
245 test_KErrNone(serverThread.Create(_L("server"), RunServerCode, KHeapSize, NULL, (TAny*)0));
246 serverThread.Rendezvous(status);
247 serverThread.Resume();
248 User::WaitForRequest(status);
249 test_KErrNone(status.Int());
251 RDebug::Printf("Main: start client");
252 RThread clientThread;
253 test_KErrNone(clientThread.Create(_L("client"), RunClientCode, KHeapSize, NULL, (TAny*)0));
254 clientThread.Logon(status);
255 clientThread.Resume();
256 User::WaitForRequest(status);
257 test_KErrNone(clientThread.ExitReason());
258 test_Equal(EExitKill, clientThread.ExitType());
260 serverThread.Logon(status);
261 User::WaitForRequest(status);
262 test_KErrNone(serverThread.ExitReason());
263 test_Equal(EExitKill, serverThread.ExitType());
266 RDebug::Printf("Main: exit");
271 TRequestStatus status;
273 RDebug::Printf("Main: start master server");
274 RThread masterThread;
275 test_KErrNone(masterThread.Create(_L("master"), RunServerCode, KHeapSize, NULL, (TAny*)1));
276 masterThread.Rendezvous(status);
277 masterThread.Resume();
278 User::WaitForRequest(status);
279 test_KErrNone(status.Int());
281 RDebug::Printf("Main: start slave server");
283 test_KErrNone(slaveThread.Create(_L("slave"), RunServerCode, KHeapSize, NULL, (TAny*)2));
284 slaveThread.Rendezvous(status);
285 slaveThread.Resume();
286 User::WaitForRequest(status);
287 test_KErrNone(status.Int());
289 RDebug::Printf("Main: start client");
290 RThread clientThread;
291 test_KErrNone(clientThread.Create(_L("client2"), RunClientCode, KHeapSize, NULL, (TAny*)3));
292 clientThread.Logon(status);
293 clientThread.Resume();
294 User::WaitForRequest(status);
295 test_KErrNone(clientThread.ExitReason());
296 test_Equal(EExitKill, clientThread.ExitType());
298 slaveThread.Logon(status);
299 User::WaitForRequest(status);
300 test_KErrNone(slaveThread.ExitReason());
301 test_Equal(EExitKill, slaveThread.ExitType());
303 masterThread.Logon(status);
304 User::WaitForRequest(status);
305 test_KErrNone(masterThread.ExitReason());
306 test_Equal(EExitKill, masterThread.ExitType());
309 RDebug::Printf("Main: exit");
313 GLDEF_C TInt E32Main()
321 test.Start(_L("Test threaded server support"));
322 test.Next(_L("Test two sessions to the same server (single-threaded)"));
324 test.Next(_L("Test two sessions to the same server (multi-threaded)"));