diff --git a/xmlsecurity/source/xmlsec/diagnose.cxx b/xmlsecurity/source/xmlsec/diagnose.cxx index 9c0fb60..9c3638b 100644 --- a/xmlsecurity/source/xmlsec/diagnose.cxx +++ b/xmlsecurity/source/xmlsec/diagnose.cxx @@ -34,8 +34,7 @@ namespace xmlsecurity { -struct UseDiagnose : public rtl::StaticWithInit< - const bool, UseDiagnose> +struct UseDiagnose : public rtl::StaticWithInit< bool, UseDiagnose> { bool operator () () const { diff --git a/binfilter/bf_svtools/source/numbers/svt_zformat.cxx b/binfilter/bf_svtools/source/numbers/svt_zformat.cxx index 5518a81..fcba7cb 100644 --- a/binfilter/bf_svtools/source/numbers/svt_zformat.cxx +++ b/binfilter/bf_svtools/source/numbers/svt_zformat.cxx @@ -61,9 +61,9 @@ namespace binfilter namespace { struct Gregorian - : public rtl::StaticWithInit { - const ::rtl::OUString operator () () { - return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("gregorian")); + : public rtl::StaticWithInit { + const rtl::OUString operator () () { + return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("gregorian")); } }; } diff --git a/sd/source/ui/slidesorter/cache/SlsCacheConfiguration.cxx b/sd/source/ui/slidesorter/cache/SlsCacheConfiguration.cxx index 8d342cb..89f0b7c 100644 --- a/sd/source/ui/slidesorter/cache/SlsCacheConfiguration.cxx +++ b/sd/source/ui/slidesorter/cache/SlsCacheConfiguration.cxx @@ -31,6 +31,7 @@ #include "SlsCacheConfiguration.hxx" #include +#include #include #include @@ -43,33 +44,38 @@ using namespace ::com::sun::star::uno; namespace sd { namespace slidesorter { namespace cache { -::boost::shared_ptr CacheConfiguration::mpInstance; +namespace +{ + typedef ::boost::shared_ptr CacheConfigSharedPtr; + class theInstance : + public rtl::Static {}; +} + ::boost::weak_ptr CacheConfiguration::mpWeakInstance; Timer CacheConfiguration::maReleaseTimer; - - ::boost::shared_ptr CacheConfiguration::Instance (void) { SolarMutexGuard aSolarGuard; - if (mpInstance.get() == NULL) + CacheConfigSharedPtr &rInstancePtr = theInstance::get(); + if (rInstancePtr.get() == NULL) { // Maybe somebody else kept a previously created instance alive. if ( ! mpWeakInstance.expired()) - mpInstance = ::boost::shared_ptr(mpWeakInstance); - if (mpInstance.get() == NULL) + rInstancePtr = ::boost::shared_ptr(mpWeakInstance); + if (rInstancePtr.get() == NULL) { // We have to create a new instance. - mpInstance.reset(new CacheConfiguration()); - mpWeakInstance = mpInstance; + rInstancePtr.reset(new CacheConfiguration()); + mpWeakInstance = rInstancePtr; // Prepare to release this instance in the near future. maReleaseTimer.SetTimeoutHdl( - LINK(mpInstance.get(),CacheConfiguration,TimerCallback)); + LINK(rInstancePtr.get(),CacheConfiguration,TimerCallback)); maReleaseTimer.SetTimeout(5000 /* 5s */); maReleaseTimer.Start(); } } - return mpInstance; + return rInstancePtr; } @@ -167,8 +173,9 @@ Any CacheConfiguration::GetValue (const ::rtl::OUString& rName) IMPL_LINK(CacheConfiguration,TimerCallback, Timer*,EMPTYARG) { + CacheConfigSharedPtr &rInstancePtr = theInstance::get(); // Release out reference to the instance. - mpInstance.reset(); + rInstancePtr.reset(); return 0; } diff --git a/sd/source/ui/slidesorter/cache/SlsCacheConfiguration.hxx b/sd/source/ui/slidesorter/cache/SlsCacheConfiguration.hxx index 27d7888..6e7174b 100644 --- a/sd/source/ui/slidesorter/cache/SlsCacheConfiguration.hxx +++ b/sd/source/ui/slidesorter/cache/SlsCacheConfiguration.hxx @@ -56,7 +56,6 @@ public: ::com::sun::star::uno::Any GetValue (const ::rtl::OUString& rName); private: - static ::boost::shared_ptr mpInstance; /** When a caller holds a reference after we have released ours we use this weak pointer to avoid creating a new instance. */ diff --git a/configmgr/source/components.cxx b/configmgr/source/components.cxx index 3896fbe..61a751d 100644 --- a/configmgr/source/components.cxx +++ b/configmgr/source/components.cxx @@ -57,6 +57,7 @@ #include "rtl/textenc.h" #include "rtl/ustring.h" #include "rtl/ustring.hxx" +#include "rtl/instance.hxx" #include "sal/types.h" #include "salhelper/simplereferenceobject.hxx" @@ -150,9 +151,6 @@ bool canRemoveFromLayer(int layer, rtl::Reference< Node > const & node) { } } -static bool singletonCreated = false; -static Components * singleton = 0; - } class Components::WriteThread: @@ -217,23 +215,19 @@ void Components::WriteThread::run() { reference_->clear(); } +class theComponentsSingleton : + public rtl::StaticWithArg< + Components, + css::uno::Reference< css::uno::XComponentContext >, + theComponentsSingleton> +{ +}; + Components & Components::getSingleton( css::uno::Reference< css::uno::XComponentContext > const & context) { OSL_ASSERT(context.is()); - if (!singletonCreated) { - static Components theSingleton(context); - singleton = &theSingleton; - singletonCreated = true; - } - if (singleton == 0) { - throw css::uno::RuntimeException( - rtl::OUString( - RTL_CONSTASCII_USTRINGPARAM( - "configmgr no Components singleton")), - css::uno::Reference< css::uno::XInterface >()); - } - return *singleton; + return theComponentsSingleton::get(context); } bool Components::allLocales(rtl::OUString const & locale) { @@ -514,6 +508,7 @@ Components::Components( css::uno::Reference< css::uno::XComponentContext > const & context): context_(context) { + fprintf(stderr, "Components::Components ctor %p\n", this); lock_ = lock(); OSL_ASSERT(context.is()); @@ -593,6 +588,7 @@ Components::Components( Components::~Components() { + fprintf(stderr, "Components::Components dtor %p\n", this); flushModifications(); } diff --git a/configmgr/source/components.hxx b/configmgr/source/components.hxx index 9d216e1..26af3fb 100644 --- a/configmgr/source/components.hxx +++ b/configmgr/source/components.hxx @@ -123,12 +123,13 @@ private: typedef void FileParser( rtl::OUString const &, int, Data &, Partial const *, Modifications *, Additions *); - +public: Components( com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > const & context); ~Components(); +private: void parseFileLeniently( FileParser * parseFile, rtl::OUString const & url, int layer, diff --git a/configmgr/source/rootaccess.cxx b/configmgr/source/rootaccess.cxx index ef5982e..8d4e309 100644 --- a/configmgr/source/rootaccess.cxx +++ b/configmgr/source/rootaccess.cxx @@ -79,6 +79,7 @@ RootAccess::RootAccess( Access(components), pathRepresentation_(pathRepresentation), locale_(locale), update_(update) { + fprintf(stderr, "RootAccess::RootAccess ctor %p\n", this); lock_ = lock(); } @@ -130,8 +131,10 @@ bool RootAccess::isUpdate() const { return update_; } -RootAccess::~RootAccess() { +RootAccess::~RootAccess() +{ osl::MutexGuard g(*lock_); + fprintf(stderr, "RootAccess::RootAccess dtor %p\n", this); getComponents().removeRootAccess(this); } diff --git a/desktop/source/deployment/gui/dp_gui_dialog2.cxx b/desktop/source/deployment/gui/dp_gui_dialog2.cxx index 7aa8dec..020ef14 100644 --- a/desktop/source/deployment/gui/dp_gui_dialog2.cxx +++ b/desktop/source/deployment/gui/dp_gui_dialog2.cxx @@ -100,7 +100,7 @@ namespace dp_gui { #define PROGRESS_HEIGHT 14 //------------------------------------------------------------------------------ -struct StrAllFiles : public rtl::StaticWithInit< const OUString, StrAllFiles > +struct StrAllFiles : public rtl::StaticWithInit< OUString, StrAllFiles > { const OUString operator () () { const SolarMutexGuard guard; diff --git a/desktop/source/deployment/gui/dp_gui_shared.hxx b/desktop/source/deployment/gui/dp_gui_shared.hxx index dcee286..a70686a 100644 --- a/desktop/source/deployment/gui/dp_gui_shared.hxx +++ b/desktop/source/deployment/gui/dp_gui_shared.hxx @@ -45,7 +45,7 @@ struct DeploymentGuiResMgr : } }; -struct BrandName : public ::rtl::StaticWithInit { +struct BrandName : public ::rtl::StaticWithInit< ::rtl::OUString, BrandName > { const ::rtl::OUString operator () () { return ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTNAME ).get< ::rtl::OUString >(); diff --git a/desktop/source/deployment/inc/dp_dependencies.hxx b/desktop/source/deployment/inc/dp_dependencies.hxx index f31d5f3..b0df05f 100644 --- a/desktop/source/deployment/inc/dp_dependencies.hxx +++ b/desktop/source/deployment/inc/dp_dependencies.hxx @@ -45,7 +45,7 @@ namespace rtl { class OUString; } namespace dp_misc { -struct BrandName : public ::rtl::StaticWithInit { +struct BrandName : public ::rtl::StaticWithInit< ::rtl::OUString, BrandName > { const ::rtl::OUString operator () () { return ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTNAME ).get< ::rtl::OUString >(); diff --git a/desktop/source/deployment/inc/dp_resource.h b/desktop/source/deployment/inc/dp_resource.h index bd3a4fa..212ed5a 100755 --- a/desktop/source/deployment/inc/dp_resource.h +++ b/desktop/source/deployment/inc/dp_resource.h @@ -47,7 +47,7 @@ DESKTOP_DEPLOYMENTMISC_DLLPUBLIC String getResourceString( sal_uInt16 id ); template struct StaticResourceString : - public ::rtl::StaticWithInit { + public ::rtl::StaticWithInit< ::rtl::OUString, Unique > { const ::rtl::OUString operator () () { return getResourceString(id); } }; diff --git a/desktop/source/deployment/inc/dp_ucb.h b/desktop/source/deployment/inc/dp_ucb.h index c2fcdcd..2835f15 100755 --- a/desktop/source/deployment/inc/dp_ucb.h +++ b/desktop/source/deployment/inc/dp_ucb.h @@ -45,7 +45,7 @@ namespace css = ::com::sun::star; namespace dp_misc { struct DESKTOP_DEPLOYMENTMISC_DLLPUBLIC StrTitle : - public rtl::StaticWithInit + public rtl::StaticWithInit { const rtl::OUString operator () (); }; diff --git a/desktop/source/deployment/misc/dp_misc.cxx b/desktop/source/deployment/misc/dp_misc.cxx index 78696a4..b626141 100644 --- a/desktop/source/deployment/misc/dp_misc.cxx +++ b/desktop/source/deployment/misc/dp_misc.cxx @@ -79,7 +79,7 @@ namespace dp_misc { namespace { struct UnoRc : public rtl::StaticWithInit< - const boost::shared_ptr, UnoRc> { + boost::shared_ptr, UnoRc> { const boost::shared_ptr operator () () { OUString unorc( RTL_CONSTASCII_USTRINGPARAM( "$OOO_BASE_DIR/program/" SAL_CONFIGFILE("uno")) ); @@ -91,7 +91,7 @@ struct UnoRc : public rtl::StaticWithInit< } }; -struct OfficePipeId : public rtl::StaticWithInit { +struct OfficePipeId : public rtl::StaticWithInit { const OUString operator () (); }; diff --git a/desktop/source/deployment/misc/dp_platform.cxx b/desktop/source/deployment/misc/dp_platform.cxx index 6217be2..515b848 100644 --- a/desktop/source/deployment/misc/dp_platform.cxx +++ b/desktop/source/deployment/misc/dp_platform.cxx @@ -91,7 +91,7 @@ namespace dp_misc namespace { struct StrOperatingSystem : - public rtl::StaticWithInit { + public rtl::StaticWithInit { const OUString operator () () { OUString os( RTL_CONSTASCII_USTRINGPARAM("$_OS") ); ::rtl::Bootstrap::expandMacros( os ); @@ -100,7 +100,7 @@ namespace }; struct StrCPU : - public rtl::StaticWithInit { + public rtl::StaticWithInit { const OUString operator () () { OUString arch( RTL_CONSTASCII_USTRINGPARAM("$_ARCH") ); ::rtl::Bootstrap::expandMacros( arch ); @@ -110,7 +110,7 @@ namespace struct StrPlatform : public rtl::StaticWithInit< - const OUString, StrPlatform> { + OUString, StrPlatform> { const OUString operator () () { ::rtl::OUStringBuffer buf; buf.append( StrOperatingSystem::get() ); diff --git a/desktop/source/deployment/misc/dp_resource.cxx b/desktop/source/deployment/misc/dp_resource.cxx index c8c57ac..ad7a9e0 100644 --- a/desktop/source/deployment/misc/dp_resource.cxx +++ b/desktop/source/deployment/misc/dp_resource.cxx @@ -46,7 +46,7 @@ namespace dp_misc { namespace { struct OfficeLocale : - public rtl::StaticWithInit { + public rtl::StaticWithInit { const OUString operator () () { OUString slang; if (! (::utl::ConfigManager::GetDirectConfigProperty( diff --git a/desktop/source/pkgchk/unopkg/unopkg_cmdenv.cxx b/desktop/source/pkgchk/unopkg/unopkg_cmdenv.cxx index f3d68a0..c8007cf 100644 --- a/desktop/source/pkgchk/unopkg/unopkg_cmdenv.cxx +++ b/desktop/source/pkgchk/unopkg/unopkg_cmdenv.cxx @@ -67,7 +67,7 @@ namespace { //============================================================================== struct OfficeLocale : - public rtl::StaticWithInit { + public rtl::StaticWithInit { const lang::Locale operator () () { OUString slang; if (! (::utl::ConfigManager::GetDirectConfigProperty( diff --git a/desktop/source/pkgchk/unopkg/unopkg_misc.cxx b/desktop/source/pkgchk/unopkg/unopkg_misc.cxx index 1a87c92..7db2372 100644 --- a/desktop/source/pkgchk/unopkg/unopkg_misc.cxx +++ b/desktop/source/pkgchk/unopkg/unopkg_misc.cxx @@ -180,7 +180,7 @@ bool readArgument( namespace { struct ExecutableDir : public rtl::StaticWithInit< - const OUString, ExecutableDir> { + OUString, ExecutableDir> { const OUString operator () () { OUString path; if (osl_getExecutableFile( &path.pData ) != osl_Process_E_None) { @@ -191,7 +191,7 @@ struct ExecutableDir : public rtl::StaticWithInit< } }; struct ProcessWorkingDir : public rtl::StaticWithInit< - const OUString, ProcessWorkingDir> { + OUString, ProcessWorkingDir> { const OUString operator () () { OUString workingDir; tools::getProcessWorkingDir(workingDir); diff --git a/desktop/source/pkgchk/unopkg/unopkg_shared.h b/desktop/source/pkgchk/unopkg/unopkg_shared.h index cc25e93..ddad731 100755 --- a/desktop/source/pkgchk/unopkg/unopkg_shared.h +++ b/desktop/source/pkgchk/unopkg/unopkg_shared.h @@ -56,7 +56,7 @@ namespace unopkg { struct OfficeLocale : - public rtl::StaticWithInit { + public rtl::StaticWithInit { const css::lang::Locale operator () () { ::rtl::OUString slang; if (! (::utl::ConfigManager::GetDirectConfigProperty( diff --git a/sfx2/source/toolbox/imgmgr.cxx b/sfx2/source/toolbox/imgmgr.cxx index cb4eefe..b3af92d 100644 --- a/sfx2/source/toolbox/imgmgr.cxx +++ b/sfx2/source/toolbox/imgmgr.cxx @@ -47,6 +47,7 @@ #include #include #include +#include #include @@ -80,27 +81,38 @@ public: ~SfxImageManager_Impl(); }; +namespace +{ + typedef boost::unordered_map< SfxModule*, boost::shared_ptr > SfxImageManagerImplMap; + + class theImageManagerImplMap : + public rtl::Static {}; + + class theGlobalImageManager : + public rtl::StaticWithArg {}; +} + static SfxImageManager_Impl* GetImageManager( SfxModule* pModule ) { SolarMutexGuard aGuard; if ( pModule == 0 ) { - static SfxImageManager_Impl aGlobalImageManager(0); - return &aGlobalImageManager; + return &theGlobalImageManager::get(NULL); } else { - typedef boost::unordered_map< SfxModule*, boost::shared_ptr > SfxImageManagerImplMap; - static SfxImageManagerImplMap m_ImageManager_ImplMap; + SfxImageManagerImplMap &rImageManager_ImplMap = + theImageManagerImplMap::get(); SfxImageManager_Impl* pImpl( 0 ); - SfxImageManagerImplMap::const_iterator pIter = m_ImageManager_ImplMap.find(pModule); - if ( pIter != m_ImageManager_ImplMap.end() ) + SfxImageManagerImplMap::const_iterator pIter = rImageManager_ImplMap.find(pModule); + if ( pIter != rImageManager_ImplMap.end() ) pImpl = pIter->second.get(); else { - m_ImageManager_ImplMap[pModule].reset(new SfxImageManager_Impl(pModule)); - pImpl = m_ImageManager_ImplMap[pModule].get(); + rImageManager_ImplMap[pModule].reset(new SfxImageManager_Impl(pModule)); + pImpl = rImageManager_ImplMap[pModule].get(); } return pImpl; } @@ -290,21 +302,28 @@ SfxImageManager::~SfxImageManager() //------------------------------------------------------------------------- +namespace +{ + typedef boost::unordered_map< SfxModule*, boost::shared_ptr > SfxImageManagerMap; + + class theImageManagerMap : + public rtl::Static {}; +} + SfxImageManager* SfxImageManager::GetImageManager( SfxModule* pModule ) { SolarMutexGuard aGuard; SfxImageManager* pSfxImageManager(0); - typedef boost::unordered_map< SfxModule*, boost::shared_ptr > SfxImageManagerMap; - static SfxImageManagerMap m_ImageManagerMap; + SfxImageManagerMap &rImageManagerMap = theImageManagerMap::get(); - SfxImageManagerMap::const_iterator pIter = m_ImageManagerMap.find(pModule); - if ( pIter != m_ImageManagerMap.end() ) + SfxImageManagerMap::const_iterator pIter = rImageManagerMap.find(pModule); + if ( pIter != rImageManagerMap.end() ) pSfxImageManager = pIter->second.get(); else { - m_ImageManagerMap[pModule].reset(new SfxImageManager(pModule)); - pSfxImageManager = m_ImageManagerMap[pModule].get(); + rImageManagerMap[pModule].reset(new SfxImageManager(pModule)); + pSfxImageManager = rImageManagerMap[pModule].get(); } return pSfxImageManager; } diff --git a/svl/source/numbers/zformat.cxx b/svl/source/numbers/zformat.cxx index 1f8e8a5..82497b2 100644 --- a/svl/source/numbers/zformat.cxx +++ b/svl/source/numbers/zformat.cxx @@ -64,9 +64,9 @@ using ::rtl::OUStringBuffer; namespace { struct Gregorian - : public rtl::StaticWithInit { - const ::rtl::OUString operator () () { - return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("gregorian")); + : public rtl::StaticWithInit { + const rtl::OUString operator () () { + return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("gregorian")); } }; diff --git a/tools/source/string/tstring.cxx b/tools/source/string/tstring.cxx index bf224e1..233eaa2 100644 --- a/tools/source/string/tstring.cxx +++ b/tools/source/string/tstring.cxx @@ -135,7 +135,7 @@ ByteString ByteString::CreateFromDouble( double d ) // ----------------------------------------------------------------------- -namespace { struct Empty : public rtl::Static< const ByteString, Empty> {}; } +namespace { struct Empty : public rtl::Static< ByteString, Empty> {}; } const ByteString& ByteString::EmptyString() { return Empty::get(); diff --git a/tools/source/string/tustring.cxx b/tools/source/string/tustring.cxx index c99d0a8..2824ebd 100644 --- a/tools/source/string/tustring.cxx +++ b/tools/source/string/tustring.cxx @@ -113,7 +113,7 @@ UniString UniString::CreateFromDouble( double d ) // ----------------------------------------------------------------------- -namespace { struct Empty : public rtl::Static< const UniString, Empty> {}; } +namespace { struct Empty : public rtl::Static< UniString, Empty> {}; } const UniString& UniString::EmptyString() { return Empty::get(); diff --git a/unotools/inc/unotools/fontcfg.hxx b/unotools/inc/unotools/fontcfg.hxx index 75b23a4..784d03e 100644 --- a/unotools/inc/unotools/fontcfg.hxx +++ b/unotools/inc/unotools/fontcfg.hxx @@ -93,8 +93,8 @@ class UNOTOOLS_DLLPUBLIC DefaultFontConfiguration rtl::OUString tryLocale( const com::sun::star::lang::Locale& rLocale, const rtl::OUString& rType ) const; - DefaultFontConfiguration(); public: + DefaultFontConfiguration(); ~DefaultFontConfiguration(); static DefaultFontConfiguration& get(); @@ -207,8 +207,8 @@ private: unsigned long getSubstType( const com::sun::star::uno::Reference< com::sun::star::container::XNameAccess > xFont, const rtl::OUString& rType ) const; void readLocaleSubst( const com::sun::star::lang::Locale& rLocale ) const; - FontSubstConfiguration(); public: + FontSubstConfiguration(); ~FontSubstConfiguration(); static FontSubstConfiguration& get(); diff --git a/unotools/source/config/fontcfg.cxx b/unotools/source/config/fontcfg.cxx index e8749cb..d3fa4d3 100644 --- a/unotools/source/config/fontcfg.cxx +++ b/unotools/source/config/fontcfg.cxx @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -96,14 +97,23 @@ static const char* getKeyType( int nKeyType ) } } +namespace +{ + class theDefaultFontConfiguration + : public rtl::Static + { + }; +} + DefaultFontConfiguration& DefaultFontConfiguration::get() { - static DefaultFontConfiguration aDefaultFontConfiguration; - return aDefaultFontConfiguration; + return theDefaultFontConfiguration::get(); } DefaultFontConfiguration::DefaultFontConfiguration() { + fprintf(stderr, "DefaultFontConfiguration::DefaultFontConfiguration ctor %p\n", this); try { // get service provider @@ -177,6 +187,7 @@ DefaultFontConfiguration::DefaultFontConfiguration() DefaultFontConfiguration::~DefaultFontConfiguration() { + fprintf(stderr, "DefaultFontConfiguration::DefaultFontConfiguration dtor %p\n", this); // release all nodes m_aConfig.clear(); // release top node @@ -370,10 +381,17 @@ OUString DefaultFontConfiguration::getUserInterfaceFont( const Locale& rLocale ) * FontSubstConfigItem::get */ +namespace +{ + class theFontSubstConfiguration + : public rtl::Static + { + }; +} + FontSubstConfiguration& FontSubstConfiguration::get() { - static FontSubstConfiguration aFontSubstConfiguration; - return aFontSubstConfiguration; + return theFontSubstConfiguration::get(); } /* @@ -383,6 +401,7 @@ FontSubstConfiguration& FontSubstConfiguration::get() FontSubstConfiguration::FontSubstConfiguration() : maSubstHash( 300 ) { + fprintf(stderr, "FontSubstConfiguration ctor %p\n", this); try { // get service provider @@ -460,6 +479,7 @@ FontSubstConfiguration::FontSubstConfiguration() : FontSubstConfiguration::~FontSubstConfiguration() { + fprintf(stderr, "FontSubstConfiguration dtor %p\n", this); // release config access m_xConfigAccess.clear(); // release config provider diff --git a/sal/inc/rtl/instance.hxx b/sal/inc/rtl/instance.hxx index 61f7ba0..bf7e8d5 100644 --- a/sal/inc/rtl/instance.hxx +++ b/sal/inc/rtl/instance.hxx @@ -32,6 +32,24 @@ #include "osl/doublecheckedlocking.h" #include "osl/getglobalmutex.hxx" +#include +#include + +namespace rtl +{ + class StaticInstanceController + { + public: + virtual void release() = 0; + }; +} + +extern "C" +{ + void SAL_CALL register_at_sal_main_exit(rtl::StaticInstanceController*); + void SAL_CALL deregister_at_sal_main_exit(rtl::StaticInstanceController*); +} + namespace { /** A non-broken version of the double-checked locking pattern. @@ -323,6 +341,31 @@ public: return p; } + static inline Inst * create(InstCtor aInstCtor, GuardCtor aGuardCtor, + const Data &rData) + { +#if defined _MSC_VER + static Inst * m_pInstance = 0; +#endif // _MSC_VER + Inst * p = m_pInstance; + if (!p) + { + Guard aGuard(aGuardCtor()); + p = m_pInstance; + if (!p) + { + p = aInstCtor(rData); + OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); + m_pInstance = p; + } + } + else + { + OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); + } + return p; + } + private: #if !defined _MSC_VER static Inst * m_pInstance; @@ -338,6 +381,58 @@ rtl_Instance< Inst, InstCtor, Guard, GuardCtor, Data, DataCtor >::m_pInstance = 0; #endif // _MSC_VER +//Under modern Linux with __cxa_atexit and __cxa_finalize local +//statics are destroyed in reverse order of completion of construction +//as expected and desired. Other platforms may have quirks where this +//doesn't happen with some extra help. +// +//This implementation helper: +// a) dynamically allocates the singleton +// b) on completion of its constructor registers it in a global list of +// singletons. All singletons created after main is entered are destroyed +// in reverse-order at the end of main. +// c) if the StaticInstanceControllerTmpl itself is destructed before the +// end of main, e.g. shared-library event then deregister itself from that +// list. This in practice will also include a few singletons constructed +// before main is entered. +template class StaticInstanceControllerTmpl : + public rtl::StaticInstanceController +{ +private: + //Using malloc/free and placement new in order not to touch our own + //allocators which would give a recursive dependency + void *m_pRaw; +public: + T* m_pObject; +public: + StaticInstanceControllerTmpl() + { + m_pRaw = malloc(sizeof(T)); + m_pObject = new (m_pRaw) T(); + register_at_sal_main_exit(this); + } + StaticInstanceControllerTmpl(const D &rData) + { + m_pRaw = malloc(sizeof(T)); + m_pObject = new (m_pRaw) T(rData); + register_at_sal_main_exit(this); + } + virtual void release() + { + if (m_pObject) + { + static_cast(m_pObject)->~T(); + free(m_pRaw); + m_pObject = NULL; + } + } + ~StaticInstanceControllerTmpl() + { + deregister_at_sal_main_exit(this); + release(); + } +}; + } namespace rtl { @@ -361,7 +456,7 @@ namespace rtl { using the outer class (the one that derives from this base class) */ -#if (__GNUC__ >= 4) +#if (__GNUC__ >= 40) template class Static { public: @@ -395,8 +490,116 @@ public: private: struct StaticInstance { T * operator () () { +#if 0 static T instance; return &instance; +#else + static StaticInstanceControllerTmpl aDeleter; + return aDeleter.m_pObject; +#endif + } + }; +}; +#endif + +/** Helper base class for a late-initialized (default-constructed) + static variable, implementing the double-checked locking pattern correctly. + + @derive + Derive from this class (common practice), e.g. +
+    struct MyStatic : public rtl::Static {};
+    ...
+    MyType & rStatic = MyStatic::get();
+    ...
+    
+ + @tplparam T + variable's type + @tplparam Unique + Implementation trick to make the inner static holder unique, + using the outer class + (the one that derives from this base class) +*/ +#if (__GNUC__ >= 40) +template +class StaticWithArg { +public: + /** Gets the static. Mutual exclusion is implied by a functional + -fthreadsafe-statics + + @return + static variable + */ + static T & get(const Data& rData) { + static T instance(rData); + return instance; + } + + /** Gets the static. Mutual exclusion is implied by a functional + -fthreadsafe-statics + + @return + static variable + */ + static T & get(Data& rData) { + static T instance(rData); + return instance; + } +}; +#else +template +class StaticWithArg { +public: + /** Gets the static. Mutual exclusion is performed using the + osl global mutex. + + @return + static variable + */ + static T & get(const Data& rData) { + return *rtl_Instance< + T, StaticInstanceWithArg, + ::osl::MutexGuard, ::osl::GetGlobalMutex, + Data >::create( StaticInstanceWithArg(), + ::osl::GetGlobalMutex(), + rData ); + } + + /** Gets the static. Mutual exclusion is performed using the + osl global mutex. + + @return + static variable + */ + static T & get(Data& rData) { + return *rtl_Instance< + T, StaticInstanceWithArg, + ::osl::MutexGuard, ::osl::GetGlobalMutex, + Data >::create( StaticInstanceWithArg(), + ::osl::GetGlobalMutex(), + rData ); + } +private: + struct StaticInstanceWithArg { + T * operator () (const Data& rData) { +#if 0 + static T instance(rData); + return &instance; +#else + static StaticInstanceControllerTmpl aDeleter(rData); + return aDeleter.m_pObject; +#endif + } + + T * operator () (Data& rData) { +#if 0 + static T instance(rData); + return &instance; +#else + static StaticInstanceControllerTmpl aDeleter(rData); + return aDeleter.m_pObject; +#endif } }; }; @@ -410,7 +613,7 @@ private: @tplparam InitAggregate initializer functor class */ -#if (__GNUC__ >= 4) +#if (__GNUC__ >= 40) template class StaticAggregate { public: @@ -475,7 +678,7 @@ public: Initializer functor's return type. Default is T (common practice). */ -#if (__GNUC__ >= 4) +#if (__GNUC__ >= 40) template class StaticWithInit { @@ -513,8 +716,13 @@ public: private: struct StaticInstanceWithInit { T * operator () ( Data d ) { +#if 0 static T instance(d); return &instance; +#else + static StaticInstanceControllerTmpl aDeleter(d); + return aDeleter.m_pObject; +#endif } }; }; diff --git a/sal/inc/sal/main.h b/sal/inc/sal/main.h index bf7a828..a1ea92e 100644 --- a/sal/inc/sal/main.h +++ b/sal/inc/sal/main.h @@ -40,13 +40,17 @@ extern "C" { void SAL_CALL sal_detail_initialize(int argc, char ** argv); void SAL_CALL sal_detail_deinitialize(); +void SAL_CALL sal_initialize_at_sal_main_exit(); +void SAL_CALL sal_deinitialize_at_sal_main_exit(); #define SAL_MAIN_WITH_ARGS_IMPL \ int SAL_CALL main(int argc, char ** argv) \ { \ int ret; \ - sal_detail_initialize(argc, argv); \ + sal_detail_initialize(argc, argv); \ + sal_initialize_at_sal_main_exit(); \ ret = sal_main_with_args(argc, argv); \ + sal_deinitialize_at_sal_main_exit(); \ sal_detail_deinitialize(); \ return ret; \ } @@ -56,7 +60,9 @@ int SAL_CALL main(int argc, char ** argv) \ { \ int ret; \ sal_detail_initialize(argc, argv); \ + sal_initialize_at_sal_main_exit(); \ ret = sal_main(); \ + sal_deinitialize_at_sal_main_exit(); \ sal_detail_deinitialize(); \ return ret; \ } diff --git a/sal/osl/all/debugbase.cxx b/sal/osl/all/debugbase.cxx index 1269324..15d6a60 100644 --- a/sal/osl/all/debugbase.cxx +++ b/sal/osl/all/debugbase.cxx @@ -51,8 +51,8 @@ namespace { typedef std::vector > OStringVec; struct StaticDebugBaseAddressFilter - : rtl::StaticWithInit { - OStringVec const operator()() const { + : rtl::StaticWithInit { + OStringVec operator()() const { OStringVec vec; rtl_uString * pStr = 0; rtl::OUString const name( diff --git a/sal/qa/rtl/doublelock/rtl_doublelocking.cxx b/sal/qa/rtl/doublelock/rtl_doublelocking.cxx index 9ccaf5a..2690091 100644 --- a/sal/qa/rtl/doublelock/rtl_doublelocking.cxx +++ b/sal/qa/rtl/doublelock/rtl_doublelocking.cxx @@ -54,9 +54,9 @@ #define CONST_TEST_STRING "gregorian" namespace { -struct Gregorian : public ::rtl::StaticWithInit { - const ::rtl::OUString operator () () { - return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( CONST_TEST_STRING )); +struct Gregorian : public rtl::StaticWithInit { + const rtl::OUString operator () () { + return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( CONST_TEST_STRING )); } }; } diff --git a/sal/rtl/source/alloc_fini.cxx b/sal/rtl/source/alloc_fini.cxx index dfd3599..0aafd25 100644 --- a/sal/rtl/source/alloc_fini.cxx +++ b/sal/rtl/source/alloc_fini.cxx @@ -27,6 +27,104 @@ ************************************************************************/ #include +#include + +struct StaticInstanceControllerLink +{ + rtl::StaticInstanceController *pEntry; + StaticInstanceControllerLink *pPrev; +}; + +static StaticInstanceControllerLink *pLastSingletonEntry=NULL; +static StaticInstanceControllerLink *pLastPreMainSingletonEntry=NULL; + +extern "C" void SAL_CALL register_at_sal_main_exit(rtl::StaticInstanceController* pDeleter) +{ + fprintf(stderr, "singleton %p ctor\n", pDeleter); + + StaticInstanceControllerLink *pLink = (StaticInstanceControllerLink*) + malloc(sizeof(StaticInstanceControllerLink)); + pLink->pEntry = pDeleter; + pLink->pPrev = pLastSingletonEntry; + pLastSingletonEntry = pLink; +} + +extern "C" void SAL_CALL deregister_at_sal_main_exit(rtl::StaticInstanceController* pDeleter) +{ + if (!pLastSingletonEntry) + { + fprintf(stderr, "os-exit triggered singleton %p dtor\n", + pDeleter); + return; + } + + StaticInstanceControllerLink *pLink = pLastSingletonEntry; + while (pLink != pLastPreMainSingletonEntry) + { + if (pLink->pEntry == pDeleter) + { + fprintf(stderr, "dso-unload triggered singleton %p dtor\n", + pDeleter); + pLink->pEntry = NULL; + } + pLink = pLink->pPrev; + } + + while (pLink) + { + if (pLink->pEntry == pDeleter) + { + fprintf(stderr, "pre-main singleton %p dtor called before main ended!\n", pDeleter); + pLink->pEntry = NULL; + } + pLink = pLink->pPrev; + } +} + +extern "C" void SAL_CALL sal_initialize_at_sal_main_exit() +{ + fprintf(stderr, "begin start_sal_main\n"); + pLastPreMainSingletonEntry = pLastSingletonEntry; + fprintf(stderr, "end start_sal_main\n"); +} + +extern "C" void SAL_CALL sal_deinitialize_at_sal_main_exit() +{ + fprintf(stderr, "begin end_sal_main\n"); + while (pLastSingletonEntry != pLastPreMainSingletonEntry) + { + StaticInstanceControllerLink *pLink = pLastSingletonEntry; + + if (pLink->pEntry) + { + fprintf(stderr, "at-sal-main-exit manual singleton %p dtor\n", pLink->pEntry); + pLink->pEntry->release(); + } + + pLastSingletonEntry = pLink->pPrev; + + free(pLink); + } + + while (pLastSingletonEntry) + { + StaticInstanceControllerLink *pLink = pLastSingletonEntry; + + if (pLink->pEntry) + { + //skipping pre-main entry on the basis that it may be needed + //post-main and that at this stage the situation is sufficiently + //simple that local static StaticInstanceController destructors + //will get called in the correct order + fprintf(stderr, "skipping pre-main entry of %p\n", pLink->pEntry); + } + + pLastSingletonEntry = pLink->pPrev; + + free(pLink); + } + fprintf(stderr, "end end_sal_main\n"); +} extern "C" void rtl_memory_fini (void); extern "C" void rtl_memory_init (void); diff --git a/sal/util/sal.map b/sal/util/sal.map index 020e11f..7142fb2 100755 --- a/sal/util/sal.map +++ b/sal/util/sal.map @@ -620,3 +620,11 @@ PRIVATE_1.1 { sal_detail_initialize; sal_detail_deinitialize; } PRIVATE_1.0; + +PRIVATE_1.2 { + global: + sal_initialize_at_sal_main_exit; + register_at_sal_main_exit; + deregister_at_sal_main_exit; + sal_deinitialize_at_sal_main_exit; +} PRIVATE_1.1;