123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254 |
- <!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
- <html>
- <!--
- (C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
- Use, modification and distribution is subject to the Boost Software
- License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
- http://www.boost.org/LICENSE_1_0.txt)
- -->
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
- <link rel="stylesheet" type="text/css" href="../../../boost.css">
- <link rel="stylesheet" type="text/css" href="style.css">
- <title>Serialization - singleton</title>
- </head>
- <body link="#0000ff" vlink="#800080">
- <table border="0" cellpadding="7" cellspacing="0" width="100%" summary="header">
- <tr>
- <td valign="top" width="300">
- <h3><a href="../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../boost.png" border="0"></a></h3>
- </td>
- <td valign="top">
- <h1 align="center">Serialization</h1>
- <h2 align="center"><code style="white-space: normal">singleton</code></h2>
- </td>
- </tr>
- </table>
- <hr>
- <dl class="page-index">
- <dt><a href="#motivation">Motivation</a>
- <dt><a href="#features">Features</a>
- <dt><a href="#classinterface">Class Interface</a>
- <dt><a href="#requirements">Requirements</a>
- <dt><a href="#example">Examples</a>
- <dt><a href="#multithreading">Multi-Threading</a>
- </dl>
- <h3><a name="motivation">Motivation</a></h3>
- The serialization library relies on the existence of a number
- of static variables and tables to store information related
- to runtime types. Examples are tables which relate exported
- names to types and tables which relate base classes to derived
- classes. Construction, destruction and usage of these variables
- requires consideration of the following issues:
- <ul>
- <li>Some static data variable and constant entries refer to others.
- The sequence of initialization cannot be arbitrary but must be in proper
- sequence.</li>
- <li>A number of static variables aren't referred to explicitly and, without
- special precautions, will be stripped by most code optimizers</li>
- <li>Many of these variables are created by templates and special care must
- be taken to be sure that they are instantiated</li>
- <li>In a multi-threading system, its possible that these static variables
- will be accessed concurrently by separate threads. This would create a
- race condition with unpredictabe behavior</li>
- </ul>
- This singleton class addresses all of the above issues.
- <h3><a name="features">Features</a></h3>
- This singleton implementation has the following features:
- <ul>
- <li>
- Any instance will be constructed before any attempt is made to access it.</li>
- <li>
- Any instance created with a template is guaranteed to be instantiated.
- <li>
- Regardless of whether or not an instance has been explicitly
- referred to, it will not be stripped by the optimizer when the
- executable is built in release mode.
- <li>
- All instances are constructed before
- <code style="white-space: normal">main</code> is called
- regardless of where they might be referenced within the program.
- In a multi-tasking system, this guarantees that there will be no
- race conditions during the construction of any instance. No
- thread locking is required to guarantee this.
- <li>
- The above implies that any <code style="white-space: normal">const</code>
- instances are thread-safe during the whole program. Again, no
- thread locking is required.
- <li>
- If a mutable instance is created, and such an instance is modified
- after main is called in a multi-threading system, there exists
- the possibility that a race condition will occur. The serialization
- library takes care that in the few places where a mutable
- singleton is required, it is not altered after
- <code style="white-space: normal">main</code> is called.
- For a more general purpose usage, thread locking on this
- singleton could easily be implemented. But as the serialization
- library didn't require it, it wasn't implemented.
- </ul>
- <h3><a name="classinterface">Class Interface</a></h3>
- <pre><code>
- namespace boost {
- namespace serialization {
- template <class T>
- class singleton : public boost::noncopyable
- {
- public:
- static const T & get_const_instance();
- static T & get_mutable_instance();
- static bool is_destroyed();
- };
- } // namespace serialization
- } // namespace boost
- </code></pre>
- <dl>
- <dt><h4><pre><code>
- static const T & get_const_instance();
- </code></pre></h4></dt>
- <dd>
- Retrieve a constant reference to the singleton for this type.
- </dd>
- <dt><h4><pre><code>
- static T & get_mutable_instance();
- </code></pre></h4></dt>
- <dd>
- Retrieve a mutable reference to the singleton for this type.
- </dd>
- <dt><h4><pre><code>
- static bool is_destroyed();
- </code></pre></h4></dt>
- <dd>
- Return <code>true</code> if the destructor on this singleton has been
- called. Otherwise, return <code>false</code>.
- </dd>
- </dl>
- <h3><a name="requirements">Requirements</a></h3>
- In order to be used as
- <a target="singleton.hpp" href = "../../../boost/serialization/singleton.hpp">
- <code style="white-space: normal">
- singleton<T>
- </code>
- </a>, the type T must be default constructable.
- It doesn't require static variables - though it may have them.
- Since the library guarantees that only one instance of
- <a target="singleton.hpp" href = "../../../boost/serialization/singleton.hpp">
- <code style="white-space: normal">
- singleton<T>
- </code>
- </a>
- exists and all accesss is through the above static interface
- functions, common member functions of T become
- the functional equivalent of
- <code style="white-space: normal">static</code> functions.
- <h3><a name="example">Examples</a></h3>
- There are at least two different ways to use this class template.
- Both are used in the serialization library.
- <p>
- The first way is illustrated by an excerpt from the file
- <code style="white-space: normal"><a target="extended_type_info" href="../src/extended_type_info.cpp">extended_type_info.cpp</a></code>.
- which contains the following code:
- <pre><code>
- typedef std::set<const extended_type_info *, key_compare> ktmap;
- ...
- void
- extended_type_info::key_register(const char *key) {
- ...
- result = singleton<ktmap>::get_mutable_instance().insert(this);
- ...
- }
- </code></pre>
- Just by referring to the singleton instance anywhere in the program
- will guarantee that one and only one instance for the specified
- type (<code style="white-space: normal">ktmap</code> in this example)
- will exist throughout the program. There is no need for any other
- declaration or definition.
- <p>
- A second way is to use
- <a target="singleton.hpp" href = "../../../boost/serialization/singleton.hpp">
- <code style="white-space: normal">
- singleton<T>
- </code>
- </a>
- as one of the base classes of the type. This is illustrated by a simplified
- excerpt from
- <a target="extended_type_info_typeid.hpp" href = "../../../boost/serialization/extended_type_info_typeid.hpp">
- <code style="white-space: normal">
- extended_type_info_typeid.hpp
- </code>
- </a>
- <pre><code>
- template<class T>
- class extended_type_info_typeid :
- public detail::extended_type_info_typeid_0,
- public singleton<extended_type_info_typeid<const T> >
- {
- friend class singleton<extended_type_info_typeid<const T> >;
- private:
- // private constructor to inhibit any existence other than the
- // static one. Note: not all compilers support this !!!
- extended_type_info_typeid() :
- detail::extended_type_info_typeid_0()
- {
- type_register(typeid(T));
- }
- ~extended_type_info_typeid(){}
- ...
- };
- </code></pre>
- This usage will permit a more natural syntax to be used:
- <pre><code>
- extended_type_info_typeid<T>::get_const_instance()
- </code></pre>
- Again, including one or more of the above statements anywhere
- in the program will guarantee that one and only one instance
- is created and referred to.
- <h3><a name="multithreading">Multi-Threading</a></h3>
- This singleton CAN be safely used in multi-threading applications if one
- is careful follow a simple rule:
- <p>
- <b>Do not call get_mutable_instance when more than one thread is running!</b>
- All singletons used in the serialization library follow this rule.
- In order to help detect accidental violations of this rule there
- exist singleton lock/unlock functions.
- <pre><code>
- void boost::serialization::singleton_module::lock();
- void boost::serialization::singleton_module::unlock();
- bool boost::serialization::singleton_module::is_locked();
- </code></pre>
- In a program compiled for debug, any invocation of
- <code style="white-space: normal">get_mutable_instance()</code>
- while the library is in a "locked" state will trap in an assertion.
- The singleton module lock state is initialized as "unlocked" to permit
- alteration of static variables before
- <code style="white-space: normal">main</code> is called.
- The <code style="white-space: normal">lock()</code> and
- <code style="white-space: normal">unlock()</code> are "global"
- in that they affect ALL the singletons defined by this template.
- All serialization tests invoke <code style="white-space: normal">lock()</code>
- at the start of the progam. For programs compiled in release
- mode these functions have no effect.
- <hr>
- <p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2007.
- Distributed under the Boost Software License, Version 1.0. (See
- accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- </i></p>
- </body>
- </html>
|