255 lines
9.3 KiB
HTML
255 lines
9.3 KiB
HTML
<!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>
|