source: rrlib_util/patterns/singleton/tSingletonHolder.h @ 44:b8711bbdd13e

Last change on this file since 44:b8711bbdd13e was 44:b8711bbdd13e, checked in by Tobias Föhst <foehst@…>, 9 years ago

Added lifetime policy Longevity for ordered destruction of singletons

File size: 4.3 KB
Line 
1//
2// You received this file as part of RRLib
3// Robotics Research Library
4//
5// Copyright (C) Finroc GbR (finroc.org)
6//
7// This program is free software; you can redistribute it and/or
8// modify it under the terms of the GNU General Public License
9// as published by the Free Software Foundation; either version 2
10// of the License, or (at your option) any later version.
11//
12// This program is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15// GNU General Public License for more details.
16//
17// You should have received a copy of the GNU General Public License
18// along with this program; if not, write to the Free Software
19// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20//
21//----------------------------------------------------------------------
22/*!\file    tSingletonHolder.h
23 *
24 * \author  Tobias Foehst
25 *
26 * \date    2010-10-26
27 *
28 * \brief Contains tSingletonHolder
29 *
30 * \b tSingletonHolder
31 *
32 */
33//----------------------------------------------------------------------
34#ifndef __rrlib__util__patterns__singleton__tSingletonHolder_h__
35#define __rrlib__util__patterns__singleton__tSingletonHolder_h__
36
37//----------------------------------------------------------------------
38// External includes (system with <>, local with "")
39//----------------------------------------------------------------------
40#include <boost/noncopyable.hpp>
41#include <mutex>
42
43//----------------------------------------------------------------------
44// Internal includes with ""
45//----------------------------------------------------------------------
46
47//----------------------------------------------------------------------
48// Debugging
49//----------------------------------------------------------------------
50#include <cassert>
51
52//----------------------------------------------------------------------
53// Namespace declaration
54//----------------------------------------------------------------------
55namespace rrlib
56{
57namespace util
58{
59
60//----------------------------------------------------------------------
61// Forward declarations / typedefs / enums
62//----------------------------------------------------------------------
63
64//----------------------------------------------------------------------
65// Class declaration
66//----------------------------------------------------------------------
67//!
68/*!
69 *
70 */
71template <
72typename T,
73         template <typename> class TLifetimePolicy = singleton::DefaultLifetime,
74         template <typename> class TCreationPolicy = singleton::CreateUsingNew
75         >
76class tSingletonHolder : public boost::noncopyable
77{
78
79//----------------------------------------------------------------------
80// Public methods and typedefs
81//----------------------------------------------------------------------
82public:
83
84  static T &Instance()
85  {
86    if (!tSingletonHolder::InstancePointer())
87    {
88      tSingletonHolder::CreateInstance();
89    }
90    return *tSingletonHolder::InstancePointer();
91  }
92
93//----------------------------------------------------------------------
94// Private fields and methods
95//----------------------------------------------------------------------
96private:
97
98  tSingletonHolder();
99
100  static void CreateInstance()
101  {
102    static std::mutex mutex;
103    std::unique_lock<std::mutex> lock(mutex);
104
105    if (!tSingletonHolder::InstancePointer())
106    {
107      if (tSingletonHolder::Destroyed())
108      {
109        TLifetimePolicy<T>::OnDeadReference();
110        tSingletonHolder::Destroyed() = false;
111      }
112      tSingletonHolder::InstancePointer() = TCreationPolicy<T>::Create();
113      TLifetimePolicy<T>::ScheduleDestruction(tSingletonHolder::InstancePointer(), &tSingletonHolder::DestroyInstance);
114    }
115  }
116
117  static void DestroyInstance()
118  {
119    assert(!tSingletonHolder::Destroyed());
120    TCreationPolicy<T>::Destroy(tSingletonHolder::InstancePointer());
121    tSingletonHolder::InstancePointer() = 0;
122    tSingletonHolder::Destroyed() = true;
123  }
124
125  static T *&InstancePointer()
126  {
127    static T *instance = 0;
128    return instance;
129  }
130
131  static bool &Destroyed()
132  {
133    static bool destroyed = false;
134    return destroyed;
135  }
136
137};
138
139//----------------------------------------------------------------------
140// End of namespace declaration
141//----------------------------------------------------------------------
142}
143}
144
145#endif
Note: See TracBrowser for help on using the repository browser.