My Project
UDK 3.2.7 C/C++ API Reference
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
singletonref.hxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * Copyright 2000, 2010 Oracle and/or its affiliates.
7  *
8  * OpenOffice.org - a multi-platform office productivity suite
9  *
10  * This file is part of OpenOffice.org.
11  *
12  * OpenOffice.org is free software: you can redistribute it and/or modify
13  * it under the terms of the GNU Lesser General Public License version 3
14  * only, as published by the Free Software Foundation.
15  *
16  * OpenOffice.org is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU Lesser General Public License version 3 for more details
20  * (a copy is included in the LICENSE file that accompanied this code).
21  *
22  * You should have received a copy of the GNU Lesser General Public License
23  * version 3 along with OpenOffice.org. If not, see
24  * <http://www.openoffice.org/license.html>
25  * for a copy of the LGPLv3 License.
26  *
27  ************************************************************************/
28 
29 #ifndef _SALHELPER_SINGLETONREF_HXX_
30 #define _SALHELPER_SINGLETONREF_HXX_
31 
32 //_______________________________________________
33 // includes
34 
35 #include <osl/mutex.hxx>
36 #include "rtl/instance.hxx"
37 #include "osl/diagnose.h"
38 #include "osl/getglobalmutex.hxx"
39 
40 //_______________________________________________
41 // namespace
42 
43 namespace salhelper{
44 
45 //_______________________________________________
46 // definitions
47 
80 template< class SingletonClass >
82 {
83  //-------------------------------------------
84  // member
85 
86  private :
87 
89  static SingletonClass* m_pInstance;
90 
92  static sal_Int32 m_nRef;
93 
94  //-------------------------------------------
95  // interface
96 
97  public :
98 
99  //---------------------------------------
100 
109  {
110  // GLOBAL SAFE ->
111  ::osl::MutexGuard aLock(SingletonRef::ownStaticLock());
112 
113  // must be increased before(!) the check is done.
114  // Otherwhise this check can fail inside the same thread ...
115  ++m_nRef;
116  if (m_nRef == 1)
117  m_pInstance = new SingletonClass();
118 
119  OSL_ENSURE(m_nRef>0 && m_pInstance, "Race? Ref count of singleton >0, but instance is NULL!");
120  // <- GLOBAL SAFE
121  }
122 
123  //---------------------------------------
124 
133  {
134  // GLOBAL SAFE ->
135  ::osl::MutexGuard aLock(SingletonRef::ownStaticLock());
136 
137  // must be decreased before(!) the check is done.
138  // Otherwhise this check can fail inside the same thread ...
139  --m_nRef;
140  if (m_nRef == 0)
141  {
142  delete m_pInstance;
143  m_pInstance = 0;
144  }
145  // <- GLOBAL SAFE
146  }
147 
148  //---------------------------------------
149 
152  SingletonClass* operator->() const
153  {
154  // GLOBAL SAFE ->
155  ::osl::MutexGuard aLock(SingletonRef::ownStaticLock());
156  return m_pInstance;
157  // <- GLOBAL SAFE
158  }
159 
160  //---------------------------------------
161 
164  SingletonClass& operator*() const
165  {
166  // GLOBAL SAFE ->
167  ::osl::MutexGuard aLock(SingletonRef::ownStaticLock());
168  return *m_pInstance;
169  // <- GLOBAL SAFE
170  }
171 
172  //-------------------------------------------
173  // helper
174 
175  private :
176 
177  //---------------------------------------
178 
185  struct SingletonLockInit
186  {
187  ::osl::Mutex* operator()()
188  {
189  static ::osl::Mutex aInstance;
190  return &aInstance;
191  }
192  };
193 
194  ::osl::Mutex& ownStaticLock() const
195  {
196  return *rtl_Instance< ::osl::Mutex,
197  SingletonLockInit,
199  ::osl::GetGlobalMutex >::create(SingletonLockInit(), ::osl::GetGlobalMutex());
200  }
201 };
202 
203 template< class SingletonClass >
204 SingletonClass* SingletonRef< SingletonClass >::m_pInstance = 0;
205 
206 template< class SingletonClass >
207 sal_Int32 SingletonRef< SingletonClass >::m_nRef = 0;
208 
209 } // namespace salhelper
210 
211 #endif // _SALHELPER_SINGLETONREF_HXX_
212 
213 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */