Update contrib.
2 * Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
4 * This component and the accompanying materials are made available
5 * under the terms of the License "Eclipse Public License v1.0"
6 * which accompanies this distribution, and is available
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
15 * CScsSession implementation. See class and function definitions
26 #include <scs/scsserver.h>
27 #include "scsserverconstants.h"
29 EXPORT_C void CScsSession::ConstructL()
31 The subsession [handle] container could be constructed
32 here, but that is deferred until the subsession is allocated to
33 avoid the memory overhead for sessions which may not require
37 iServer.IncrementSessionCount();
40 EXPORT_C CScsSession::CScsSession(CScsServer &aServer)
43 Setup the iServer member variable so it can be used during construction
49 EXPORT_C CScsSession::~CScsSession()
51 Deletes any subsessions.
53 Deletes any outstanding requests.
55 Decrements the server's session count so the server can be shut down
56 if there are no open sessions.
59 iServer.CancelOutstandingRequests(this, /* aCompleteClientRequests */ EFalse);
61 DeleteSubsessionContainers(); // closes any remaining subsessions
63 // decrement the session count, so the server can be shut down if
64 // there are no more open sessions.
65 iServer.DecrementSessionCount();
68 EXPORT_C void CScsSession::CloseAllSubsessionsL()
70 DeleteSubsessionContainers();
73 EXPORT_C void CScsSession::ServiceL(const RMessage2& aMessage)
75 Implement CSession2 by handling any SCS-specific messages, and
76 otherwise delegating to the subclass' implementation.
78 @param aMessage Standard server-side message object.
81 ScsImpl::TScsFunction scsFunc;
83 ScsImpl::ExtractScsAndImplFunctions(aMessage, &scsFunc, &implFunc);
84 TBool completeMessage = ETrue;
89 case ScsImpl::ECallSessionFunc:
90 completeMessage = DoServiceL(implFunc, aMessage);
93 case ScsImpl::EPreCloseSession:
97 case ScsImpl::ECancelSessionFunc:
98 CancelAsyncSessionRequestL(implFunc);
101 case ScsImpl::EGetServerPid:
103 TPckgBuf<TProcessId> idBuf;
106 aMessage.WriteL(0, idBuf);
110 case ScsImpl::EShutdownAsap:
111 iServer.ShutdownWhenIdleL();
115 case ScsImpl::ECreateSubsession:
116 // if there are no open subsessions before this attempt then clean up
117 // the containers if it fails. This is to ensure the server heap balances
118 // in the event of failure.
119 iPreCreateSubsessionCount = iSsHandles ? iSsHandles->ActiveCount() : 0;
120 CreateSubsessionL(implFunc, aMessage);
123 case ScsImpl::ECloseSubsession:
124 CloseSubsessionL(aMessage);
127 case ScsImpl::ECallSubsessionFunc:
128 completeMessage = CallSubsessionFunctionL(implFunc, aMessage);
131 case ScsImpl::ECancelSubsessionFunc:
132 CancelAsyncSubsessionRequestL(implFunc, aMessage);
135 // server heap testing
136 case ScsImpl::EUHeapSetFail:
138 iServer.DoPreHeapMarkOrCheckL();
140 __UHEAP_SETFAIL(RAllocator::EDeterministic, aMessage.Int0());
141 iServer.DoPostHeapMarkOrCheckL();
145 case ScsImpl::EUHeapResetFail:
147 iServer.DoPreHeapMarkOrCheckL();
150 iServer.DoPostHeapMarkOrCheckL();
154 // unrecognized SCS code, so fail with KErrNotSupported
156 User::Leave(KErrNotSupported);
159 // None of the delegate functions have left so complete with KErrNone.
162 aMessage.Complete(KErrNone);
166 EXPORT_C void CScsSession::ServiceError(const RMessage2& aMessage, TInt aError)
168 Override CSession2 by handling any leave which occurred during the ServiceL.
170 Panick the client if the leave is because of a bad descriptor or subsession
171 handle. Otherwise, complete the request with the error code.
173 @param aMessage Message which caused leave to occur.
174 @param aError Leave code. This is a Symbian OS error code.
175 @see CSession2::ServiceError
178 // if failed to create first subsession then free containers so heap
179 // balances after message has been completed.
181 ScsImpl::TScsFunction scsFunc;
182 ScsImpl::ExtractScsAndImplFunctions(aMessage, &scsFunc, NULL);
184 if (scsFunc == ScsImpl::ECreateSubsession && iPreCreateSubsessionCount == 0)
185 DeleteSubsessionContainers();
189 case KErrBadDescriptor:
190 PanicClient(aMessage, ScsImpl::EScsClBadDesc);
194 PanicClient(aMessage, ScsImpl::EScsClBadHandle);
197 case KErrScsAsyncAlreadyQueued:
198 PanicClient(aMessage, ScsImpl::EScsClAsyncAlreadyQueued);
202 aMessage.Complete(aError);
207 // -------- session close --------
209 void CScsSession::PreCloseSession()
211 This function is invoked from RScsClientBase::Close
212 just before the session is closed, to cancel any
213 outstanding requests.
216 iServer.CancelOutstandingRequests(this, /* aCompleteClientRequests */ ETrue);
219 // -------- asynchronous requests --------
221 void CScsSession::CancelAsyncSessionRequestL(TInt aFunction)
223 This function is called when handling an ECancelSessionFunction message.
224 If the outstanding function cannot be found, this function does nothing.
226 @param aFunction Implementation function without SCS code.
229 iServer.CancelAsyncRequest(this, /* aSubsession */ 0, aFunction);
232 // -------- subsessions --------
234 CScsSubsession* CScsSession::GetSubsessionL(const RMessage2& aMessage)
236 Extract subsession handle from the supplied message and return
237 a pointer to the corresponding subsession object.
239 @param aMessage Standard server-side message object. The fourth
240 argument is the subsession handle.
241 @return Pointer to corresponding subsession object.
242 @leave KErrBadHandle if the handle does not identify a
246 TInt handle = aMessage.Int3();
247 CObject* obj = iSsHandles->AtL(handle); // leaves with KErrBadHandle if not found
248 return static_cast<CScsSubsession*>(obj);
251 void CScsSession::DeleteSubsessionContainers()
253 Free the handle and object containers which this session uses
254 to manage subsessions. It is safe to call this function if the
255 containers were not set up successfully.
263 iServer.iContainerIndex->Remove(iSsObjects);
268 void CScsSession::CreateSubsessionL(TInt aFunction, const RMessage2& aMessage)
270 Attempt to allocate a subsession object for this session. The actual
271 subsession allocation is delegated to the subclass's implementation
272 of DoCreateSubsessionL. If the subclass has not reimplemented this
273 function, then default implementation leaves with KErrNotSupported.
275 @param aFunction Function identifier without SCS code.
276 @param aMessage Standard server-side message object.
279 // if this is the first subsession then create the object container and index
282 iSsObjects = iServer.iContainerIndex->CreateL();
283 iSsHandles = CObjectIx::NewL();
286 CScsSubsession* ss = DoCreateSubsessionL(aFunction, aMessage);
287 CleanupClosePushL(*ss);
289 iSsObjects->AddL(ss);
290 TInt handle = iSsHandles->AddL(ss);
291 CleanupStack::Pop(ss);
293 TPckg<TInt> handlePckg(handle);
294 TInt r = aMessage.Write(3, handlePckg);
295 User::LeaveIfError(r);
298 #ifdef _BullseyeCoverage
299 static const char * const bull1="BullseyeCoverage save off";
301 EXPORT_C CScsSubsession* CScsSession::DoCreateSubsessionL(TInt aFunction, const RMessage2& aMessage)
303 This default implementation leaves with KErrNotSupported. The subclass
304 does not have to supply its own implementation unless it actually wants
305 to support subsessions.
307 @param aFunction Function identifier without SCS code. The subclass
308 implementation of this function would use this to decide
309 what kind of subsession object to create.
310 @param aMessage Client message. Not used.
311 @leave KErrNotSupported.
317 User::Leave(KErrNotSupported);
318 /*lint -unreachable*/ // Avoid compiler warning and keep lint happy
321 #ifdef _BullseyeCoverage
322 static const char * const bull2="BullseyeCoverage restore";
325 void CScsSession::CloseSubsessionL(const RMessage2& aMessage)
327 Delete the subsession identified in the supplied message.
329 If the subsession cannot be found this function leaves with KErrBadHandle,
330 and the client is panicked in ServiceError.
332 @param aMessage Standard server-side message handle. The fourth
333 integer contains the subsession handle.
336 TInt handle = aMessage.Int3();
337 CObject* obj = iSsHandles->AtL(handle); // leaves with KErrBadHandle if not found
338 CScsSubsession* ss = static_cast<CScsSubsession*>(obj);
340 iServer.CancelOutstandingRequests(this, ss, /* aCancelClientRequests */ ETrue);
342 iSsHandles->Remove(handle);
344 // close the container objects to ensure the heap balances when the last subsession is closed
345 if (iSsHandles->ActiveCount() == 0)
346 DeleteSubsessionContainers();
349 TBool CScsSession::CallSubsessionFunctionL(TInt aFunction, const RMessage2& aMessage)
351 Pass the supplied function identifier and message to the subsession
352 which is identified in the message.
354 If the subsession cannot be found this function leaves with KErrBadHandle,
355 and the client is panicked in ServiceError.
357 @param aFunction Function identifier without SCS code.
358 @param aMessage Client message.
359 @return ETrue means complete client request now.
363 CScsSubsession* ss = GetSubsessionL(aMessage);
364 return ss->DoServiceL(aFunction, aMessage);
367 void CScsSession::CancelAsyncSubsessionRequestL(TInt aFunction, const RMessage2& aMessage)
369 Cancel an outstanding asynchronous request for the subsession
370 identified in the supplied message.
372 @param aFunction Function identifier without SCS code.
373 @param aMessage Standard server-side message handle. The fourth
374 integer contains the subsession handle.
377 CScsSubsession* ss = GetSubsessionL(aMessage);
378 iServer.CancelAsyncRequest(this, ss, aFunction);