photosgallery/common/src/glxsingletonstore.cpp
changeset 0 4e91876724a2
--- /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 <glxlog.h>
+
+// -----------------------------------------------------------------------------
+// Constructor
+// -----------------------------------------------------------------------------
+//
+CGlxSingletonStore::CGlxSingletonStore()
+	{
+    GLX_LOG_INFO("CGlxSingletonStore::CGlxSingletonStore");
+	}
+
+// -----------------------------------------------------------------------------
+// return new instance
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CGlxSingletonStore* CGlxSingletonStore::InstanceLC()
+	{
+    CGlxSingletonStore* store = reinterpret_cast<CGlxSingletonStore*>(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<TAny*>(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<CGlxSingletonStore*>( 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<CGlxSingletonStore*>(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()");
+        }
+    }