1<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 2<html> 3<!-- 4(C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com . 5Use, modification and distribution is subject to the Boost Software 6License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 7http://www.boost.org/LICENSE_1_0.txt) 8--> 9<head> 10<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 11<link rel="stylesheet" type="text/css" href="../../../boost.css"> 12<link rel="stylesheet" type="text/css" href="style.css"> 13<title>Serialization - singleton</title> 14</head> 15<body link="#0000ff" vlink="#800080"> 16<table border="0" cellpadding="7" cellspacing="0" width="100%" summary="header"> 17 <tr> 18 <td valign="top" width="300"> 19 <h3><a href="../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../boost.png" border="0"></a></h3> 20 </td> 21 <td valign="top"> 22 <h1 align="center">Serialization</h1> 23 <h2 align="center"><code style="white-space: normal">singleton</code></h2> 24 </td> 25 </tr> 26</table> 27<hr> 28<dl class="page-index"> 29 <dt><a href="#motivation">Motivation</a> 30 <dt><a href="#features">Features</a> 31 <dt><a href="#classinterface">Class Interface</a> 32 <dt><a href="#requirements">Requirements</a> 33 <dt><a href="#example">Examples</a> 34 <dt><a href="#multithreading">Multi-Threading</a> 35</dl> 36 37<h3><a name="motivation">Motivation</a></h3> 38The serialization library relies on the existence of a number 39of static variables and tables to store information related 40to runtime types. Examples are tables which relate exported 41names to types and tables which relate base classes to derived 42classes. Construction, destruction and usage of these variables 43requires consideration of the following issues: 44<ul> 45 <li>Some static data variable and constant entries refer to others. 46 The sequence of initialization cannot be arbitrary but must be in proper 47 sequence.</li> 48 <li>A number of static variables aren't referred to explicitly and, without 49 special precautions, will be stripped by most code optimizers</li> 50 <li>Many of these variables are created by templates and special care must 51 be taken to be sure that they are instantiated</li> 52 <li>In a multi-threading system, its possible that these static variables 53 will be accessed concurrently by separate threads. This would create a 54 race condition with unpredictabe behavior</li> 55</ul> 56This singleton class addresses all of the above issues. 57 58<h3><a name="features">Features</a></h3> 59This singleton implementation has the following features: 60<ul> 61 <li> 62 Any instance will be constructed before any attempt is made to access it.</li> 63 <li> 64 Any instance created with a template is guaranteed to be instantiated. 65 <li> 66 Regardless of whether or not an instance has been explicitly 67 referred to, it will not be stripped by the optimizer when the 68 executable is built in release mode. 69 <li> 70 All instances are constructed before 71 <code style="white-space: normal">main</code> is called 72 regardless of where they might be referenced within the program. 73 In a multi-tasking system, this guarantees that there will be no 74 race conditions during the construction of any instance. No 75 thread locking is required to guarantee this. 76 <li> 77 The above implies that any <code style="white-space: normal">const</code> 78 instances are thread-safe during the whole program. Again, no 79 thread locking is required. 80 <li> 81 If a mutable instance is created, and such an instance is modified 82 after main is called in a multi-threading system, there exists 83 the possibility that a race condition will occur. The serialization 84 library takes care that in the few places where a mutable 85 singleton is required, it is not altered after 86 <code style="white-space: normal">main</code> is called. 87 For a more general purpose usage, thread locking on this 88 singleton could easily be implemented. But as the serialization 89 library didn't require it, it wasn't implemented. 90</ul> 91 92<h3><a name="classinterface">Class Interface</a></h3> 93<pre><code> 94namespace boost { 95namespace serialization { 96 97template <class T> 98class singleton : public boost::noncopyable 99{ 100public: 101 static const T & get_const_instance(); 102 static T & get_mutable_instance(); 103 static bool is_destroyed(); 104}; 105 106} // namespace serialization 107} // namespace boost 108</code></pre> 109 110<dl> 111 112<dt><h4><pre><code> 113static const T & get_const_instance(); 114</code></pre></h4></dt> 115<dd> 116Retrieve a constant reference to the singleton for this type. 117</dd> 118 119<dt><h4><pre><code> 120static T & get_mutable_instance(); 121</code></pre></h4></dt> 122<dd> 123Retrieve a mutable reference to the singleton for this type. 124</dd> 125 126<dt><h4><pre><code> 127static bool is_destroyed(); 128</code></pre></h4></dt> 129<dd> 130Return <code>true</code> if the destructor on this singleton has been 131called. Otherwise, return <code>false</code>. 132</dd> 133 134</dl> 135 136<h3><a name="requirements">Requirements</a></h3> 137In order to be used as 138<a target="singleton.hpp" href = "../../../boost/serialization/singleton.hpp"> 139<code style="white-space: normal"> 140singleton<T> 141</code> 142</a>, the type T must be default constructable. 143It doesn't require static variables - though it may have them. 144Since the library guarantees that only one instance of 145<a target="singleton.hpp" href = "../../../boost/serialization/singleton.hpp"> 146<code style="white-space: normal"> 147singleton<T> 148</code> 149</a> 150exists and all accesss is through the above static interface 151functions, common member functions of T become 152the functional equivalent of 153<code style="white-space: normal">static</code> functions. 154 155<h3><a name="example">Examples</a></h3> 156There are at least two different ways to use this class template. 157Both are used in the serialization library. 158<p> 159The first way is illustrated by an excerpt from the file 160<code style="white-space: normal"><a target="extended_type_info" href="../src/extended_type_info.cpp">extended_type_info.cpp</a></code>. 161which contains the following code: 162 163<pre><code> 164typedef std::set<const extended_type_info *, key_compare> ktmap; 165... 166void 167extended_type_info::key_register(const char *key) { 168 ... 169 result = singleton<ktmap>::get_mutable_instance().insert(this); 170 ... 171} 172</code></pre> 173Just by referring to the singleton instance anywhere in the program 174will guarantee that one and only one instance for the specified 175type (<code style="white-space: normal">ktmap</code> in this example) 176will exist throughout the program. There is no need for any other 177declaration or definition. 178<p> 179A second way is to use 180<a target="singleton.hpp" href = "../../../boost/serialization/singleton.hpp"> 181<code style="white-space: normal"> 182singleton<T> 183</code> 184</a> 185as one of the base classes of the type. This is illustrated by a simplified 186excerpt from 187<a target="extended_type_info_typeid.hpp" href = "../../../boost/serialization/extended_type_info_typeid.hpp"> 188<code style="white-space: normal"> 189extended_type_info_typeid.hpp 190</code> 191</a> 192 193<pre><code> 194template<class T> 195class extended_type_info_typeid : 196 public detail::extended_type_info_typeid_0, 197 public singleton<extended_type_info_typeid<const T> > 198{ 199 friend class singleton<extended_type_info_typeid<const T> >; 200private: 201 // private constructor to inhibit any existence other than the 202 // static one. Note: not all compilers support this !!! 203 extended_type_info_typeid() : 204 detail::extended_type_info_typeid_0() 205 { 206 type_register(typeid(T)); 207 } 208 ~extended_type_info_typeid(){} 209 ... 210}; 211</code></pre> 212 213This usage will permit a more natural syntax to be used: 214<pre><code> 215extended_type_info_typeid<T>::get_const_instance() 216</code></pre> 217 218Again, including one or more of the above statements anywhere 219in the program will guarantee that one and only one instance 220is created and referred to. 221 222<h3><a name="multithreading">Multi-Threading</a></h3> 223This singleton CAN be safely used in multi-threading applications if one 224is careful follow a simple rule: 225<p> 226<b>Do not call get_mutable_instance when more than one thread is running!</b> 227All singletons used in the serialization library follow this rule. 228In order to help detect accidental violations of this rule there 229exist singleton lock/unlock functions. 230<pre><code> 231void boost::serialization::singleton_module::lock(); 232void boost::serialization::singleton_module::unlock(); 233bool boost::serialization::singleton_module::is_locked(); 234</code></pre> 235In a program compiled for debug, any invocation of 236<code style="white-space: normal">get_mutable_instance()</code> 237while the library is in a "locked" state will trap in an assertion. 238The singleton module lock state is initialized as "unlocked" to permit 239alteration of static variables before 240<code style="white-space: normal">main</code> is called. 241The <code style="white-space: normal">lock()</code> and 242<code style="white-space: normal">unlock()</code> are "global" 243in that they affect ALL the singletons defined by this template. 244All serialization tests invoke <code style="white-space: normal">lock()</code> 245at the start of the progam. For programs compiled in release 246mode these functions have no effect. 247 248<hr> 249<p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2007. 250Distributed under the Boost Software License, Version 1.0. (See 251accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 252</i></p> 253</body> 254</html> 255