UDK 3.2.7 C/C++ API Reference
salhelper/singletonref.hxx
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 /*************************************************************************
00003  *
00004  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
00005  *
00006  * Copyright 2000, 2010 Oracle and/or its affiliates.
00007  *
00008  * OpenOffice.org - a multi-platform office productivity suite
00009  *
00010  * This file is part of OpenOffice.org.
00011  *
00012  * OpenOffice.org is free software: you can redistribute it and/or modify
00013  * it under the terms of the GNU Lesser General Public License version 3
00014  * only, as published by the Free Software Foundation.
00015  *
00016  * OpenOffice.org is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU Lesser General Public License version 3 for more details
00020  * (a copy is included in the LICENSE file that accompanied this code).
00021  *
00022  * You should have received a copy of the GNU Lesser General Public License
00023  * version 3 along with OpenOffice.org.  If not, see
00024  * <http://www.openoffice.org/license.html>
00025  * for a copy of the LGPLv3 License.
00026  *
00027  ************************************************************************/
00028 
00029 #ifndef _SALHELPER_SINGLETONREF_HXX_
00030 #define _SALHELPER_SINGLETONREF_HXX_
00031 
00032 //_______________________________________________
00033 // includes
00034 
00035 #include <osl/mutex.hxx>
00036 #include "rtl/instance.hxx"
00037 #include "osl/diagnose.h"
00038 #include "osl/getglobalmutex.hxx"
00039 
00040 //_______________________________________________
00041 // namespace
00042 
00043 namespace salhelper{
00044 
00045 //_______________________________________________
00046 // definitions
00047 
00080 template< class SingletonClass >
00081 class SingletonRef
00082 {
00083     //-------------------------------------------
00084     // member
00085 
00086     private :
00087 
00089         static SingletonClass* m_pInstance;
00090 
00092         static sal_Int32 m_nRef;
00093 
00094     //-------------------------------------------
00095     // interface
00096 
00097     public :
00098 
00099         //---------------------------------------
00100 
00108         SingletonRef()
00109         {
00110             // GLOBAL SAFE ->
00111             ::osl::MutexGuard aLock(SingletonRef::ownStaticLock());
00112 
00113             // must be increased before(!) the check is done.
00114             // Otherwhise this check can fail inside the same thread ...
00115             ++m_nRef;
00116             if (m_nRef == 1)
00117                 m_pInstance = new SingletonClass();
00118 
00119             OSL_ENSURE(m_nRef>0 && m_pInstance, "Race? Ref count of singleton >0, but instance is NULL!");
00120             // <- GLOBAL SAFE
00121         }
00122 
00123         //---------------------------------------
00124 
00132         ~SingletonRef()
00133         {
00134             // GLOBAL SAFE ->
00135             ::osl::MutexGuard aLock(SingletonRef::ownStaticLock());
00136 
00137             // must be decreased before(!) the check is done.
00138             // Otherwhise this check can fail inside the same thread ...
00139             --m_nRef;
00140             if (m_nRef == 0)
00141             {
00142                 delete m_pInstance;
00143                 m_pInstance = 0;
00144             }
00145             // <- GLOBAL SAFE
00146         }
00147 
00148         //---------------------------------------
00149 
00152         SingletonClass* operator->() const
00153         {
00154             // GLOBAL SAFE ->
00155             ::osl::MutexGuard aLock(SingletonRef::ownStaticLock());
00156             return m_pInstance;
00157             // <- GLOBAL SAFE
00158         }
00159 
00160         //---------------------------------------
00161 
00164         SingletonClass& operator*() const
00165         {
00166             // GLOBAL SAFE ->
00167             ::osl::MutexGuard aLock(SingletonRef::ownStaticLock());
00168             return *m_pInstance;
00169             // <- GLOBAL SAFE
00170         }
00171 
00172     //-------------------------------------------
00173     // helper
00174 
00175     private :
00176 
00177         //---------------------------------------
00178 
00185         struct SingletonLockInit
00186         {
00187             ::osl::Mutex* operator()()
00188             {
00189                 static ::osl::Mutex aInstance;
00190                 return &aInstance;
00191             }
00192         };
00193 
00194         ::osl::Mutex& ownStaticLock() const
00195         {
00196             return *rtl_Instance< ::osl::Mutex,
00197                                   SingletonLockInit,
00198                                   ::osl::MutexGuard,
00199                                   ::osl::GetGlobalMutex >::create(SingletonLockInit(), ::osl::GetGlobalMutex());
00200         }
00201 };
00202 
00203 template< class SingletonClass >
00204 SingletonClass* SingletonRef< SingletonClass >::m_pInstance = 0;
00205 
00206 template< class SingletonClass >
00207 sal_Int32 SingletonRef< SingletonClass >::m_nRef = 0;
00208 
00209 } // namespace salhelper
00210 
00211 #endif // _SALHELPER_SINGLETONREF_HXX_
00212 
00213 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines