--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cryptomgmtlibs/securitycommonutils/source/scsserver/asyncrequest.cpp Thu Sep 10 14:01:51 2009 +0300
@@ -0,0 +1,166 @@
+/*
+* Copyright (c) 2007-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:
+* Base class functionality for server-side asynchronous requests.
+*
+*/
+
+
+/**
+ @file
+*/
+
+
+#include <scs/scsserver.h>
+#include "scsserverconstants.h"
+
+EXPORT_C CAsyncRequest::CAsyncRequest(CScsSession* aSession, CScsSubsession* aSubsession, const RMessage2& aMessage)
+/**
+ Record the session, subsession, and function associated with this request.
+ These are required to complete or to cancel the request later.
+
+ Adds this object to the active scheduler.
+
+ @param aSession Session used to launch this request.
+ @param aSubsession Subsession on which this request is queued. This
+ should be NULL if the request is relative to a session,
+ instead of a subsession
+ @param aMessage Handle to the kernel-side request object, which
+ will be completed later.
+ */
+: CActive(CActive::EPriorityStandard),
+ iSession(aSession),
+ iSubsession(aSubsession),
+ iMessagePtr2(aMessage)
+ {
+ // extract implementation function
+ ScsImpl::ExtractScsAndImplFunctions(aMessage, NULL, &iFunction);
+
+ CActiveScheduler::Add(this);
+ }
+
+EXPORT_C void CAsyncRequest::TransferToScsFrameworkL()
+/**
+ Adds this asynchronous request to the global collection.
+ This should be called after the subclass has performed its
+ own initialization, but before the active request has been
+ set up.
+ */
+ {
+ iSession->iServer.AddAsyncRequestL(this);
+ }
+
+EXPORT_C void CAsyncRequest::RunL()
+/**
+ Implement CActive by completing the server client's request status
+ with the AO error code, i.e. iStatus. This function also marks this
+ object for deletion.
+
+ If a subclass overrides this implementation then it must call
+ CompleteAndMarkForDeletion itself to complete the client-side
+ request.
+
+ @see CompleteAndMarkForDeletion
+ */
+ {
+ TInt r = iStatus.Int();
+ CompleteAndMarkForDeletion(r);
+ }
+
+EXPORT_C TInt CAsyncRequest::RunError(TInt aError)
+/**
+ Override CActive by completing the request with the
+ supplied error code and marking this object for deletion.
+ The default implementation of RunL cannot leave, but the
+ subclass may override it with a more complex implementation.
+
+ @param aError Error code with which aError left.
+ @return KErrNone, meaning do not propagate
+ the error to the active scheduler.
+ */
+ {
+ CompleteAndMarkForDeletion(aError);
+ return KErrNone;
+ }
+
+void CAsyncRequest::CancelCompleteAndMarkForDeletion()
+/**
+ Cancel this asynchronous request and complete the client
+ request with KErrCancel. On exit, this object has been
+ marked for deletion.
+ */
+ {
+ CompleteAndMarkForDeletion(KErrCancel);
+ }
+
+EXPORT_C void CAsyncRequest::CompleteAndMarkForDeletion(TInt aError)
+/**
+ Completes the client-side request associated with this
+ asynchronous request and marks this object for deletion.
+
+ If the error was because the client passed a bad descriptor then
+ panick the client instead of completing the request for consistency
+ with synchronous requests.
+
+ @param aError Error code with which the client request
+ will be completed.
+ */
+ {
+ if (aError == KErrBadDescriptor)
+ PanicClient(iMessagePtr2, ScsImpl::EScsClBadDesc);
+ else
+ iMessagePtr2.Complete(aError);
+ MarkForDeletion();
+ }
+
+void CAsyncRequest::MarkForDeletion()
+/**
+ Mark this outstanding request for deletion, so it is
+ cleaned up when the cleanup AO runs.
+ */
+ {
+ DoCleanup();
+ // The deletion is processed at priority CActive::EPriorityHigh,
+ // so should happen ahead of any pending or new requests.
+ CAsyncCallBack* acb = iSession->iServer.iAsyncCleanup;
+ acb->CallBack(); // no effect if already queued
+ iSession = NULL; // mark for deletion
+ }
+
+EXPORT_C void CAsyncRequest::DoCleanup()
+/**
+ This virtual function is called whenever the SCS needs to cancel an operation.
+
+ If the asynchronous request implementation ALWAYS has an internal request active
+ for the duration of the client request, then this default implementation can be used, which
+ simply calls CActive::Cancel which will call the derived classe's DoCancel (if, and only if
+ the object IsActive).
+
+ A more complex case is where the asynchronous requests may enter an internal queue where
+ the client request is (obviously still active), but the derived class has not outstanding request.
+ In this case the default implementation will cause a HANG, because Cancel will not call DoCancel if
+ the object is not active...
+
+ In the generic case, the derived class should provide an overload for the Cleanup method.
+ This function should call Cancel to cancel any outstanding operation, then perform whatever other
+ cleanup is required to cleanup the request (closing handles, removing from queues etc).
+ The framework will then complete the client request.
+
+ nb. The destructor of the CAsyncRequest may not run until sometime after the client request has been
+ completed.
+ */
+{
+ Cancel();
+}
+