diff -r 000000000000 -r bde4ae8d615e os/security/authorisation/userpromptservice/server/source/upsserver/upspolicycachehandle.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/os/security/authorisation/userpromptservice/server/source/upsserver/upspolicycachehandle.cpp Fri Jun 15 03:10:57 2012 +0200 @@ -0,0 +1,283 @@ +/* +* 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: +* Implements the UPS database handle manager. See class and function +* definitions for more information. +* +*/ + + +/** + @file +*/ +#include +#include "upscommon.h" +#include "policycache.h" +#include "upspolicycachehandle.h" + +namespace UserPromptService +{ + +NONSHARABLE_CLASS(CPolicyCacheContainer) : public CBase + { +public: + static CPolicyCacheContainer *NewL(RFs &aFs); + + void IncrementReferenceCount(); + void DecrementReferenceCount(); + inline CPolicyCache *PolicyCache(); + + TInt ReferenceCount() const; + + void NotifyOnRef1(TRequestStatus &aStatus); + void CancelNotifyOnRef1(); + +private: + void ConstructL(RFs &aFs); + ~CPolicyCacheContainer(); + + TInt iReferenceCount; + CPolicyCache *iPolicyCache; + TRequestStatus *iClientRequest; + }; + +inline CPolicyCache *CPolicyCacheContainer::PolicyCache() + { + ASSERT(iPolicyCache != 0); + return iPolicyCache; + } + +inline TInt CPolicyCacheContainer::ReferenceCount() const + { + return iReferenceCount; + } + +RPolicyCacheCountedHandle::RPolicyCacheCountedHandle(RFs &aFs) + : iFs(aFs), iContainer(0) + { + } + +RPolicyCacheCountedHandle::RPolicyCacheCountedHandle(RPolicyCacheCountedHandle &aPolicyCacheManager) + : iFs(aPolicyCacheManager.iFs), iContainer(0) + { + *this = aPolicyCacheManager; + } + +RPolicyCacheCountedHandle &RPolicyCacheCountedHandle::operator=(const RPolicyCacheCountedHandle &aRhs) + { + if(this == &aRhs) return *this; + + Release(); + + if(aRhs.iContainer) + { + iContainer = aRhs.iContainer; + iContainer->IncrementReferenceCount(); + } + + return *this; + } + +RPolicyCacheCountedHandle::~RPolicyCacheCountedHandle() +/** + Destructor - make sure cache container is released. +*/ + { + Release(); + } + +void RPolicyCacheCountedHandle::OpenL() +/** + Create/Open a new policy cache. If this manager is already opened then the existing cache is + released first (see Release()). +*/ + { + // First release any existing container/policy cache. + Release(); + + // Now create a new one + iContainer = CPolicyCacheContainer::NewL(iFs); + } + +void RPolicyCacheCountedHandle::Release() +/** + Release the current policy cache container. If this decreases its reference count to 0, it will be + deleted. +*/ + { + if(iContainer) + { + iContainer->DecrementReferenceCount(); + iContainer = 0; + } + } + +TBool RPolicyCacheCountedHandle::IsOpen() const + { + return iContainer != 0; + } + +CPolicyCache *RPolicyCacheCountedHandle::operator->() +/** + Returns the CPolicyCache ptr so -> can be used to call policy cache functions. + + If the class is not already open, then we will attempt to open ourself using OpenL(). + + Note that this operator can leave... +*/ + { + if(iContainer == 0) + { + OpenL(); + ASSERT(iContainer); + } + return iContainer->PolicyCache(); + } + +void RPolicyCacheCountedHandle::NotifyOnRef1(TRequestStatus &aStatus) +/** + Register for notifcation when the underlying CPolicyCacheContainer reference + count reaches 1, presumably when the client holds the only reference. + + Only one client is allowed to register against a single CPolicyCacheContainer. +*/ + { + if((iContainer == 0) || (iContainer->ReferenceCount() <= 1)) + { + // No container or ref count is 1, so complete now. + TRequestStatus *rs = &aStatus; + *rs = KRequestPending; + User::RequestComplete(rs, KErrNone); + return; + } + iContainer->NotifyOnRef1(aStatus); + } + +void RPolicyCacheCountedHandle::CancelNotifyOnRef1() +/** + Cancel the call to NotifyOnRef1. The request will be completed immediately. +*/ + { + if(!iContainer) + { + return; + } + iContainer->CancelNotifyOnRef1(); + } + +CPolicyCacheContainer *CPolicyCacheContainer::NewL(RFs &aFs) +/** + Create a CPolicyCacheContainer containing a CPolicyCache with a reference count of 1. +*/ + { + CPolicyCacheContainer *self = new(ELeave) CPolicyCacheContainer(); + CleanupStack::PushL(self); + self->ConstructL(aFs); + CleanupStack::Pop(self); + return self; + } + +void CPolicyCacheContainer::IncrementReferenceCount() +/** + Increment the reference count. +*/ + { + ASSERT(iReferenceCount > 0); + ++iReferenceCount; + } + +void CPolicyCacheContainer::DecrementReferenceCount() +/** + Decrement the reference count and delete self if it reaches 0. +*/ + { + --iReferenceCount; + if(iReferenceCount <= 1) + { + if(iClientRequest && iClientRequest->Int() == KRequestPending) + { + User::RequestComplete(iClientRequest, KErrNone); + } + } + + if(iReferenceCount <= 0) + { + delete this; + } + } + +void CPolicyCacheContainer::NotifyOnRef1(TRequestStatus &aStatus) +/** + Register for notifcation when the reference count reduces to 1, presumably + when the client holds the only reference. + + Only one client is allowed to register against a single CPolicyCacheContainer. +*/ + { + BULLSEYE_OFF + if(iClientRequest != 0) + { + TRequestStatus *rs = &aStatus; + *rs = KRequestPending; + User::RequestComplete(rs, KErrServerBusy); + return; + } + BULLSEYE_RESTORE + + // Initialise client request + iClientRequest = &aStatus; + *iClientRequest = KRequestPending; + + // Are we already at ref 1? + if(iReferenceCount <= 1) + { + User::RequestComplete(iClientRequest, KErrNone); + } + } + +void CPolicyCacheContainer::CancelNotifyOnRef1() +/** + Cancel the previous call to NotifyOnRef1. +*/ + { + if((iClientRequest != 0) && (iClientRequest->Int() == KRequestPending)) + { + User::RequestComplete(iClientRequest, KErrCancel); + return; + } + } + +void CPolicyCacheContainer::ConstructL(RFs &aFs) + { + _LIT(KPolicyDir,"\\private\\10283558\\policies\\"); + iPolicyCache = CPolicyCache::NewL(aFs, KPolicyDir()); + iReferenceCount = 1; + } + +CPolicyCacheContainer::~CPolicyCacheContainer() + { + delete iPolicyCache; + iPolicyCache = 0; + + if(iClientRequest && iClientRequest->Int() == KRequestPending) + { + User::RequestComplete(iClientRequest, KErrNone); + iClientRequest = 0; + } + } + +} // End of UserPromptService namespace + +// End of file +