singleton.html 9.3 KB

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