diff -r 000000000000 -r 4e91876724a2 photosgallery/common/src/glxsingletonstore.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/photosgallery/common/src/glxsingletonstore.cpp Thu Dec 17 08:45:44 2009 +0200 @@ -0,0 +1,149 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "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: Store for singletons +* +*/ + + + + +// INCLUDE FILES +#include "glxsingletonstore.h" + +#include + +// ----------------------------------------------------------------------------- +// Constructor +// ----------------------------------------------------------------------------- +// +CGlxSingletonStore::CGlxSingletonStore() + { + GLX_LOG_INFO("CGlxSingletonStore::CGlxSingletonStore"); + } + +// ----------------------------------------------------------------------------- +// return new instance +// ----------------------------------------------------------------------------- +// +EXPORT_C CGlxSingletonStore* CGlxSingletonStore::InstanceLC() + { + CGlxSingletonStore* store = reinterpret_cast(Dll::Tls()); + + // Create new object, if one has not been created previously + if ( !store ) + { + store = new (ELeave) CGlxSingletonStore; + + // Store in tls pointer + Dll::SetTls( reinterpret_cast(store)); + } + + // Push to cleanup stack - will make sure tls pointer is cleared if + // something leaves + CleanupStack::PushL( TCleanupItem(&Cleanup, store) ); + + return store; + } + +// ----------------------------------------------------------------------------- +// Cleanup function +// ----------------------------------------------------------------------------- +// +void CGlxSingletonStore::Cleanup( TAny* /*aStore*/ ) + { + // In case of one singleton owning another there can be nested calls to + // CGlxSingletonStore::InstanceL, and so multiple Cleanup items on the + // stack to delete the store. + // Get the store pointer from TLS to ensure it hasn't already been deleted + CGlxSingletonStore* obj + = reinterpret_cast( Dll::Tls() ); + + // Delete the object if instance was just created, and singleton + // was _not_ successfully added + if ( obj && obj->iSingletons.Count() == 0 ) + { + delete obj; + } + + GLX_LOG_WARNING("Singleton factory function has (probably) left"); + } + +// ----------------------------------------------------------------------------- +// Destructor +// ----------------------------------------------------------------------------- +// +EXPORT_C CGlxSingletonStore::~CGlxSingletonStore() + { + GLX_LOG_INFO("CGlxSingletonStore::~CGlxSingletonStore"); + + // Delete remaining objects, if any + TInt count = iSingletons.Count(); + for (TInt i = 0; i < count; i++) + { + delete iSingletons[i].iObject; + } + + // Close the singletons array + iSingletons.Close(); + + // Clear tls pointer + Dll::SetTls( NULL ); + } + +// ----------------------------------------------------------------------------- +// Decrement reference count, and potentially delete object(s) +// ----------------------------------------------------------------------------- +// +EXPORT_C void CGlxSingletonStore::Close(CBase* aObj) + { + CGlxSingletonStore* store = reinterpret_cast(Dll::Tls()); + if ( store ) + { + // Find an object by type + TInt count = store->iSingletons.Count(); + TInt i = 0; + while ( i < count ) + { + TSingleton& singleton = store->iSingletons[i]; + if ( aObj == singleton.iObject ) + { + // Found an existing object of type T + // Remove reference + singleton.iReferenceCount--; + GLX_LOG_INFO2("CGlxSingletonStore::Close, Ref count %d, %x", singleton.iReferenceCount, singleton.iObject); + + // Delete object if no more references + if ( !singleton.iReferenceCount ) + { + store->iSingletons.Remove(i); + + // Delete store object if last singleton + if ( store->iSingletons.Count() == 0 ) + { + // CGlxSingletonStore destructor will clean up DLL's TLS pointer + delete store; + } + + delete aObj; + } + break; + } + i++; + } + } + else + { + GLX_LOG_ERROR("CGlxSingletonStore::Close - Too many calls to Close()"); + } + }