|
1 // Copyright (c) 2004-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 "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 // |
|
15 |
|
16 #include "panic.h" |
|
17 #include "srvreqs.h" |
|
18 #include "sessmgr.h" |
|
19 #include "cachemgr.h" |
|
20 #include "srvsubsess.h" |
|
21 #include "srvsess.h" |
|
22 |
|
23 CServerSession::~CServerSession() |
|
24 { |
|
25 // Delete the subsession index. |
|
26 delete iSubSessionIx; |
|
27 |
|
28 //Delete the subsession container via the CObjectConIx's remove function |
|
29 ((CSessionManager*)Server())->RemoveContainer(iContainer); |
|
30 } |
|
31 |
|
32 //Called by client/server framework after session has been successfully created. |
|
33 //In effect, a second-phase constructor. |
|
34 //Creates the object index and the object container for this session. |
|
35 void CServerSession::CreateL() |
|
36 { |
|
37 // Create new object index |
|
38 iSubSessionIx = CObjectIx::NewL(); |
|
39 |
|
40 // Initialize the object container |
|
41 // using the object container index in the server. |
|
42 iContainer = ((CSessionManager*)Server())->NewContainerL(); |
|
43 } |
|
44 |
|
45 //helper method to resolve and verify subsession using RMessage and subsession handle |
|
46 CServerSubSession* CServerSession::SubSessionFromHandle(const RMessage2& aMessage, TInt aHandle) |
|
47 { |
|
48 CServerSubSession* subSession = (CServerSubSession*)iSubSessionIx->At(aHandle); |
|
49 if (subSession == NULL) |
|
50 { |
|
51 PanicClient(EBadSubsessionHandle, aMessage); |
|
52 } |
|
53 |
|
54 return subSession; |
|
55 } |
|
56 |
|
57 // if ServiceL Leaves, execution resumes in this method. |
|
58 // this allows us to panic clients using bad descriptors, to deal with OOM conditions |
|
59 // and to fail transactions with the correct reason: OOM etc. |
|
60 void CServerSession::ServiceError(const RMessage2 &aMessage, TInt aError) |
|
61 { |
|
62 TServerRequest fn = static_cast<TServerRequest>(aMessage.Function()); |
|
63 |
|
64 // If we have failed during initialisation the subsession is no longer available. |
|
65 // Perform additional cleanup by removing the subsession's handle from the server's |
|
66 // subsession index. |
|
67 if (fn == EInitialise) |
|
68 { |
|
69 // Retrieve handle |
|
70 TPckgBuf<TInt> handlePckg; |
|
71 TRAPD(res,aMessage.ReadL(3,handlePckg)); |
|
72 |
|
73 if (res == KErrNone) |
|
74 { |
|
75 TInt subSessionHandle = handlePckg(); |
|
76 iSubSessionIx->Remove(subSessionHandle); |
|
77 } |
|
78 #ifdef _DEBUG |
|
79 else |
|
80 { |
|
81 RDebug::Print(_L("CServerSession::ServiceError - Can't remove subsession handle; aError = %d; res = %d"), aError, res); |
|
82 } |
|
83 #endif |
|
84 } |
|
85 |
|
86 //under following conditions the subsession handles the error |
|
87 if(fn > EInitialise && fn < ELastInTable) |
|
88 { |
|
89 CServerSubSession* subSession = SubSessionFromHandle(aMessage, aMessage.Int3()); |
|
90 if(subSession) |
|
91 { |
|
92 subSession->ServiceError(aError); |
|
93 } |
|
94 #ifdef _DEBUG |
|
95 else |
|
96 { |
|
97 RDebug::Print(_L("CServerSession::ServiceError - bad subsession handle. aError = %d"), aError); |
|
98 } |
|
99 #endif |
|
100 } |
|
101 #ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS |
|
102 //for multi ROFS instead of leaving we panic the client instead |
|
103 switch (aError) |
|
104 { |
|
105 case KErrMultiRofsOldCreUsed: |
|
106 PanicClient(EMultiRofsPanicOldCre,aMessage); |
|
107 return; |
|
108 case KErrMultiRofsGlobalOverride: |
|
109 PanicClient(EMultiRofsPanicGlobalOverride,aMessage); |
|
110 return; |
|
111 case KErrMultiRofsTypeOverride: |
|
112 PanicClient(EMultiRofsPanicTypeOveride,aMessage); |
|
113 return; |
|
114 case KErrMultiRofsIllegalRofs: |
|
115 PanicClient(EMultiRofsPanicIllegalRofs,aMessage); |
|
116 return; |
|
117 } |
|
118 #endif |
|
119 |
|
120 CSession2::ServiceError(aMessage, aError); |
|
121 } |
|
122 |
|
123 void CServerSession::ServiceL(const RMessage2& aMessage) |
|
124 { |
|
125 TServerRequest fn = static_cast<TServerRequest>(aMessage.Function()); |
|
126 |
|
127 #if defined(__CENTREP_SERVER_PERFTEST__) || defined(__CENTREP_SERVER_MEMTEST__) || defined(__CENTREP_SERVER_CACHETEST__) |
|
128 if (fn == EGetSetParameters) |
|
129 { |
|
130 TInt r = GetSetParameters(aMessage); |
|
131 aMessage.Complete(r); |
|
132 return; |
|
133 } |
|
134 #endif |
|
135 |
|
136 if(fn > ELastInTable) |
|
137 { |
|
138 PanicClient(EBadMessageNumber, aMessage); |
|
139 } |
|
140 |
|
141 CServerSubSession* subSession = NULL; |
|
142 |
|
143 #if defined (SYMBIAN_CENTREP_SUPPORT_MULTIROFS) && defined(CENTREP_TRACE) |
|
144 TUint32 startTick=0; |
|
145 TUid repUid; |
|
146 startTick=User::FastCounter(); |
|
147 #endif |
|
148 PERF_TEST_EVENT_START(subSession, aMessage); |
|
149 |
|
150 if(fn == EInitialise) |
|
151 { |
|
152 //create subsession |
|
153 subSession = NewSubSessionL(aMessage); |
|
154 #if defined (SYMBIAN_CENTREP_SUPPORT_MULTIROFS) && defined(CENTREP_TRACE) |
|
155 repUid=TUid::Uid(aMessage.Int0()); |
|
156 subSession->iRepositoryUid=repUid; |
|
157 #endif |
|
158 } |
|
159 else |
|
160 { |
|
161 subSession = SubSessionFromHandle(aMessage, aMessage.Int3()); |
|
162 #if defined (SYMBIAN_CENTREP_SUPPORT_MULTIROFS) && defined(CENTREP_TRACE) |
|
163 repUid=subSession->iRepositoryUid; |
|
164 #endif |
|
165 } |
|
166 |
|
167 if(subSession) |
|
168 { |
|
169 |
|
170 TInt r = KErrNone; |
|
171 |
|
172 if(fn == EClose) |
|
173 { |
|
174 //delete subsession |
|
175 DeleteSubSession(aMessage.Int3()); |
|
176 } |
|
177 else |
|
178 { |
|
179 //ask subsession to handle the message |
|
180 r = subSession->ServiceL(aMessage); |
|
181 } |
|
182 |
|
183 PERF_TEST_EVENT_END(subSession, aMessage); |
|
184 |
|
185 #if defined (SYMBIAN_CENTREP_SUPPORT_MULTIROFS) && defined(CENTREP_TRACE) |
|
186 TUint32 endTick=User::FastCounter(); |
|
187 RDebug::Print(_L("[CENTREP],TimeStamp=,%d,Repository=,%x,Function=,%d,TickCount=,%d"),startTick,repUid.iUid,fn,endTick-startTick); |
|
188 #endif |
|
189 if (r != CServerSubSession::KDontCompleteMessage) |
|
190 { |
|
191 aMessage.Complete(r); |
|
192 } |
|
193 } |
|
194 //If (subsession == NULL) we don't need to complete the message, as the message is completed already when the client panicked |
|
195 #ifdef _DEBUG |
|
196 else |
|
197 { |
|
198 RDebug::Print(_L("CServerSession::ServiceL - bad subsession handle. TServerRequest = %d"), fn); |
|
199 } |
|
200 #endif |
|
201 } |
|
202 |
|
203 //Creates a new subsession object, and writes its handle to the message. |
|
204 //A subsession object is the server side "partner" to the client side subsession. |
|
205 //On return last parameter of aMessage is filled with the handle of the subsession |
|
206 //and handle is also returned |
|
207 CServerSubSession* CServerSession::NewSubSessionL(const RMessage2& aMessage) |
|
208 { |
|
209 //create a new subsession |
|
210 CServerSubSession* subSession = new (ELeave) CServerSubSession(this); |
|
211 CleanupStack::PushL(subSession); |
|
212 |
|
213 //add the subsession object to this session's object container to generate a unique ID |
|
214 iContainer->AddL(subSession); |
|
215 CleanupStack::Pop(subSession); |
|
216 |
|
217 //add the object to the subsessions index, this returns a unique handle so that we can |
|
218 //refer to the object later |
|
219 TInt handle = iSubSessionIx->AddL(subSession); |
|
220 |
|
221 //write the handle to the client's message |
|
222 TPckgBuf<TInt> handlePckg(handle); |
|
223 TRAPD(res,aMessage.WriteL(3,handlePckg)); |
|
224 if (res!=KErrNone) |
|
225 { |
|
226 iSubSessionIx->Remove(handle); |
|
227 PanicClient(EBadSubsessionHandle, aMessage); |
|
228 subSession = NULL; |
|
229 } |
|
230 |
|
231 return subSession; |
|
232 } |
|
233 |
|
234 //Deletes a subsession object through its handle. |
|
235 void CServerSession::DeleteSubSession(TInt aHandle) |
|
236 { |
|
237 iSubSessionIx->Remove(aHandle); |
|
238 } |
|
239 |
|
240 inline CSessionManager* CServerSession::Server() |
|
241 { |
|
242 return static_cast<CSessionManager*>(const_cast<CServer2*>(CSession2::Server())); |
|
243 } |
|
244 |
|
245 #if defined(__CENTREP_SERVER_PERFTEST__) || defined (__CENTREP_SERVER_MEMTEST__) || defined(__CENTREP_SERVER_CACHETEST__) |
|
246 // GetSetParameters |
|
247 // The function code EGetSetParameters is a generic msg reserved |
|
248 // for testing purpose. Int0 specifies the function to perform. |
|
249 TInt CServerSession::GetSetParameters(const TClientRequest& aMessage) |
|
250 { |
|
251 TServerGetSetParametersSubCmd cmd = static_cast<TServerGetSetParametersSubCmd>(aMessage.Int0()); |
|
252 |
|
253 #ifdef __CENTREP_SERVER_PERFTEST__ |
|
254 if (cmd == EGetPerfResults) |
|
255 { |
|
256 TInt desSize = aMessage.GetDesMaxLength(1); |
|
257 TInt numVals = desSize / sizeof(TUint32); |
|
258 if (numVals < KCentRepPerfTestArraySize) |
|
259 { |
|
260 return KErrOverflow; |
|
261 } |
|
262 TPtrC8 p(reinterpret_cast<const TUint8*>(TServerResources::iPerfTestMgr.Entries()), |
|
263 KCentRepPerfTestArraySize * sizeof(TUint32)); |
|
264 TInt ret = aMessage.Write(1, p); |
|
265 if (ret == KErrNone) |
|
266 { |
|
267 TUint lastCompleteAccess = TServerResources::iPerfTestMgr.LastCompleteAccess(); |
|
268 TPckg<TUint> p2(lastCompleteAccess); |
|
269 ret = aMessage.Write(2, p2); |
|
270 } |
|
271 return ret; |
|
272 } |
|
273 else if (cmd == ERestartPerfTests) |
|
274 { |
|
275 TServerResources::iPerfTestMgr.Reset(); |
|
276 return KErrNone; |
|
277 } |
|
278 else if (cmd == EStopPerfTests) |
|
279 { |
|
280 TServerResources::iPerfTestMgr.Stop(); |
|
281 return KErrNone; |
|
282 } |
|
283 #endif // __CENTREP_SERVER_PERFTEST__ |
|
284 |
|
285 #ifdef __CENTREP_SERVER_MEMTEST__ |
|
286 if(cmd == ERestartMemTests) |
|
287 { |
|
288 TServerResources::StartRecordTimerResult(); |
|
289 return KErrNone; |
|
290 } |
|
291 else if(cmd == ESingleMemTest) |
|
292 { |
|
293 RECORD_HEAP_SIZE(EMemLcnOnDemand, aMessage.Int1()); |
|
294 return KErrNone; |
|
295 } |
|
296 else if(cmd == EGetMemResults) |
|
297 { |
|
298 TInt count = TServerResources::iMemTestDataCount; |
|
299 TPckg<TInt> pCount(count); |
|
300 |
|
301 TInt err = aMessage.Write(1, pCount); |
|
302 if(err == KErrNone && count > 0) |
|
303 { |
|
304 TPtrC8 pBuf(reinterpret_cast<TUint8*>(TServerResources::iMemTestData), (TServerResources::iMemTestDataCount)*sizeof(TInt32)); |
|
305 err = aMessage.Write(2, pBuf); |
|
306 } |
|
307 // Stop recording results |
|
308 TServerResources::StopRecordTimerResult(); |
|
309 return err; |
|
310 } |
|
311 #endif // __CENTREP_SERVER_MEMTEST__ |
|
312 |
|
313 #ifdef __CENTREP_SERVER_CACHETEST__ |
|
314 if (cmd == EEnableCache) |
|
315 { |
|
316 // First parameter is Timer Interval, second is cache size |
|
317 TServerResources::iCacheManager->EnableCache(aMessage.Int1(), aMessage.Int2()); |
|
318 return KErrNone; |
|
319 } |
|
320 else if (cmd == EDisableCache) |
|
321 { |
|
322 TServerResources::iCacheManager->DisableCache(ETrue); |
|
323 return KErrNone; |
|
324 } |
|
325 #endif // __CENTREP_SERVER_CACHETEST__ |
|
326 |
|
327 return KErrNotSupported; |
|
328 } |
|
329 #endif // __CENTREP_SERVER_PERFTEST__ || __CENTREP_SERVER_MEMTEST__ || __CENTREP_SERVER_CACHETEST__ |
|
330 |