1565d668cSAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3565d668cSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4565d668cSAndrew Rist * or more contributor license agreements. See the NOTICE file 5565d668cSAndrew Rist * distributed with this work for additional information 6565d668cSAndrew Rist * regarding copyright ownership. The ASF licenses this file 7565d668cSAndrew Rist * to you under the Apache License, Version 2.0 (the 8565d668cSAndrew Rist * "License"); you may not use this file except in compliance 9565d668cSAndrew Rist * with the License. You may obtain a copy of the License at 10565d668cSAndrew Rist * 11565d668cSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12565d668cSAndrew Rist * 13565d668cSAndrew Rist * Unless required by applicable law or agreed to in writing, 14565d668cSAndrew Rist * software distributed under the License is distributed on an 15565d668cSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16565d668cSAndrew Rist * KIND, either express or implied. See the License for the 17565d668cSAndrew Rist * specific language governing permissions and limitations 18565d668cSAndrew Rist * under the License. 19565d668cSAndrew Rist * 20565d668cSAndrew Rist *************************************************************/ 21565d668cSAndrew Rist 22565d668cSAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir #if !defined INCLUDED_RTL_INSTANCE_HXX 25cdf0e10cSrcweir #define INCLUDED_RTL_INSTANCE_HXX 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include "osl/doublecheckedlocking.h" 28cdf0e10cSrcweir #include "osl/getglobalmutex.hxx" 29cdf0e10cSrcweir 30cdf0e10cSrcweir namespace { 31cdf0e10cSrcweir 32cdf0e10cSrcweir /** A non-broken version of the double-checked locking pattern. 33cdf0e10cSrcweir 34cdf0e10cSrcweir See 35cdf0e10cSrcweir <http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html> 36cdf0e10cSrcweir for a description of double-checked locking, why it is broken, and how it 37cdf0e10cSrcweir can be fixed. Always use this template instead of spelling out the 38cdf0e10cSrcweir double-checked locking pattern explicitly, and only in those rare cases 39cdf0e10cSrcweir where that is not possible and you have to spell it out explicitly, at 40cdf0e10cSrcweir least call OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER() at the right 41cdf0e10cSrcweir places. That way, all platform-dependent code to make double-checked 42cdf0e10cSrcweir locking work can be kept in one place. 43cdf0e10cSrcweir 44cdf0e10cSrcweir Usage scenarios: 45cdf0e10cSrcweir 46cdf0e10cSrcweir 1 Static instance (most common case) 47cdf0e10cSrcweir 48cdf0e10cSrcweir Pattern: 49cdf0e10cSrcweir 50cdf0e10cSrcweir T * getInstance() 51cdf0e10cSrcweir { 52cdf0e10cSrcweir static T * pInstance = 0; 53cdf0e10cSrcweir if (!pInstance) 54cdf0e10cSrcweir { 55cdf0e10cSrcweir ::osl::MutexGuard aGuard(::osl::Mutex::getGlobalMutex()); 56cdf0e10cSrcweir if (!pInstance) 57cdf0e10cSrcweir { 58cdf0e10cSrcweir static T aInstance; 59cdf0e10cSrcweir pInstance = &aInstance; 60cdf0e10cSrcweir } 61cdf0e10cSrcweir } 62cdf0e10cSrcweir return pInstance; 63cdf0e10cSrcweir } 64cdf0e10cSrcweir 65cdf0e10cSrcweir Code: 66cdf0e10cSrcweir 67cdf0e10cSrcweir #include "rtl/instance.hxx" 68cdf0e10cSrcweir #include "osl/getglobalmutex.hxx" 69cdf0e10cSrcweir 70cdf0e10cSrcweir namespace { 71cdf0e10cSrcweir struct Init 72cdf0e10cSrcweir { 73cdf0e10cSrcweir T * operator()() 74cdf0e10cSrcweir { 75cdf0e10cSrcweir static T aInstance; 76cdf0e10cSrcweir return &aInstance; 77cdf0e10cSrcweir } 78cdf0e10cSrcweir }; 79cdf0e10cSrcweir } 80cdf0e10cSrcweir 81cdf0e10cSrcweir T * getInstance() 82cdf0e10cSrcweir { 83cdf0e10cSrcweir return rtl_Instance< T, Init, ::osl::MutexGuard, 84cdf0e10cSrcweir ::osl::GetGlobalMutex >::create( 85cdf0e10cSrcweir Init(), ::osl::GetGlobalMutex()); 86cdf0e10cSrcweir } 87cdf0e10cSrcweir 88cdf0e10cSrcweir 2 Dynamic instance 89cdf0e10cSrcweir 90cdf0e10cSrcweir Pattern: 91cdf0e10cSrcweir 92cdf0e10cSrcweir T * getInstance() 93cdf0e10cSrcweir { 94cdf0e10cSrcweir static T * pInstance = 0; 95cdf0e10cSrcweir if (!pInstance) 96cdf0e10cSrcweir { 97cdf0e10cSrcweir ::osl::MutexGuard aGuard(::osl::Mutex::getGlobalMutex()); 98cdf0e10cSrcweir if (!pInstance) 99cdf0e10cSrcweir pInstance = new T; 100cdf0e10cSrcweir } 101cdf0e10cSrcweir return pInstance; 102cdf0e10cSrcweir } 103cdf0e10cSrcweir 104cdf0e10cSrcweir Code: 105cdf0e10cSrcweir 106cdf0e10cSrcweir #include "rtl/instance.hxx" 107cdf0e10cSrcweir #include "osl/getglobalmutex.hxx" 108cdf0e10cSrcweir 109cdf0e10cSrcweir namespace { 110cdf0e10cSrcweir struct Init 111cdf0e10cSrcweir { 112cdf0e10cSrcweir T * operator()() 113cdf0e10cSrcweir { 114cdf0e10cSrcweir return new T; 115cdf0e10cSrcweir } 116cdf0e10cSrcweir }; 117cdf0e10cSrcweir } 118cdf0e10cSrcweir 119cdf0e10cSrcweir T * getInstance() 120cdf0e10cSrcweir { 121cdf0e10cSrcweir return rtl_Instance< T, Init, ::osl::MutexGuard, 122cdf0e10cSrcweir ::osl::GetGlobalMutex >::create( 123cdf0e10cSrcweir Init(), ::osl::GetGlobalMutex()); 124cdf0e10cSrcweir } 125cdf0e10cSrcweir 126cdf0e10cSrcweir 3 Other guard/mutex 127cdf0e10cSrcweir 128cdf0e10cSrcweir Pattern: 129cdf0e10cSrcweir 130cdf0e10cSrcweir T * getInstance() 131cdf0e10cSrcweir { 132cdf0e10cSrcweir static T * pInstance = 0; 133cdf0e10cSrcweir if (!pInstance) 134cdf0e10cSrcweir { 135cdf0e10cSrcweir SomeGuard aGuard(pSomeMutex); 136cdf0e10cSrcweir if (!pInstance) 137cdf0e10cSrcweir { 138cdf0e10cSrcweir static T aInstance; 139cdf0e10cSrcweir pInstance = &aInstance; 140cdf0e10cSrcweir } 141cdf0e10cSrcweir } 142cdf0e10cSrcweir return pInstance; 143cdf0e10cSrcweir } 144cdf0e10cSrcweir 145cdf0e10cSrcweir Code: 146cdf0e10cSrcweir 147cdf0e10cSrcweir #include "rtl/instance.hxx" 148cdf0e10cSrcweir 149cdf0e10cSrcweir namespace { 150cdf0e10cSrcweir struct InitInstance 151cdf0e10cSrcweir { 152cdf0e10cSrcweir T * operator()() 153cdf0e10cSrcweir { 154cdf0e10cSrcweir static T aInstance; 155cdf0e10cSrcweir return &aInstance; 156cdf0e10cSrcweir } 157cdf0e10cSrcweir }; 158cdf0e10cSrcweir 159cdf0e10cSrcweir struct InitGuard 160cdf0e10cSrcweir { 161cdf0e10cSrcweir SomeMutex * operator()() 162cdf0e10cSrcweir { 163cdf0e10cSrcweir return pSomeMutex; 164cdf0e10cSrcweir } 165cdf0e10cSrcweir }; 166cdf0e10cSrcweir } 167cdf0e10cSrcweir 168cdf0e10cSrcweir T * getInstance() 169cdf0e10cSrcweir { 170cdf0e10cSrcweir return rtl_Instance< T, InitInstance, 171cdf0e10cSrcweir SomeGuard, InitGuard >::create( 172cdf0e10cSrcweir InitInstance(), InitMutex()); 173cdf0e10cSrcweir } 174cdf0e10cSrcweir 175cdf0e10cSrcweir 4 Calculate extra data 176cdf0e10cSrcweir 177cdf0e10cSrcweir Pattern: 178cdf0e10cSrcweir 179cdf0e10cSrcweir T * getInstance() 180cdf0e10cSrcweir { 181cdf0e10cSrcweir static T * pInstance = 0; 182cdf0e10cSrcweir if (!pInstance) 183cdf0e10cSrcweir { 184cdf0e10cSrcweir Data aData(...); 185cdf0e10cSrcweir ::osl::MutexGuard aGuard(::osl::Mutex::getGlobalMutex()); 186cdf0e10cSrcweir if (!pInstance) 187cdf0e10cSrcweir { 188cdf0e10cSrcweir static T aInstance(aData); 189cdf0e10cSrcweir pInstance = &aInstance; 190cdf0e10cSrcweir } 191cdf0e10cSrcweir } 192cdf0e10cSrcweir return pInstance; 193cdf0e10cSrcweir } 194cdf0e10cSrcweir 195cdf0e10cSrcweir Code: 196cdf0e10cSrcweir 197cdf0e10cSrcweir #include "rtl/instance.hxx" 198cdf0e10cSrcweir #include "osl/getglobalmutex.hxx" 199cdf0e10cSrcweir 200cdf0e10cSrcweir namespace { 201cdf0e10cSrcweir struct InitInstance 202cdf0e10cSrcweir { 203cdf0e10cSrcweir T * operator()() 204cdf0e10cSrcweir { 205cdf0e10cSrcweir static T aInstance; 206cdf0e10cSrcweir return &aInstance; 207cdf0e10cSrcweir } 208cdf0e10cSrcweir } 209cdf0e10cSrcweir 210cdf0e10cSrcweir struct InitData 211cdf0e10cSrcweir { 212cdf0e10cSrcweir Data const & operator()() 213cdf0e10cSrcweir { 214cdf0e10cSrcweir return ...; 215cdf0e10cSrcweir } 216cdf0e10cSrcweir } 217cdf0e10cSrcweir } 218cdf0e10cSrcweir 219cdf0e10cSrcweir T * getInstance() 220cdf0e10cSrcweir { 221cdf0e10cSrcweir return rtl_Instance< T, InitInstance, 222cdf0e10cSrcweir ::osl::Mutex, ::osl::GetGlobalMutex, 223cdf0e10cSrcweir Data, InitData >::create( 224cdf0e10cSrcweir InitInstance(), ::osl::GetGlobalMutex(), InitData()); 225cdf0e10cSrcweir } 226cdf0e10cSrcweir 227cdf0e10cSrcweir Some comments: 228cdf0e10cSrcweir 229cdf0e10cSrcweir For any instantiation of rtl_Instance, at most one call to a create method 230*86e1cf34SPedro Giffuni may occur in the program code: Each occurrence of a create method within 231cdf0e10cSrcweir the program code is supposed to return a fresh object instance on the 232cdf0e10cSrcweir first call, and that same object instance on subsequent calls; but 233*86e1cf34SPedro Giffuni independent occurrences of create methods are supposed to return 234cdf0e10cSrcweir independent object instances. Since there is a one-to-one correspondence 235cdf0e10cSrcweir between object instances and instantiations of rtl_Instance, the 236cdf0e10cSrcweir requirement should be clear. One measure to enforce the requirement is 237cdf0e10cSrcweir that rtl_Instance lives in an unnamed namespace, so that instantiations of 238cdf0e10cSrcweir rtl_Instance in different translation units will definitely be different 239cdf0e10cSrcweir instantiations. A drawback of that measure is that the name of the class 240cdf0e10cSrcweir needs a funny "hand coded" prefix "rtl_" instead of a proper namespace 241cdf0e10cSrcweir prefix like "::rtl::". 242cdf0e10cSrcweir 243*86e1cf34SPedro Giffuni A known problem with this template is when two occurrences of calls to 244cdf0e10cSrcweir create methods with identical template arguments appear in one translation 245cdf0e10cSrcweir unit. Those two places will share a single object instance. This can be 246cdf0e10cSrcweir avoided by using different Init structs (see the above code samples) in 247cdf0e10cSrcweir the two places. 248cdf0e10cSrcweir 249cdf0e10cSrcweir There is no need to make m_pInstance volatile, in order to avoid usage of 250cdf0e10cSrcweir stale copies of m_pInstance: At the first check, a thread will see that 251cdf0e10cSrcweir m_pInstance contains either 0 or a valid pointer. If it contains a valid 252cdf0e10cSrcweir pointer, it cannot be stale, and that pointer is used. If it contains 0, 253cdf0e10cSrcweir acquiring the mutex will ensure that the second check sees a non-stale 254cdf0e10cSrcweir value in all cases. 255cdf0e10cSrcweir 256cdf0e10cSrcweir On some compilers, the create methods would not be inlined if they 257cdf0e10cSrcweir contained any static variables, so m_pInstance is made a class member 258cdf0e10cSrcweir instead (and the create methods are inlined). But on MSC, the definition 259cdf0e10cSrcweir of the class member m_pInstance would cause compilation to fail with an 260cdf0e10cSrcweir internal compiler error. Since MSC is able to inline methods containing 261cdf0e10cSrcweir static variables, m_pInstance is moved into the methods there. Note that 262cdf0e10cSrcweir this only works well because for any instantiation of rtl_Instance at most 263cdf0e10cSrcweir one call to a create method should be present, anyway. 264cdf0e10cSrcweir */ 265cdf0e10cSrcweir template< typename Inst, typename InstCtor, 266cdf0e10cSrcweir typename Guard, typename GuardCtor, 267cdf0e10cSrcweir typename Data = int, typename DataCtor = int > 268cdf0e10cSrcweir class rtl_Instance 269cdf0e10cSrcweir { 270cdf0e10cSrcweir public: create(InstCtor aInstCtor,GuardCtor aGuardCtor)271cdf0e10cSrcweir static inline Inst * create(InstCtor aInstCtor, GuardCtor aGuardCtor) 272cdf0e10cSrcweir { 273cdf0e10cSrcweir #if defined _MSC_VER 274cdf0e10cSrcweir static Inst * m_pInstance = 0; 275cdf0e10cSrcweir #endif // _MSC_VER 276cdf0e10cSrcweir Inst * p = m_pInstance; 277cdf0e10cSrcweir if (!p) 278cdf0e10cSrcweir { 279cdf0e10cSrcweir Guard aGuard(aGuardCtor()); 280cdf0e10cSrcweir p = m_pInstance; 281cdf0e10cSrcweir if (!p) 282cdf0e10cSrcweir { 283cdf0e10cSrcweir p = aInstCtor(); 284cdf0e10cSrcweir OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); 285cdf0e10cSrcweir m_pInstance = p; 286cdf0e10cSrcweir } 287cdf0e10cSrcweir } 288cdf0e10cSrcweir else 289cdf0e10cSrcweir { 290cdf0e10cSrcweir OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); 291cdf0e10cSrcweir } 292cdf0e10cSrcweir return p; 293cdf0e10cSrcweir } 294cdf0e10cSrcweir create(InstCtor aInstCtor,GuardCtor aGuardCtor,DataCtor aDataCtor)295cdf0e10cSrcweir static inline Inst * create(InstCtor aInstCtor, GuardCtor aGuardCtor, 296cdf0e10cSrcweir DataCtor aDataCtor) 297cdf0e10cSrcweir { 298cdf0e10cSrcweir #if defined _MSC_VER 299cdf0e10cSrcweir static Inst * m_pInstance = 0; 300cdf0e10cSrcweir #endif // _MSC_VER 301cdf0e10cSrcweir Inst * p = m_pInstance; 302cdf0e10cSrcweir if (!p) 303cdf0e10cSrcweir { 304cdf0e10cSrcweir Data aData(aDataCtor()); 305cdf0e10cSrcweir Guard aGuard(aGuardCtor()); 306cdf0e10cSrcweir p = m_pInstance; 307cdf0e10cSrcweir if (!p) 308cdf0e10cSrcweir { 309cdf0e10cSrcweir p = aInstCtor(aData); 310cdf0e10cSrcweir OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); 311cdf0e10cSrcweir m_pInstance = p; 312cdf0e10cSrcweir } 313cdf0e10cSrcweir } 314cdf0e10cSrcweir else 315cdf0e10cSrcweir { 316cdf0e10cSrcweir OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); 317cdf0e10cSrcweir } 318cdf0e10cSrcweir return p; 319cdf0e10cSrcweir } 320cdf0e10cSrcweir 321cdf0e10cSrcweir private: 322cdf0e10cSrcweir #if !defined _MSC_VER 323cdf0e10cSrcweir static Inst * m_pInstance; 324cdf0e10cSrcweir #endif // _MSC_VER 325cdf0e10cSrcweir }; 326cdf0e10cSrcweir 327cdf0e10cSrcweir #if !defined _MSC_VER 328cdf0e10cSrcweir template< typename Inst, typename InstCtor, 329cdf0e10cSrcweir typename Guard, typename GuardCtor, 330cdf0e10cSrcweir typename Data, typename DataCtor > 331cdf0e10cSrcweir Inst * 332cdf0e10cSrcweir rtl_Instance< Inst, InstCtor, Guard, GuardCtor, Data, DataCtor >::m_pInstance 333cdf0e10cSrcweir = 0; 334cdf0e10cSrcweir #endif // _MSC_VER 335cdf0e10cSrcweir 336cdf0e10cSrcweir } 337cdf0e10cSrcweir 338cdf0e10cSrcweir namespace rtl { 339cdf0e10cSrcweir 340cdf0e10cSrcweir /** Helper base class for a late-initialized (default-constructed) 341cdf0e10cSrcweir static variable, implementing the double-checked locking pattern correctly. 342cdf0e10cSrcweir 343cdf0e10cSrcweir @derive 344cdf0e10cSrcweir Derive from this class (common practice), e.g. 345cdf0e10cSrcweir <pre> 346cdf0e10cSrcweir struct MyStatic : public rtl::Static<MyType, MyStatic> {}; 347cdf0e10cSrcweir ... 348cdf0e10cSrcweir MyType & rStatic = MyStatic::get(); 349cdf0e10cSrcweir ... 350cdf0e10cSrcweir </pre> 351cdf0e10cSrcweir 352cdf0e10cSrcweir @tplparam T 353cdf0e10cSrcweir variable's type 354cdf0e10cSrcweir @tplparam Unique 355cdf0e10cSrcweir Implementation trick to make the inner static holder unique, 356cdf0e10cSrcweir using the outer class 357cdf0e10cSrcweir (the one that derives from this base class) 358cdf0e10cSrcweir */ 359cdf0e10cSrcweir template<typename T, typename Unique> 360cdf0e10cSrcweir class Static { 361cdf0e10cSrcweir public: 362cdf0e10cSrcweir /** Gets the static. Mutual exclusion is performed using the 363cdf0e10cSrcweir osl global mutex. 364cdf0e10cSrcweir 365cdf0e10cSrcweir @return 366cdf0e10cSrcweir static variable 367cdf0e10cSrcweir */ get()368cdf0e10cSrcweir static T & get() { 369cdf0e10cSrcweir return *rtl_Instance< 370cdf0e10cSrcweir T, StaticInstance, 371cdf0e10cSrcweir ::osl::MutexGuard, ::osl::GetGlobalMutex >::create( 372cdf0e10cSrcweir StaticInstance(), ::osl::GetGlobalMutex() ); 373cdf0e10cSrcweir } 374cdf0e10cSrcweir private: 375cdf0e10cSrcweir struct StaticInstance { operator ()rtl::Static::StaticInstance376cdf0e10cSrcweir T * operator () () { 377cdf0e10cSrcweir static T instance; 378cdf0e10cSrcweir return &instance; 379cdf0e10cSrcweir } 380cdf0e10cSrcweir }; 381cdf0e10cSrcweir }; 382cdf0e10cSrcweir 383cdf0e10cSrcweir /** Helper class for a late-initialized static aggregate, e.g. an array, 384cdf0e10cSrcweir implementing the double-checked locking pattern correctly. 385cdf0e10cSrcweir 386cdf0e10cSrcweir @tplparam T 387cdf0e10cSrcweir aggregate's element type 388cdf0e10cSrcweir @tplparam InitAggregate 389cdf0e10cSrcweir initializer functor class 390cdf0e10cSrcweir */ 391cdf0e10cSrcweir template<typename T, typename InitAggregate> 392cdf0e10cSrcweir class StaticAggregate { 393cdf0e10cSrcweir public: 394cdf0e10cSrcweir /** Gets the static aggregate, late-initializing. 395cdf0e10cSrcweir Mutual exclusion is performed using the osl global mutex. 396cdf0e10cSrcweir 397cdf0e10cSrcweir @return 398cdf0e10cSrcweir aggregate 399cdf0e10cSrcweir */ get()400cdf0e10cSrcweir static T * get() { 401cdf0e10cSrcweir return rtl_Instance< 402cdf0e10cSrcweir T, InitAggregate, 403cdf0e10cSrcweir ::osl::MutexGuard, ::osl::GetGlobalMutex >::create( 404cdf0e10cSrcweir InitAggregate(), ::osl::GetGlobalMutex() ); 405cdf0e10cSrcweir } 406cdf0e10cSrcweir }; 407cdf0e10cSrcweir 408cdf0e10cSrcweir /** Helper base class for a late-initialized static variable, 409cdf0e10cSrcweir implementing the double-checked locking pattern correctly. 410cdf0e10cSrcweir 411cdf0e10cSrcweir @derive 412cdf0e10cSrcweir Derive from this class (common practice), 413cdf0e10cSrcweir providing an initializer functor class, e.g. 414cdf0e10cSrcweir <pre> 415cdf0e10cSrcweir struct MyStatic : public rtl::StaticWithInit<MyType, MyStatic> { 416cdf0e10cSrcweir MyType operator () () { 417cdf0e10cSrcweir ... 418cdf0e10cSrcweir return MyType( ... ); 419cdf0e10cSrcweir } 420cdf0e10cSrcweir }; 421cdf0e10cSrcweir ... 422cdf0e10cSrcweir MyType & rStatic = MyStatic::get(); 423cdf0e10cSrcweir ... 424cdf0e10cSrcweir </pre> 425cdf0e10cSrcweir 426cdf0e10cSrcweir @tplparam T 427cdf0e10cSrcweir variable's type 428cdf0e10cSrcweir @tplparam InitData 429cdf0e10cSrcweir initializer functor class 430cdf0e10cSrcweir @tplparam Unique 431cdf0e10cSrcweir Implementation trick to make the inner static holder unique, 432cdf0e10cSrcweir using the outer class 433cdf0e10cSrcweir (the one that derives from this base class). 434cdf0e10cSrcweir Default is InitData (common practice). 435cdf0e10cSrcweir @tplparam Data 436cdf0e10cSrcweir Initializer functor's return type. 437cdf0e10cSrcweir Default is T (common practice). 438cdf0e10cSrcweir */ 439cdf0e10cSrcweir template<typename T, typename InitData, 440cdf0e10cSrcweir typename Unique = InitData, typename Data = T> 441cdf0e10cSrcweir class StaticWithInit { 442cdf0e10cSrcweir public: 443cdf0e10cSrcweir /** Gets the static. Mutual exclusion is performed using the 444cdf0e10cSrcweir osl global mutex. 445cdf0e10cSrcweir 446cdf0e10cSrcweir @return 447cdf0e10cSrcweir static variable 448cdf0e10cSrcweir */ get()449cdf0e10cSrcweir static T & get() { 450cdf0e10cSrcweir return *rtl_Instance< 451cdf0e10cSrcweir T, StaticInstanceWithInit, 452cdf0e10cSrcweir ::osl::MutexGuard, ::osl::GetGlobalMutex, 453cdf0e10cSrcweir Data, InitData >::create( StaticInstanceWithInit(), 454cdf0e10cSrcweir ::osl::GetGlobalMutex(), 455cdf0e10cSrcweir InitData() ); 456cdf0e10cSrcweir } 457cdf0e10cSrcweir private: 458cdf0e10cSrcweir struct StaticInstanceWithInit { operator ()rtl::StaticWithInit::StaticInstanceWithInit459cdf0e10cSrcweir T * operator () ( Data d ) { 460cdf0e10cSrcweir static T instance(d); 461cdf0e10cSrcweir return &instance; 462cdf0e10cSrcweir } 463cdf0e10cSrcweir }; 464cdf0e10cSrcweir }; 465cdf0e10cSrcweir 466cdf0e10cSrcweir } // namespace rtl 467cdf0e10cSrcweir 468cdf0e10cSrcweir #endif // INCLUDED_RTL_INSTANCE_HXX 469