diff options
author | Anas Nashif <anas.nashif@intel.com> | 2012-10-30 12:57:26 -0700 |
---|---|---|
committer | Anas Nashif <anas.nashif@intel.com> | 2012-10-30 12:57:26 -0700 |
commit | 1a78a62555be32868418fe52f8e330c9d0f95d5a (patch) | |
tree | d3765a80e7d3b9640ec2e930743630cd6b9fce2b /doc/html/interprocess/interprocess_smart_ptr.html | |
download | boost-1a78a62555be32868418fe52f8e330c9d0f95d5a.tar.gz boost-1a78a62555be32868418fe52f8e330c9d0f95d5a.tar.bz2 boost-1a78a62555be32868418fe52f8e330c9d0f95d5a.zip |
Imported Upstream version 1.49.0upstream/1.49.0
Diffstat (limited to 'doc/html/interprocess/interprocess_smart_ptr.html')
-rwxr-xr-x | doc/html/interprocess/interprocess_smart_ptr.html | 802 |
1 files changed, 802 insertions, 0 deletions
diff --git a/doc/html/interprocess/interprocess_smart_ptr.html b/doc/html/interprocess/interprocess_smart_ptr.html new file mode 100755 index 0000000000..101212143c --- /dev/null +++ b/doc/html/interprocess/interprocess_smart_ptr.html @@ -0,0 +1,802 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>Ownership smart pointers</title> +<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.76.1"> +<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset"> +<link rel="up" href="../interprocess.html" title="Chapter 12. Boost.Interprocess"> +<link rel="prev" href="streams.html" title="Direct iostream formatting: vectorstream and bufferstream"> +<link rel="next" href="architecture.html" title="Architecture and internals"> +</head> +<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> +<table cellpadding="2" width="100%"><tr> +<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td> +<td align="center"><a href="../../../index.html">Home</a></td> +<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td> +<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> +<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> +<td align="center"><a href="../../../more/index.htm">More</a></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="streams.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../interprocess.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="architecture.html"><img src="../../../doc/src/images/next.png" alt="Next"></a> +</div> +<div class="section"> +<div class="titlepage"><div><div><h2 class="title" style="clear: both"> +<a name="interprocess.interprocess_smart_ptr"></a><a class="link" href="interprocess_smart_ptr.html" title="Ownership smart pointers">Ownership smart pointers</a> +</h2></div></div></div> +<div class="toc"><dl> +<dt><span class="section"><a href="interprocess_smart_ptr.html#interprocess.interprocess_smart_ptr.intrusive_ptr">Intrusive + pointer</a></span></dt> +<dt><span class="section"><a href="interprocess_smart_ptr.html#interprocess.interprocess_smart_ptr.scoped_ptr">Scoped + pointer</a></span></dt> +<dt><span class="section"><a href="interprocess_smart_ptr.html#interprocess.interprocess_smart_ptr.shared_ptr">Shared + pointer and weak pointer</a></span></dt> +<dt><span class="section"><a href="interprocess_smart_ptr.html#interprocess.interprocess_smart_ptr.unique_ptr">Unique + pointer</a></span></dt> +</dl></div> +<p> + C++ users know the importance of ownership smart pointers when dealing with + resources. Boost offers a wide range of such type of pointers: <code class="computeroutput"><span class="identifier">intrusive_ptr</span><span class="special"><></span></code>, + <code class="computeroutput"><span class="identifier">scoped_ptr</span><span class="special"><></span></code>, + <code class="computeroutput"><span class="identifier">shared_ptr</span><span class="special"><></span></code>... + </p> +<p> + When building complex shared memory/memory mapped files structures, programmers + would like to use also the advantages of these smart pointers. The problem + is that Boost and C++ TR1 smart pointers are not ready to be used for shared + memory. The cause is that those smart pointers contain raw pointers and they + use virtual functions, something that is not possible if you want to place + your data in shared memory. The virtual function limitation makes even impossible + to achieve the same level of functionality of Boost and TR1 with <span class="bold"><strong>Boost.Interprocess</strong></span> smart pointers. + </p> +<p> + Interprocess ownership smart pointers are mainly "smart pointers containing + smart pointers", so we can specify the pointer type they contain. + </p> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="interprocess.interprocess_smart_ptr.intrusive_ptr"></a><a class="link" href="interprocess_smart_ptr.html#interprocess.interprocess_smart_ptr.intrusive_ptr" title="Intrusive pointer">Intrusive + pointer</a> +</h3></div></div></div> +<p> + <code class="computeroutput"><a class="link" href="../boost/interprocess/intrusive_ptr.html" title="Class template intrusive_ptr">boost::interprocess::intrusive_ptr</a></code> + is the generalization of <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">intrusive_ptr</span><span class="special"><></span></code> to allow non-raw pointers as intrusive + pointer members. As the well-known <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">intrusive_ptr</span></code> + we must specify the pointee type but we also must also specify the pointer + type to be stored in the intrusive_ptr: + </p> +<pre class="programlisting"><span class="comment">//!The intrusive_ptr class template stores a pointer to an object</span> +<span class="comment">//!with an embedded reference count. intrusive_ptr is parameterized on</span> +<span class="comment">//!T (the type of the object pointed to) and VoidPointer(a void pointer type </span> +<span class="comment">//!that defines the type of pointer that intrusive_ptr will store).</span> +<span class="comment">//!intrusive_ptr<T, void *> defines a class with a T* member whereas</span> +<span class="comment">//!intrusive_ptr<T, offset_ptr<void> > defines a class with a offset_ptr<T> member.</span> +<span class="comment">//!Relies on unqualified calls to:</span> +<span class="comment">//! </span> +<span class="comment">//!void intrusive_ptr_add_ref(T * p);</span> +<span class="comment">//!void intrusive_ptr_release(T * p);</span> +<span class="comment">//!</span> +<span class="comment">//!with (p != 0)</span> +<span class="comment">//!</span> +<span class="comment">//!The object is responsible for destroying itself.</span> +<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">VoidPointer</span><span class="special">></span> +<span class="keyword">class</span> <span class="identifier">intrusive_ptr</span><span class="special">;</span> +</pre> +<p> + So <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">interprocess</span><span class="special">::</span><span class="identifier">intrusive_ptr</span><span class="special"><</span><span class="identifier">MyClass</span><span class="special">,</span> <span class="keyword">void</span><span class="special">*></span></code> + is equivalent to <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">intrusive_ptr</span><span class="special"><</span><span class="identifier">MyClass</span><span class="special">></span></code>. + But if we want to place the intrusive_ptr in shared memory we must specify + a relative pointer type like <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">interprocess</span><span class="special">::</span><span class="identifier">intrusive_ptr</span><span class="special"><</span><span class="identifier">MyClass</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">interprocess</span><span class="special">::</span><span class="identifier">offset_ptr</span><span class="special"><</span><span class="keyword">void</span><span class="special">></span> + <span class="special">></span></code> + </p> +<p> +</p> +<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">interprocess</span><span class="special">/</span><span class="identifier">managed_shared_memory</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">interprocess</span><span class="special">/</span><span class="identifier">smart_ptr</span><span class="special">/</span><span class="identifier">intrusive_ptr</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> + +<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">interprocess</span><span class="special">;</span> + +<span class="keyword">namespace</span> <span class="identifier">N</span> <span class="special">{</span> + +<span class="comment">//A class that has an internal reference count</span> +<span class="keyword">class</span> <span class="identifier">reference_counted_class</span> +<span class="special">{</span> + <span class="keyword">private</span><span class="special">:</span> + <span class="comment">//Non-copyable</span> + <span class="identifier">reference_counted_class</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">reference_counted_class</span> <span class="special">&);</span> + <span class="comment">//Non-assignable</span> + <span class="identifier">reference_counted_class</span> <span class="special">&</span> <span class="keyword">operator</span><span class="special">=(</span><span class="keyword">const</span> <span class="identifier">reference_counted_class</span> <span class="special">&);</span> + <span class="comment">//A typedef to save typing</span> + <span class="keyword">typedef</span> <span class="identifier">managed_shared_memory</span><span class="special">::</span><span class="identifier">segment_manager</span> <span class="identifier">segment_manager</span><span class="special">;</span> + <span class="comment">//This is the reference count</span> + <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">m_use_count</span><span class="special">;</span> + <span class="comment">//The segment manager allows deletion from shared memory segment</span> + <span class="identifier">offset_ptr</span><span class="special"><</span><span class="identifier">segment_manager</span><span class="special">></span> <span class="identifier">mp_segment_manager</span><span class="special">;</span> + + <span class="keyword">public</span><span class="special">:</span> + <span class="comment">//Constructor</span> + <span class="identifier">reference_counted_class</span><span class="special">(</span><span class="identifier">segment_manager</span> <span class="special">*</span><span class="identifier">s_mngr</span><span class="special">)</span> + <span class="special">:</span> <span class="identifier">m_use_count</span><span class="special">(</span><span class="number">0</span><span class="special">),</span> <span class="identifier">mp_segment_manager</span><span class="special">(</span><span class="identifier">s_mngr</span><span class="special">){}</span> + <span class="comment">//Destructor</span> + <span class="special">~</span><span class="identifier">reference_counted_class</span><span class="special">(){}</span> + + <span class="keyword">public</span><span class="special">:</span> + <span class="comment">//Returns the reference count</span> + <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">use_count</span><span class="special">()</span> <span class="keyword">const</span> + <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">m_use_count</span><span class="special">;</span> <span class="special">}</span> + + <span class="comment">//Adds a reference</span> + <span class="keyword">inline</span> <span class="keyword">friend</span> <span class="keyword">void</span> <span class="identifier">intrusive_ptr_add_ref</span><span class="special">(</span><span class="identifier">reference_counted_class</span> <span class="special">*</span> <span class="identifier">p</span><span class="special">)</span> + <span class="special">{</span> <span class="special">++</span><span class="identifier">p</span><span class="special">-></span><span class="identifier">m_use_count</span><span class="special">;</span> <span class="special">}</span> + + <span class="comment">//Releases a reference</span> + <span class="keyword">inline</span> <span class="keyword">friend</span> <span class="keyword">void</span> <span class="identifier">intrusive_ptr_release</span><span class="special">(</span><span class="identifier">reference_counted_class</span> <span class="special">*</span> <span class="identifier">p</span><span class="special">)</span> + <span class="special">{</span> <span class="keyword">if</span><span class="special">(--</span><span class="identifier">p</span><span class="special">-></span><span class="identifier">m_use_count</span> <span class="special">==</span> <span class="number">0</span><span class="special">)</span> <span class="identifier">p</span><span class="special">-></span><span class="identifier">mp_segment_manager</span><span class="special">-></span><span class="identifier">destroy_ptr</span><span class="special">(</span><span class="identifier">p</span><span class="special">);</span> <span class="special">}</span> +<span class="special">};</span> + +<span class="special">}</span> <span class="comment">//namespace N {</span> + +<span class="comment">//A class that has an intrusive pointer to reference_counted_class</span> +<span class="keyword">class</span> <span class="identifier">intrusive_ptr_owner</span> +<span class="special">{</span> + <span class="keyword">typedef</span> <span class="identifier">intrusive_ptr</span><span class="special"><</span><span class="identifier">N</span><span class="special">::</span><span class="identifier">reference_counted_class</span><span class="special">,</span> + <span class="identifier">offset_ptr</span><span class="special"><</span><span class="keyword">void</span><span class="special">></span> <span class="special">></span> <span class="identifier">intrusive_ptr_t</span><span class="special">;</span> + <span class="identifier">intrusive_ptr_t</span> <span class="identifier">m_intrusive_ptr</span><span class="special">;</span> + + <span class="keyword">public</span><span class="special">:</span> + <span class="comment">//Takes a pointer to the reference counted class</span> + <span class="identifier">intrusive_ptr_owner</span><span class="special">(</span><span class="identifier">N</span><span class="special">::</span><span class="identifier">reference_counted_class</span> <span class="special">*</span><span class="identifier">ptr</span><span class="special">)</span> + <span class="special">:</span> <span class="identifier">m_intrusive_ptr</span><span class="special">(</span><span class="identifier">ptr</span><span class="special">){}</span> +<span class="special">};</span> + +<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> +<span class="special">{</span> + <span class="comment">//Remove shared memory on construction and destruction</span> + <span class="keyword">struct</span> <span class="identifier">shm_remove</span> + <span class="special">{</span> + <span class="identifier">shm_remove</span><span class="special">()</span> <span class="special">{</span> <span class="identifier">shared_memory_object</span><span class="special">::</span><span class="identifier">remove</span><span class="special">(</span><span class="string">"MySharedMemory"</span><span class="special">);</span> <span class="special">}</span> + <span class="special">~</span><span class="identifier">shm_remove</span><span class="special">(){</span> <span class="identifier">shared_memory_object</span><span class="special">::</span><span class="identifier">remove</span><span class="special">(</span><span class="string">"MySharedMemory"</span><span class="special">);</span> <span class="special">}</span> + <span class="special">}</span> <span class="identifier">remover</span><span class="special">;</span> + + <span class="comment">//Create shared memory</span> + <span class="identifier">managed_shared_memory</span> <span class="identifier">shmem</span><span class="special">(</span><span class="identifier">create_only</span><span class="special">,</span> <span class="string">"MySharedMemory"</span><span class="special">,</span> <span class="number">10000</span><span class="special">);</span> + + <span class="comment">//Create the unique reference counted object in shared memory</span> + <span class="identifier">N</span><span class="special">::</span><span class="identifier">reference_counted_class</span> <span class="special">*</span><span class="identifier">ref_counted</span> <span class="special">=</span> + <span class="identifier">shmem</span><span class="special">.</span><span class="identifier">construct</span><span class="special"><</span><span class="identifier">N</span><span class="special">::</span><span class="identifier">reference_counted_class</span><span class="special">></span> + <span class="special">(</span><span class="string">"ref_counted"</span><span class="special">)(</span><span class="identifier">shmem</span><span class="special">.</span><span class="identifier">get_segment_manager</span><span class="special">());</span> + + <span class="comment">//Create an array of ten intrusive pointer owners in shared memory</span> + <span class="identifier">intrusive_ptr_owner</span> <span class="special">*</span><span class="identifier">intrusive_owner_array</span> <span class="special">=</span> + <span class="identifier">shmem</span><span class="special">.</span><span class="identifier">construct</span><span class="special"><</span><span class="identifier">intrusive_ptr_owner</span><span class="special">></span> + <span class="special">(</span><span class="identifier">anonymous_instance</span><span class="special">)[</span><span class="number">10</span><span class="special">](</span><span class="identifier">ref_counted</span><span class="special">);</span> + + <span class="comment">//Now test that reference count is ten</span> + <span class="keyword">if</span><span class="special">(</span><span class="identifier">ref_counted</span><span class="special">-></span><span class="identifier">use_count</span><span class="special">()</span> <span class="special">!=</span> <span class="number">10</span><span class="special">)</span> + <span class="keyword">return</span> <span class="number">1</span><span class="special">;</span> + + <span class="comment">//Now destroy the array of intrusive pointer owners</span> + <span class="comment">//This should destroy every intrusive_ptr and because of</span> + <span class="comment">//that reference_counted_class will be destroyed</span> + <span class="identifier">shmem</span><span class="special">.</span><span class="identifier">destroy_ptr</span><span class="special">(</span><span class="identifier">intrusive_owner_array</span><span class="special">);</span> + + <span class="comment">//Now the reference counted object should have been destroyed</span> + <span class="keyword">if</span><span class="special">(</span><span class="identifier">shmem</span><span class="special">.</span><span class="identifier">find</span><span class="special"><</span><span class="identifier">intrusive_ptr_owner</span><span class="special">>(</span><span class="string">"ref_counted"</span><span class="special">).</span><span class="identifier">first</span><span class="special">)</span> + <span class="keyword">return</span> <span class="number">1</span><span class="special">;</span> + <span class="comment">//Success!</span> + <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span> +<span class="special">}</span> +</pre> +<p> + </p> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="interprocess.interprocess_smart_ptr.scoped_ptr"></a><a class="link" href="interprocess_smart_ptr.html#interprocess.interprocess_smart_ptr.scoped_ptr" title="Scoped pointer">Scoped + pointer</a> +</h3></div></div></div> +<p> + <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">interprocess</span><span class="special">::</span><span class="identifier">scoped_ptr</span><span class="special"><></span></code> + is the big brother of <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">scoped_ptr</span><span class="special"><></span></code>, which adds a custom deleter to specify + how the pointer passed to the scoped_ptr must be destroyed. Also, the <code class="computeroutput"><span class="identifier">pointer</span></code> typedef of the deleter will specify + the pointer type stored by scoped_ptr. + </p> +<pre class="programlisting"><span class="comment">//!scoped_ptr stores a pointer to a dynamically allocated object. </span> +<span class="comment">//!The object pointed to is guaranteed to be deleted, either on destruction</span> +<span class="comment">//!of the scoped_ptr, or via an explicit reset. The user can avoid this</span> +<span class="comment">//!deletion using release().</span> +<span class="comment">//!scoped_ptr is parameterized on T (the type of the object pointed to) and </span> +<span class="comment">//!Deleter (the functor to be executed to delete the internal pointer).</span> +<span class="comment">//!The internal pointer will be of the same pointer type as typename </span> +<span class="comment">//!Deleter::pointer type (that is, if typename Deleter::pointer is </span> +<span class="comment">//!offset_ptr<void>, the internal pointer will be offset_ptr<T>).</span> +<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Deleter</span><span class="special">></span> +<span class="keyword">class</span> <span class="identifier">scoped_ptr</span><span class="special">;</span> +</pre> +<p> + <code class="computeroutput"><span class="identifier">scoped_ptr</span><span class="special"><></span></code> + comes handy to implement <span class="bold"><strong>rollbacks</strong></span> with + exceptions: if an exception is thrown or we call <code class="computeroutput"><span class="keyword">return</span></code> + in the scope of <code class="computeroutput"><span class="identifier">scoped_ptr</span><span class="special"><></span></code> the deleter is automatically called + so that <span class="bold"><strong>the deleter can be considered as a rollback</strong></span> + function. If all goes well, we call <code class="computeroutput"><span class="identifier">release</span><span class="special">()</span></code> member function to avoid rollback when + the <code class="computeroutput"><span class="identifier">scoped_ptr</span></code> goes out of + scope. + </p> +<p> +</p> +<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">interprocess</span><span class="special">/</span><span class="identifier">managed_shared_memory</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">interprocess</span><span class="special">/</span><span class="identifier">smart_ptr</span><span class="special">/</span><span class="identifier">scoped_ptr</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> + +<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">interprocess</span><span class="special">;</span> + +<span class="keyword">class</span> <span class="identifier">my_class</span> +<span class="special">{};</span> + +<span class="keyword">class</span> <span class="identifier">my_exception</span> +<span class="special">{};</span> + +<span class="comment">//A functor that destroys the shared memory object</span> +<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> +<span class="keyword">class</span> <span class="identifier">my_deleter</span> +<span class="special">{</span> + <span class="keyword">private</span><span class="special">:</span> + <span class="comment">//A typedef to save typing</span> + <span class="keyword">typedef</span> <span class="identifier">managed_shared_memory</span><span class="special">::</span><span class="identifier">segment_manager</span> <span class="identifier">segment_manager</span><span class="special">;</span> + <span class="comment">//This my_deleter is created in the stack, not in shared memory,</span> + <span class="comment">//so we can use raw pointers</span> + <span class="identifier">segment_manager</span> <span class="special">*</span><span class="identifier">mp_segment_manager</span><span class="special">;</span> + + <span class="keyword">public</span><span class="special">:</span> + <span class="comment">//This typedef will specify the pointer type that</span> + <span class="comment">//scoped_ptr will store</span> + <span class="keyword">typedef</span> <span class="identifier">T</span> <span class="special">*</span><span class="identifier">pointer</span><span class="special">;</span> + <span class="comment">//Constructor</span> + <span class="identifier">my_deleter</span><span class="special">(</span><span class="identifier">segment_manager</span> <span class="special">*</span><span class="identifier">s_mngr</span><span class="special">)</span> + <span class="special">:</span> <span class="identifier">mp_segment_manager</span><span class="special">(</span><span class="identifier">s_mngr</span><span class="special">){}</span> + + <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">pointer</span> <span class="identifier">object_to_delete</span><span class="special">)</span> + <span class="special">{</span> <span class="identifier">mp_segment_manager</span><span class="special">-></span><span class="identifier">destroy_ptr</span><span class="special">(</span><span class="identifier">object_to_delete</span><span class="special">);</span> <span class="special">}</span> +<span class="special">};</span> + +<span class="keyword">int</span> <span class="identifier">main</span> <span class="special">()</span> +<span class="special">{</span> + <span class="comment">//Create shared memory</span> + <span class="comment">//Remove shared memory on construction and destruction</span> + <span class="keyword">struct</span> <span class="identifier">shm_remove</span> + <span class="special">{</span> + <span class="identifier">shm_remove</span><span class="special">()</span> <span class="special">{</span> <span class="identifier">shared_memory_object</span><span class="special">::</span><span class="identifier">remove</span><span class="special">(</span><span class="string">"MySharedMemory"</span><span class="special">);</span> <span class="special">}</span> + <span class="special">~</span><span class="identifier">shm_remove</span><span class="special">(){</span> <span class="identifier">shared_memory_object</span><span class="special">::</span><span class="identifier">remove</span><span class="special">(</span><span class="string">"MySharedMemory"</span><span class="special">);</span> <span class="special">}</span> + <span class="special">}</span> <span class="identifier">remover</span><span class="special">;</span> + + <span class="identifier">managed_shared_memory</span> <span class="identifier">shmem</span><span class="special">(</span><span class="identifier">create_only</span><span class="special">,</span> <span class="string">"MySharedMemory"</span><span class="special">,</span> <span class="number">10000</span><span class="special">);</span> + + <span class="comment">//In the first try, there will be no exceptions</span> + <span class="comment">//in the second try we will throw an exception</span> + <span class="keyword">for</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="identifier">i</span> <span class="special"><</span> <span class="number">2</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</span><span class="special">){</span> + <span class="comment">//Create an object in shared memory</span> + <span class="identifier">my_class</span> <span class="special">*</span> <span class="identifier">my_object</span> <span class="special">=</span> <span class="identifier">shmem</span><span class="special">.</span><span class="identifier">construct</span><span class="special"><</span><span class="identifier">my_class</span><span class="special">>(</span><span class="string">"my_object"</span><span class="special">)();</span> + <span class="identifier">my_class</span> <span class="special">*</span> <span class="identifier">my_object2</span> <span class="special">=</span> <span class="identifier">shmem</span><span class="special">.</span><span class="identifier">construct</span><span class="special"><</span><span class="identifier">my_class</span><span class="special">>(</span><span class="identifier">anonymous_instance</span><span class="special">)();</span> + <span class="identifier">shmem</span><span class="special">.</span><span class="identifier">destroy_ptr</span><span class="special">(</span><span class="identifier">my_object2</span><span class="special">);</span> + + <span class="comment">//Since the next shared memory allocation can throw</span> + <span class="comment">//assign it to a scoped_ptr so that if an exception occurs</span> + <span class="comment">//we destroy the object automatically</span> + <span class="identifier">my_deleter</span><span class="special"><</span><span class="identifier">my_class</span><span class="special">></span> <span class="identifier">d</span><span class="special">(</span><span class="identifier">shmem</span><span class="special">.</span><span class="identifier">get_segment_manager</span><span class="special">());</span> + + <span class="keyword">try</span><span class="special">{</span> + <span class="identifier">scoped_ptr</span><span class="special"><</span><span class="identifier">my_class</span><span class="special">,</span> <span class="identifier">my_deleter</span><span class="special"><</span><span class="identifier">my_class</span><span class="special">></span> <span class="special">></span> <span class="identifier">s_ptr</span><span class="special">(</span><span class="identifier">my_object</span><span class="special">,</span> <span class="identifier">d</span><span class="special">);</span> + <span class="comment">//Let's emulate a exception capable operation</span> + <span class="comment">//In the second try, throw an exception</span> + <span class="keyword">if</span><span class="special">(</span><span class="identifier">i</span> <span class="special">==</span> <span class="number">1</span><span class="special">){</span> + <span class="keyword">throw</span><span class="special">(</span><span class="identifier">my_exception</span><span class="special">());</span> + <span class="special">}</span> + <span class="comment">//If we have passed the dangerous zone</span> + <span class="comment">//we can release the scoped pointer</span> + <span class="comment">//to avoid destruction</span> + <span class="identifier">s_ptr</span><span class="special">.</span><span class="identifier">release</span><span class="special">();</span> + <span class="special">}</span> + <span class="keyword">catch</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">my_exception</span> <span class="special">&){}</span> + <span class="comment">//Here, scoped_ptr is destroyed</span> + <span class="comment">//so it we haven't thrown an exception</span> + <span class="comment">//the object should be there, otherwise, destroyed</span> + <span class="keyword">if</span><span class="special">(</span><span class="identifier">i</span> <span class="special">==</span> <span class="number">0</span><span class="special">){</span> + <span class="comment">//Make sure the object is alive</span> + <span class="keyword">if</span><span class="special">(!</span><span class="identifier">shmem</span><span class="special">.</span><span class="identifier">find</span><span class="special"><</span><span class="identifier">my_class</span><span class="special">>(</span><span class="string">"my_object"</span><span class="special">).</span><span class="identifier">first</span><span class="special">){</span> + <span class="keyword">return</span> <span class="number">1</span><span class="special">;</span> + <span class="special">}</span> + <span class="comment">//Now we can use it and delete it manually</span> + <span class="identifier">shmem</span><span class="special">.</span><span class="identifier">destroy</span><span class="special"><</span><span class="identifier">my_class</span><span class="special">>(</span><span class="string">"my_object"</span><span class="special">);</span> + <span class="special">}</span> + <span class="keyword">else</span><span class="special">{</span> + <span class="comment">//Make sure the object has been deleted</span> + <span class="keyword">if</span><span class="special">(</span><span class="identifier">shmem</span><span class="special">.</span><span class="identifier">find</span><span class="special"><</span><span class="identifier">my_class</span><span class="special">>(</span><span class="string">"my_object"</span><span class="special">).</span><span class="identifier">first</span><span class="special">){</span> + <span class="keyword">return</span> <span class="number">1</span><span class="special">;</span> + <span class="special">}</span> + <span class="special">}</span> + <span class="special">}</span> + <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span> +<span class="special">}</span> +</pre> +<p> + </p> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="interprocess.interprocess_smart_ptr.shared_ptr"></a><a class="link" href="interprocess_smart_ptr.html#interprocess.interprocess_smart_ptr.shared_ptr" title="Shared pointer and weak pointer">Shared + pointer and weak pointer</a> +</h3></div></div></div> +<p> + <span class="bold"><strong>Boost.Interprocess</strong></span> also offers the possibility + of creating non-intrusive reference-counted objects in managed shared memory + or mapped files. + </p> +<p> + Unlike <a href="http://www.boost.org/libs/smart_ptr/shared_ptr.htm" target="_top">boost::shared_ptr</a>, + due to limitations of mapped segments <code class="computeroutput"><a class="link" href="../boost/interprocess/shared_ptr.html" title="Class template shared_ptr">boost::interprocess::shared_ptr</a></code> + cannot take advantage of virtual functions to maintain the same shared pointer + type while providing user-defined allocators and deleters. The allocator + and the deleter are template parameters of the shared pointer. + </p> +<p> + Since the reference count and other auxiliary data needed by <code class="computeroutput"><a class="link" href="../boost/interprocess/shared_ptr.html" title="Class template shared_ptr">shared_ptr</a></code> + must be created also in the managed segment, and the deleter has to delete + the object from the segment, the user must specify an allocator object and + a deleter object when constructing a non-empty instance of <code class="computeroutput"><a class="link" href="../boost/interprocess/shared_ptr.html" title="Class template shared_ptr">shared_ptr</a></code>, + just like <span class="bold"><strong>Boost.Interprocess</strong></span> containers + need to pass allocators in their constructors. + </p> +<p> + Here is the declaration of <code class="computeroutput"><a class="link" href="../boost/interprocess/shared_ptr.html" title="Class template shared_ptr">shared_ptr</a></code>: + </p> +<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">VoidAllocator</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Deleter</span><span class="special">></span> +<span class="keyword">class</span> <span class="identifier">shared_ptr</span><span class="special">;</span> +</pre> +<div class="itemizedlist"><ul class="itemizedlist" type="disc"> +<li class="listitem"> + T is the type of the pointed type. + </li> +<li class="listitem"> + VoidAllocator is the allocator to be used to allocate auxiliary elements + such as the reference count, the deleter... The internal <code class="computeroutput"><span class="identifier">pointer</span></code> typedef of the allocator will + determine the type of pointer that shared_ptr will internally use, so + allocators defining <code class="computeroutput"><span class="identifier">pointer</span></code> + as <code class="computeroutput"><span class="identifier">offset_ptr</span><span class="special"><</span><span class="keyword">void</span><span class="special">></span></code> + will make all internal pointers used by <code class="computeroutput"><span class="identifier">shared_ptr</span></code> + to be also relative pointers. See <code class="computeroutput"><a class="link" href="../boost/interprocess/allocator.html" title="Class template allocator">boost::interprocess::allocator</a></code> + for a working allocator. + </li> +<li class="listitem"> + Deleter is the function object that will be used to destroy the pointed + object when the last reference to the object is destroyed. The deleter + functor will take a pointer to T of the same category as the void pointer + defined by <code class="computeroutput"><span class="identifier">VoidAllocator</span><span class="special">::</span><span class="identifier">pointer</span></code>. + See <code class="computeroutput"><a class="link" href="../boost/interprocess/deleter.html" title="Class template deleter">boost::interprocess::deleter</a></code> + for a generic deleter that erases a object from a managed segment. + </li> +</ul></div> +<p> + With correctly specified parameters, <span class="bold"><strong>Boost.Interprocess</strong></span> + users can create objects in shared memory that hold shared pointers pointing + to other objects also in shared memory, obtaining the benefits of reference + counting. Let's see how to create a shared pointer in a managed shared memory: + </p> +<p> +</p> +<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">interprocess</span><span class="special">/</span><span class="identifier">managed_shared_memory</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">interprocess</span><span class="special">/</span><span class="identifier">smart_ptr</span><span class="special">/</span><span class="identifier">shared_ptr</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">interprocess</span><span class="special">/</span><span class="identifier">allocators</span><span class="special">/</span><span class="identifier">allocator</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">interprocess</span><span class="special">/</span><span class="identifier">smart_ptr</span><span class="special">/</span><span class="identifier">deleter</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span> + +<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">interprocess</span><span class="special">;</span> + +<span class="comment">//This is type of the object we want to share</span> +<span class="keyword">class</span> <span class="identifier">MyType</span> +<span class="special">{};</span> + +<span class="keyword">typedef</span> <span class="identifier">managed_shared_memory</span><span class="special">::</span><span class="identifier">segment_manager</span> <span class="identifier">segment_manager_type</span><span class="special">;</span> +<span class="keyword">typedef</span> <span class="identifier">allocator</span><span class="special"><</span><span class="keyword">void</span><span class="special">,</span> <span class="identifier">segment_manager_type</span><span class="special">></span> <span class="identifier">void_allocator_type</span><span class="special">;</span> +<span class="keyword">typedef</span> <span class="identifier">deleter</span><span class="special"><</span><span class="identifier">MyType</span><span class="special">,</span> <span class="identifier">segment_manager_type</span><span class="special">></span> <span class="identifier">deleter_type</span><span class="special">;</span> +<span class="keyword">typedef</span> <span class="identifier">shared_ptr</span><span class="special"><</span><span class="identifier">MyType</span><span class="special">,</span> <span class="identifier">void_allocator_type</span><span class="special">,</span> <span class="identifier">deleter_type</span><span class="special">></span> <span class="identifier">my_shared_ptr</span><span class="special">;</span> + +<span class="keyword">int</span> <span class="identifier">main</span> <span class="special">()</span> +<span class="special">{</span> + <span class="comment">//Remove shared memory on construction and destruction</span> + <span class="keyword">struct</span> <span class="identifier">shm_remove</span> + <span class="special">{</span> + <span class="identifier">shm_remove</span><span class="special">()</span> <span class="special">{</span> <span class="identifier">shared_memory_object</span><span class="special">::</span><span class="identifier">remove</span><span class="special">(</span><span class="string">"MySharedMemory"</span><span class="special">);</span> <span class="special">}</span> + <span class="special">~</span><span class="identifier">shm_remove</span><span class="special">(){</span> <span class="identifier">shared_memory_object</span><span class="special">::</span><span class="identifier">remove</span><span class="special">(</span><span class="string">"MySharedMemory"</span><span class="special">);</span> <span class="special">}</span> + <span class="special">}</span> <span class="identifier">remover</span><span class="special">;</span> + + <span class="identifier">managed_shared_memory</span> <span class="identifier">segment</span><span class="special">(</span><span class="identifier">create_only</span><span class="special">,</span> <span class="string">"MySharedMemory"</span><span class="special">,</span> <span class="number">4096</span><span class="special">);</span> + + <span class="comment">//Create a shared pointer in shared memory</span> + <span class="comment">//pointing to a newly created object in the segment</span> + <span class="identifier">my_shared_ptr</span> <span class="special">&</span><span class="identifier">shared_ptr_instance</span> <span class="special">=</span> + <span class="special">*</span><span class="identifier">segment</span><span class="special">.</span><span class="identifier">construct</span><span class="special"><</span><span class="identifier">my_shared_ptr</span><span class="special">>(</span><span class="string">"shared ptr"</span><span class="special">)</span> + <span class="comment">//Arguments to construct the shared pointer</span> + <span class="special">(</span> <span class="identifier">segment</span><span class="special">.</span><span class="identifier">construct</span><span class="special"><</span><span class="identifier">MyType</span><span class="special">>(</span><span class="string">"object to share"</span><span class="special">)()</span> <span class="comment">//object to own</span> + <span class="special">,</span> <span class="identifier">void_allocator_type</span><span class="special">(</span><span class="identifier">segment</span><span class="special">.</span><span class="identifier">get_segment_manager</span><span class="special">())</span> <span class="comment">//allocator</span> + <span class="special">,</span> <span class="identifier">deleter_type</span><span class="special">(</span><span class="identifier">segment</span><span class="special">.</span><span class="identifier">get_segment_manager</span><span class="special">())</span> <span class="comment">//deleter</span> + <span class="special">);</span> + <span class="identifier">assert</span><span class="special">(</span><span class="identifier">shared_ptr_instance</span><span class="special">.</span><span class="identifier">use_count</span><span class="special">()</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span> + + <span class="comment">//Destroy "shared ptr". "object to share" will be automatically destroyed</span> + <span class="identifier">segment</span><span class="special">.</span><span class="identifier">destroy_ptr</span><span class="special">(&</span><span class="identifier">shared_ptr_instance</span><span class="special">);</span> + + <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span> +<span class="special">}</span> +</pre> +<p> + </p> +<p> + <code class="computeroutput"><a class="link" href="../boost/interprocess/shared_ptr.html" title="Class template shared_ptr">boost::interprocess::shared_ptr</a></code> + is very flexible and configurable (we can specify the allocator and the deleter, + for example), but as shown the creation of a shared pointer in managed segments + need too much typing. + </p> +<p> + To simplify this usage, <code class="computeroutput"><a class="link" href="../boost/interprocess/shared_ptr.html" title="Class template shared_ptr">boost::interprocess::shared_ptr</a></code> + header offers a shared pointer definition helper class (<code class="computeroutput"><a class="link" href="../boost/interprocess/managed_shared_ptr.html" title="Struct template managed_shared_ptr">managed_shared_ptr</a></code>) + and a function (<code class="computeroutput"><a class="link" href="../boost/interprocess/make_managed_shared_ptr_id993529.html" title="Function template make_managed_shared_ptr">make_managed_shared_ptr</a></code>) + to easily construct a shared pointer from a type allocated in a managed segment + with an allocator that will allocate the reference count also in the managed + segment and a deleter that will erase the object from the segment. + </p> +<p> + These utilities will use a <span class="bold"><strong>Boost.Interprocess</strong></span> + allocator (<code class="computeroutput"><a class="link" href="../boost/interprocess/allocator.html" title="Class template allocator">boost::interprocess::allocator</a></code>) + and deleter (<code class="computeroutput"><a class="link" href="../boost/interprocess/deleter.html" title="Class template deleter">boost::interprocess::deleter</a></code>) + to do their job. The definition of the previous shared pointer could be simplified + to the following: + </p> +<pre class="programlisting"><span class="keyword">typedef</span> <span class="identifier">managed_shared_ptr</span><span class="special"><</span><span class="identifier">MyType</span><span class="special">,</span> <span class="identifier">managed_shared_memory</span><span class="special">>::</span><span class="identifier">type</span> <span class="identifier">my_shared_ptr</span><span class="special">;</span> +</pre> +<p> + And the creation of a shared pointer can be simplified to this: + </p> +<pre class="programlisting"><span class="identifier">my_shared_ptr</span> <span class="identifier">sh_ptr</span> <span class="special">=</span> <span class="identifier">make_managed_shared_ptr</span> + <span class="special">(</span><span class="identifier">segment</span><span class="special">.</span><span class="identifier">construct</span><span class="special"><</span><span class="identifier">MyType</span><span class="special">>(</span><span class="string">"object to share"</span><span class="special">)(),</span> <span class="identifier">segment</span><span class="special">);</span> +</pre> +<p> + <span class="bold"><strong>Boost.Interprocess</strong></span> also offers a weak pointer + named <code class="computeroutput"><a class="link" href="../boost/interprocess/weak_ptr.html" title="Class template weak_ptr">weak_ptr</a></code> + (with its corresponding <code class="computeroutput"><a class="link" href="../boost/interprocess/managed_weak_ptr.html" title="Struct template managed_weak_ptr">managed_weak_ptr</a></code> + and <code class="computeroutput"><a class="link" href="../boost/interprocess/make_managed_weak_ptr.html" title="Function template make_managed_weak_ptr">make_managed_weak_ptr</a></code> + utilities) to implement non-owning observers of an object owned by <code class="computeroutput"><a class="link" href="../boost/interprocess/shared_ptr.html" title="Class template shared_ptr">shared_ptr</a></code>. + </p> +<p> + Now let's see a detailed example of the use of <code class="computeroutput"><a class="link" href="../boost/interprocess/shared_ptr.html" title="Class template shared_ptr">shared_ptr</a></code>: + and <code class="computeroutput"><a class="link" href="../boost/interprocess/weak_ptr.html" title="Class template weak_ptr">weak_ptr</a></code> + </p> +<p> +</p> +<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">interprocess</span><span class="special">/</span><span class="identifier">managed_mapped_file</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">interprocess</span><span class="special">/</span><span class="identifier">smart_ptr</span><span class="special">/</span><span class="identifier">shared_ptr</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">interprocess</span><span class="special">/</span><span class="identifier">smart_ptr</span><span class="special">/</span><span class="identifier">weak_ptr</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span> + +<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">interprocess</span><span class="special">;</span> + +<span class="comment">//This is type of the object we want to share</span> +<span class="keyword">struct</span> <span class="identifier">type_to_share</span> +<span class="special">{};</span> + +<span class="comment">//This is the type of a shared pointer to the previous type</span> +<span class="comment">//that will be built in the mapped file</span> +<span class="keyword">typedef</span> <span class="identifier">managed_shared_ptr</span><span class="special"><</span><span class="identifier">type_to_share</span><span class="special">,</span> <span class="identifier">managed_mapped_file</span><span class="special">>::</span><span class="identifier">type</span> <span class="identifier">shared_ptr_type</span><span class="special">;</span> +<span class="keyword">typedef</span> <span class="identifier">managed_weak_ptr</span><span class="special"><</span><span class="identifier">type_to_share</span><span class="special">,</span> <span class="identifier">managed_mapped_file</span><span class="special">>::</span><span class="identifier">type</span> <span class="identifier">weak_ptr_type</span><span class="special">;</span> + +<span class="comment">//This is a type holding a shared pointer</span> +<span class="keyword">struct</span> <span class="identifier">shared_ptr_owner</span> +<span class="special">{</span> + <span class="identifier">shared_ptr_owner</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">shared_ptr_type</span> <span class="special">&</span><span class="identifier">other_shared_ptr</span><span class="special">)</span> + <span class="special">:</span> <span class="identifier">shared_ptr_</span><span class="special">(</span><span class="identifier">other_shared_ptr</span><span class="special">)</span> + <span class="special">{}</span> + + <span class="identifier">shared_ptr_owner</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">shared_ptr_owner</span> <span class="special">&</span><span class="identifier">other_owner</span><span class="special">)</span> + <span class="special">:</span> <span class="identifier">shared_ptr_</span><span class="special">(</span><span class="identifier">other_owner</span><span class="special">.</span><span class="identifier">shared_ptr_</span><span class="special">)</span> + <span class="special">{}</span> + + <span class="identifier">shared_ptr_type</span> <span class="identifier">shared_ptr_</span><span class="special">;</span> + <span class="comment">//...</span> +<span class="special">};</span> + +<span class="keyword">int</span> <span class="identifier">main</span> <span class="special">()</span> +<span class="special">{</span> + <span class="comment">//Define file names</span> + <span class="keyword">const</span> <span class="keyword">char</span> <span class="special">*</span><span class="identifier">MappedFile</span> <span class="special">=</span> <span class="string">"MyMappedFile"</span><span class="special">;</span> + + <span class="comment">//Destroy any previous file with the name to be used.</span> + <span class="keyword">struct</span> <span class="identifier">file_remove</span> + <span class="special">{</span> + <span class="identifier">file_remove</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span> <span class="special">*</span><span class="identifier">MappedFile</span><span class="special">)</span> + <span class="special">:</span> <span class="identifier">MappedFile_</span><span class="special">(</span><span class="identifier">MappedFile</span><span class="special">)</span> <span class="special">{</span> <span class="identifier">file_mapping</span><span class="special">::</span><span class="identifier">remove</span><span class="special">(</span><span class="identifier">MappedFile_</span><span class="special">);</span> <span class="special">}</span> + <span class="special">~</span><span class="identifier">file_remove</span><span class="special">(){</span> <span class="identifier">file_mapping</span><span class="special">::</span><span class="identifier">remove</span><span class="special">(</span><span class="identifier">MappedFile_</span><span class="special">);</span> <span class="special">}</span> + <span class="keyword">const</span> <span class="keyword">char</span> <span class="special">*</span><span class="identifier">MappedFile_</span><span class="special">;</span> + <span class="special">}</span> <span class="identifier">remover</span><span class="special">(</span><span class="identifier">MappedFile</span><span class="special">);</span> + <span class="special">{</span> + <span class="identifier">managed_mapped_file</span> <span class="identifier">file</span><span class="special">(</span><span class="identifier">create_only</span><span class="special">,</span> <span class="identifier">MappedFile</span><span class="special">,</span> <span class="number">65536</span><span class="special">);</span> + + <span class="comment">//Construct the shared type in the file and</span> + <span class="comment">//pass ownership to this local shared pointer</span> + <span class="identifier">shared_ptr_type</span> <span class="identifier">local_shared_ptr</span> <span class="special">=</span> <span class="identifier">make_managed_shared_ptr</span> + <span class="special">(</span><span class="identifier">file</span><span class="special">.</span><span class="identifier">construct</span><span class="special"><</span><span class="identifier">type_to_share</span><span class="special">>(</span><span class="string">"object to share"</span><span class="special">)(),</span> <span class="identifier">file</span><span class="special">);</span> + <span class="identifier">assert</span><span class="special">(</span><span class="identifier">local_shared_ptr</span><span class="special">.</span><span class="identifier">use_count</span><span class="special">()</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span> + + <span class="comment">//Share ownership of the object between local_shared_ptr and a new "owner1"</span> + <span class="identifier">shared_ptr_owner</span> <span class="special">*</span><span class="identifier">owner1</span> <span class="special">=</span> + <span class="identifier">file</span><span class="special">.</span><span class="identifier">construct</span><span class="special"><</span><span class="identifier">shared_ptr_owner</span><span class="special">>(</span><span class="string">"owner1"</span><span class="special">)(</span><span class="identifier">local_shared_ptr</span><span class="special">);</span> + <span class="identifier">assert</span><span class="special">(</span><span class="identifier">local_shared_ptr</span><span class="special">.</span><span class="identifier">use_count</span><span class="special">()</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span> + + <span class="comment">//local_shared_ptr releases object ownership</span> + <span class="identifier">local_shared_ptr</span><span class="special">.</span><span class="identifier">reset</span><span class="special">();</span> + <span class="identifier">assert</span><span class="special">(</span><span class="identifier">local_shared_ptr</span><span class="special">.</span><span class="identifier">use_count</span><span class="special">()</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span> + <span class="identifier">assert</span><span class="special">(</span><span class="identifier">owner1</span><span class="special">-></span><span class="identifier">shared_ptr_</span><span class="special">.</span><span class="identifier">use_count</span><span class="special">()</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span> + + <span class="comment">//Share ownership of the object between "owner1" and a new "owner2"</span> + <span class="identifier">shared_ptr_owner</span> <span class="special">*</span><span class="identifier">owner2</span> <span class="special">=</span> + <span class="identifier">file</span><span class="special">.</span><span class="identifier">construct</span><span class="special"><</span><span class="identifier">shared_ptr_owner</span><span class="special">>(</span><span class="string">"owner2"</span><span class="special">)(*</span><span class="identifier">owner1</span><span class="special">);</span> + <span class="identifier">assert</span><span class="special">(</span><span class="identifier">owner1</span><span class="special">-></span><span class="identifier">shared_ptr_</span><span class="special">.</span><span class="identifier">use_count</span><span class="special">()</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span> + <span class="identifier">assert</span><span class="special">(</span><span class="identifier">owner2</span><span class="special">-></span><span class="identifier">shared_ptr_</span><span class="special">.</span><span class="identifier">use_count</span><span class="special">()</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span> + <span class="identifier">assert</span><span class="special">(</span><span class="identifier">owner1</span><span class="special">-></span><span class="identifier">shared_ptr_</span><span class="special">.</span><span class="identifier">get</span><span class="special">()</span> <span class="special">==</span> <span class="identifier">owner2</span><span class="special">-></span><span class="identifier">shared_ptr_</span><span class="special">.</span><span class="identifier">get</span><span class="special">());</span> + + <span class="comment">//The mapped file is unmapped here. Objects have been flushed to disk</span> + <span class="special">}</span> + <span class="special">{</span> + <span class="comment">//Reopen the mapped file and find again all owners</span> + <span class="identifier">managed_mapped_file</span> <span class="identifier">file</span><span class="special">(</span><span class="identifier">open_only</span><span class="special">,</span> <span class="identifier">MappedFile</span><span class="special">);</span> + + <span class="identifier">shared_ptr_owner</span> <span class="special">*</span><span class="identifier">owner1</span> <span class="special">=</span> <span class="identifier">file</span><span class="special">.</span><span class="identifier">find</span><span class="special"><</span><span class="identifier">shared_ptr_owner</span><span class="special">>(</span><span class="string">"owner1"</span><span class="special">).</span><span class="identifier">first</span><span class="special">;</span> + <span class="identifier">shared_ptr_owner</span> <span class="special">*</span><span class="identifier">owner2</span> <span class="special">=</span> <span class="identifier">file</span><span class="special">.</span><span class="identifier">find</span><span class="special"><</span><span class="identifier">shared_ptr_owner</span><span class="special">>(</span><span class="string">"owner2"</span><span class="special">).</span><span class="identifier">first</span><span class="special">;</span> + <span class="identifier">assert</span><span class="special">(</span><span class="identifier">owner1</span> <span class="special">&&</span> <span class="identifier">owner2</span><span class="special">);</span> + + <span class="comment">//Check everything is as expected</span> + <span class="identifier">assert</span><span class="special">(</span><span class="identifier">file</span><span class="special">.</span><span class="identifier">find</span><span class="special"><</span><span class="identifier">type_to_share</span><span class="special">>(</span><span class="string">"object to share"</span><span class="special">).</span><span class="identifier">first</span> <span class="special">!=</span> <span class="number">0</span><span class="special">);</span> + <span class="identifier">assert</span><span class="special">(</span><span class="identifier">owner1</span><span class="special">-></span><span class="identifier">shared_ptr_</span><span class="special">.</span><span class="identifier">use_count</span><span class="special">()</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span> + <span class="identifier">assert</span><span class="special">(</span><span class="identifier">owner2</span><span class="special">-></span><span class="identifier">shared_ptr_</span><span class="special">.</span><span class="identifier">use_count</span><span class="special">()</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span> + <span class="identifier">assert</span><span class="special">(</span><span class="identifier">owner1</span><span class="special">-></span><span class="identifier">shared_ptr_</span><span class="special">.</span><span class="identifier">get</span><span class="special">()</span> <span class="special">==</span> <span class="identifier">owner2</span><span class="special">-></span><span class="identifier">shared_ptr_</span><span class="special">.</span><span class="identifier">get</span><span class="special">());</span> + + <span class="comment">//Now destroy one of the owners, the reference count drops.</span> + <span class="identifier">file</span><span class="special">.</span><span class="identifier">destroy_ptr</span><span class="special">(</span><span class="identifier">owner1</span><span class="special">);</span> + <span class="identifier">assert</span><span class="special">(</span><span class="identifier">owner2</span><span class="special">-></span><span class="identifier">shared_ptr_</span><span class="special">.</span><span class="identifier">use_count</span><span class="special">()</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span> + + <span class="comment">//Create a weak pointer</span> + <span class="identifier">weak_ptr_type</span> <span class="identifier">local_observer1</span><span class="special">(</span><span class="identifier">owner2</span><span class="special">-></span><span class="identifier">shared_ptr_</span><span class="special">);</span> + <span class="identifier">assert</span><span class="special">(</span><span class="identifier">local_observer1</span><span class="special">.</span><span class="identifier">use_count</span><span class="special">()</span> <span class="special">==</span> <span class="identifier">owner2</span><span class="special">-></span><span class="identifier">shared_ptr_</span><span class="special">.</span><span class="identifier">use_count</span><span class="special">());</span> + + <span class="special">{</span> <span class="comment">//Create a local shared pointer from the weak pointer</span> + <span class="identifier">shared_ptr_type</span> <span class="identifier">local_shared_ptr</span> <span class="special">=</span> <span class="identifier">local_observer1</span><span class="special">.</span><span class="identifier">lock</span><span class="special">();</span> + <span class="identifier">assert</span><span class="special">(</span><span class="identifier">local_observer1</span><span class="special">.</span><span class="identifier">use_count</span><span class="special">()</span> <span class="special">==</span> <span class="identifier">owner2</span><span class="special">-></span><span class="identifier">shared_ptr_</span><span class="special">.</span><span class="identifier">use_count</span><span class="special">());</span> + <span class="identifier">assert</span><span class="special">(</span><span class="identifier">local_observer1</span><span class="special">.</span><span class="identifier">use_count</span><span class="special">()</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span> + <span class="special">}</span> + + <span class="comment">//Now destroy the remaining owner. "object to share" will be destroyed</span> + <span class="identifier">file</span><span class="special">.</span><span class="identifier">destroy_ptr</span><span class="special">(</span><span class="identifier">owner2</span><span class="special">);</span> + <span class="identifier">assert</span><span class="special">(</span><span class="identifier">file</span><span class="special">.</span><span class="identifier">find</span><span class="special"><</span><span class="identifier">type_to_share</span><span class="special">>(</span><span class="string">"object to share"</span><span class="special">).</span><span class="identifier">first</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span> + + <span class="comment">//Test observer</span> + <span class="identifier">assert</span><span class="special">(</span><span class="identifier">local_observer1</span><span class="special">.</span><span class="identifier">expired</span><span class="special">());</span> + <span class="identifier">assert</span><span class="special">(</span><span class="identifier">local_observer1</span><span class="special">.</span><span class="identifier">use_count</span><span class="special">()</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span> + + <span class="comment">//The reference count will be deallocated when all weak pointers</span> + <span class="comment">//disappear. After that, the file is unmapped.</span> + <span class="special">}</span> + <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span> +<span class="special">}</span> +</pre> +<p> + </p> +<p> + In general, using <span class="bold"><strong>Boost.Interprocess</strong></span>' <code class="computeroutput"><a class="link" href="../boost/interprocess/shared_ptr.html" title="Class template shared_ptr">shared_ptr</a></code> and <code class="computeroutput"><a class="link" href="../boost/interprocess/weak_ptr.html" title="Class template weak_ptr">weak_ptr</a></code> is very similar + to their counterparts <a href="http://www.boost.org/libs/smart_ptr/shared_ptr.htm" target="_top">boost::shared_ptr</a> + and <a href="http://www.boost.org/libs/smart_ptr/weak_ptr.htm" target="_top">boost::weak_ptr</a>, + but they need more template parameters and more run-time parameters in their + constructors. + </p> +<p> + Just like <a href="http://www.boost.org/libs/smart_ptr/shared_ptr.htm" target="_top">boost::shared_ptr</a> + can be stored in a STL container, <code class="computeroutput"><a class="link" href="../boost/interprocess/shared_ptr.html" title="Class template shared_ptr">shared_ptr</a></code> + can also be stored in <span class="bold"><strong>Boost.Interprocess</strong></span> + containers. + </p> +<p> + If a programmer just uses <code class="computeroutput"><a class="link" href="../boost/interprocess/shared_ptr.html" title="Class template shared_ptr">shared_ptr</a></code> + to be able to insert objects dynamically constructed in the managed segment + in a container, but does not need to share the ownership of that object with + other objects <code class="computeroutput"><a class="link" href="../boost/interprocess/unique_ptr.html" title="Class template unique_ptr">unique_ptr</a></code> + is a much faster and easier to use alternative. + </p> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="interprocess.interprocess_smart_ptr.unique_ptr"></a><a class="link" href="interprocess_smart_ptr.html#interprocess.interprocess_smart_ptr.unique_ptr" title="Unique pointer">Unique + pointer</a> +</h3></div></div></div> +<p> + Unique ownership smart pointers are really useful to free programmers from + manual resource liberation of non-shared objects. <span class="bold"><strong>Boost.Interprocess</strong></span>' + <code class="computeroutput"><a class="link" href="../boost/interprocess/unique_ptr.html" title="Class template unique_ptr">unique_ptr</a></code> is + much like <code class="computeroutput"><a class="link" href="../boost/interprocess/scoped_ptr.html" title="Class template scoped_ptr">scoped_ptr</a></code> + but it's <span class="bold"><strong>moveable</strong></span> and can be easily inserted + in <span class="bold"><strong>Boost.Interprocess</strong></span> containers. Here is + the declaration of the unique pointer class: + </p> +<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">D</span><span class="special">></span> +<span class="keyword">class</span> <span class="identifier">unique_ptr</span><span class="special">;</span> +</pre> +<div class="itemizedlist"><ul class="itemizedlist" type="disc"> +<li class="listitem"> + T is the type of the object pointed by <code class="computeroutput"><a class="link" href="../boost/interprocess/unique_ptr.html" title="Class template unique_ptr">unique_ptr</a></code>. + </li> +<li class="listitem"> + D is the deleter that will erase the object type of the object pointed + by <code class="computeroutput"><a class="link" href="../boost/interprocess/unique_ptr.html" title="Class template unique_ptr">unique_ptr</a></code> + when the unique pointer is destroyed (and if still owns ownership of + the object). If the deleter defines an internal <code class="computeroutput"><span class="identifier">pointer</span></code> + typedef, <code class="computeroutput"><a class="link" href="../boost/interprocess/unique_ptr.html" title="Class template unique_ptr">unique_ptr</a></code> + will use an internal pointer of the same type. So if <code class="computeroutput"><span class="identifier">D</span><span class="special">::</span><span class="identifier">pointer</span></code> + is <code class="computeroutput"><span class="identifier">offset_ptr</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code> + the unique pointer will store a relative pointer instead of a raw one. + This allows placing <code class="computeroutput"><a class="link" href="../boost/interprocess/unique_ptr.html" title="Class template unique_ptr">unique_ptr</a></code> + in shared memory and memory-mapped files. + </li> +</ul></div> +<p> + <code class="computeroutput"><a class="link" href="../boost/interprocess/unique_ptr.html" title="Class template unique_ptr">unique_ptr</a></code> can + release the ownership of the stored pointer so it's useful also to be used + as a rollback function. One of the main properties of the class is that + <span class="bold"><strong>is not copyable, but only moveable</strong></span>. When + a unique pointer is moved to another one, the ownership of the pointer is + transferred from the source unique pointer to the target unique pointer. + If the target unique pointer owned an object, that object is first deleted + before taking ownership of the new object. + </p> +<p> + <code class="computeroutput"><a class="link" href="../boost/interprocess/unique_ptr.html" title="Class template unique_ptr">unique_ptr</a></code> also + offers auxiliary types to easily define and construct unique pointers that + can be placed in managed segments and will correctly delete the owned object + from the segment: <code class="computeroutput"><a class="link" href="../boost/interprocess/managed_unique_ptr.html" title="Struct template managed_unique_ptr">managed_unique_ptr</a></code> + and <code class="computeroutput"><a class="link" href="../boost/interprocess/make_managed_unique_ptr.html" title="Function template make_managed_unique_ptr">make_managed_unique_ptr</a></code> + utilities. + </p> +<p> + Here we see an example of the use <code class="computeroutput"><a class="link" href="../boost/interprocess/unique_ptr.html" title="Class template unique_ptr">unique_ptr</a></code> + including creating containers of such objects: + </p> +<p> +</p> +<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">interprocess</span><span class="special">/</span><span class="identifier">managed_mapped_file</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">interprocess</span><span class="special">/</span><span class="identifier">smart_ptr</span><span class="special">/</span><span class="identifier">unique_ptr</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">interprocess</span><span class="special">/</span><span class="identifier">containers</span><span class="special">/</span><span class="identifier">vector</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">interprocess</span><span class="special">/</span><span class="identifier">containers</span><span class="special">/</span><span class="identifier">list</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">interprocess</span><span class="special">/</span><span class="identifier">allocators</span><span class="special">/</span><span class="identifier">allocator</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span> + +<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">interprocess</span><span class="special">;</span> + +<span class="comment">//This is type of the object we'll allocate dynamically</span> +<span class="keyword">struct</span> <span class="identifier">MyType</span> +<span class="special">{</span> + <span class="identifier">MyType</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">number</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> + <span class="special">:</span> <span class="identifier">number_</span><span class="special">(</span><span class="identifier">number</span><span class="special">)</span> + <span class="special">{}</span> + <span class="keyword">int</span> <span class="identifier">number_</span><span class="special">;</span> +<span class="special">};</span> + +<span class="comment">//This is the type of a unique pointer to the previous type</span> +<span class="comment">//that will be built in the mapped file</span> +<span class="keyword">typedef</span> <span class="identifier">managed_unique_ptr</span><span class="special"><</span><span class="identifier">MyType</span><span class="special">,</span> <span class="identifier">managed_mapped_file</span><span class="special">>::</span><span class="identifier">type</span> <span class="identifier">unique_ptr_type</span><span class="special">;</span> + +<span class="comment">//Define containers of unique pointer. Unique pointer simplifies object management</span> +<span class="keyword">typedef</span> <span class="identifier">vector</span> + <span class="special"><</span> <span class="identifier">unique_ptr_type</span> + <span class="special">,</span> <span class="identifier">allocator</span><span class="special"><</span><span class="identifier">unique_ptr_type</span><span class="special">,</span> <span class="identifier">managed_mapped_file</span><span class="special">::</span><span class="identifier">segment_manager</span><span class="special">></span> + <span class="special">></span> <span class="identifier">unique_ptr_vector_t</span><span class="special">;</span> + +<span class="keyword">typedef</span> <span class="identifier">list</span> + <span class="special"><</span> <span class="identifier">unique_ptr_type</span> + <span class="special">,</span> <span class="identifier">allocator</span><span class="special"><</span><span class="identifier">unique_ptr_type</span><span class="special">,</span> <span class="identifier">managed_mapped_file</span><span class="special">::</span><span class="identifier">segment_manager</span><span class="special">></span> + <span class="special">></span> <span class="identifier">unique_ptr_list_t</span><span class="special">;</span> + +<span class="keyword">int</span> <span class="identifier">main</span> <span class="special">()</span> +<span class="special">{</span> + <span class="comment">//Define file names</span> + <span class="keyword">const</span> <span class="keyword">char</span> <span class="special">*</span><span class="identifier">MappedFile</span> <span class="special">=</span> <span class="string">"MyMappedFile"</span><span class="special">;</span> + + <span class="comment">//Destroy any previous file with the name to be used.</span> + <span class="keyword">struct</span> <span class="identifier">file_remove</span> + <span class="special">{</span> + <span class="identifier">file_remove</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span> <span class="special">*</span><span class="identifier">MappedFile</span><span class="special">)</span> + <span class="special">:</span> <span class="identifier">MappedFile_</span><span class="special">(</span><span class="identifier">MappedFile</span><span class="special">)</span> <span class="special">{</span> <span class="identifier">file_mapping</span><span class="special">::</span><span class="identifier">remove</span><span class="special">(</span><span class="identifier">MappedFile_</span><span class="special">);</span> <span class="special">}</span> + <span class="special">~</span><span class="identifier">file_remove</span><span class="special">(){</span> <span class="identifier">file_mapping</span><span class="special">::</span><span class="identifier">remove</span><span class="special">(</span><span class="identifier">MappedFile_</span><span class="special">);</span> <span class="special">}</span> + <span class="keyword">const</span> <span class="keyword">char</span> <span class="special">*</span><span class="identifier">MappedFile_</span><span class="special">;</span> + <span class="special">}</span> <span class="identifier">remover</span><span class="special">(</span><span class="identifier">MappedFile</span><span class="special">);</span> + <span class="special">{</span> + <span class="identifier">managed_mapped_file</span> <span class="identifier">file</span><span class="special">(</span><span class="identifier">create_only</span><span class="special">,</span> <span class="identifier">MappedFile</span><span class="special">,</span> <span class="number">65536</span><span class="special">);</span> + + <span class="comment">//Construct an object in the file and</span> + <span class="comment">//pass ownership to this local unique pointer</span> + <span class="identifier">unique_ptr_type</span> <span class="identifier">local_unique_ptr</span> <span class="special">(</span><span class="identifier">make_managed_unique_ptr</span> + <span class="special">(</span><span class="identifier">file</span><span class="special">.</span><span class="identifier">construct</span><span class="special"><</span><span class="identifier">MyType</span><span class="special">>(</span><span class="string">"unique object"</span><span class="special">)(),</span> <span class="identifier">file</span><span class="special">));</span> + <span class="identifier">assert</span><span class="special">(</span><span class="identifier">local_unique_ptr</span><span class="special">.</span><span class="identifier">get</span><span class="special">()</span> <span class="special">!=</span> <span class="number">0</span><span class="special">);</span> + + <span class="comment">//Reset the unique pointer. The object is automatically destroyed</span> + <span class="identifier">local_unique_ptr</span><span class="special">.</span><span class="identifier">reset</span><span class="special">();</span> + <span class="identifier">assert</span><span class="special">(</span><span class="identifier">file</span><span class="special">.</span><span class="identifier">find</span><span class="special"><</span><span class="identifier">MyType</span><span class="special">>(</span><span class="string">"unique object"</span><span class="special">).</span><span class="identifier">first</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span> + + <span class="comment">//Now create a vector of unique pointers</span> + <span class="identifier">unique_ptr_vector_t</span> <span class="special">*</span><span class="identifier">unique_vector</span> <span class="special">=</span> + <span class="identifier">file</span><span class="special">.</span><span class="identifier">construct</span><span class="special"><</span><span class="identifier">unique_ptr_vector_t</span><span class="special">>(</span><span class="string">"unique vector"</span><span class="special">)(</span><span class="identifier">file</span><span class="special">.</span><span class="identifier">get_segment_manager</span><span class="special">());</span> + + <span class="comment">//Speed optimization</span> + <span class="identifier">unique_vector</span><span class="special">-></span><span class="identifier">reserve</span><span class="special">(</span><span class="number">100</span><span class="special">);</span> + + <span class="comment">//Now insert all values</span> + <span class="keyword">for</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="identifier">i</span> <span class="special"><</span> <span class="number">100</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</span><span class="special">){</span> + <span class="identifier">unique_ptr_type</span> <span class="identifier">p</span><span class="special">(</span><span class="identifier">make_managed_unique_ptr</span><span class="special">(</span><span class="identifier">file</span><span class="special">.</span><span class="identifier">construct</span><span class="special"><</span><span class="identifier">MyType</span><span class="special">>(</span><span class="identifier">anonymous_instance</span><span class="special">)(</span><span class="identifier">i</span><span class="special">),</span> <span class="identifier">file</span><span class="special">));</span> + <span class="identifier">unique_vector</span><span class="special">-></span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">p</span><span class="special">));</span> + <span class="identifier">assert</span><span class="special">(</span><span class="identifier">unique_vector</span><span class="special">-></span><span class="identifier">back</span><span class="special">()-></span><span class="identifier">number_</span> <span class="special">==</span> <span class="identifier">i</span><span class="special">);</span> + <span class="special">}</span> + + <span class="comment">//Now create a list of unique pointers</span> + <span class="identifier">unique_ptr_list_t</span> <span class="special">*</span><span class="identifier">unique_list</span> <span class="special">=</span> + <span class="identifier">file</span><span class="special">.</span><span class="identifier">construct</span><span class="special"><</span><span class="identifier">unique_ptr_list_t</span><span class="special">>(</span><span class="string">"unique list"</span><span class="special">)(</span><span class="identifier">file</span><span class="special">.</span><span class="identifier">get_segment_manager</span><span class="special">());</span> + + <span class="comment">//Pass ownership of all values to the list</span> + <span class="keyword">for</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">99</span><span class="special">;</span> <span class="special">!</span><span class="identifier">unique_vector</span><span class="special">-></span><span class="identifier">empty</span><span class="special">();</span> <span class="special">--</span><span class="identifier">i</span><span class="special">){</span> + <span class="identifier">unique_list</span><span class="special">-></span><span class="identifier">push_front</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">unique_vector</span><span class="special">-></span><span class="identifier">back</span><span class="special">()));</span> + <span class="comment">//The unique ptr of the vector is now empty...</span> + <span class="identifier">assert</span><span class="special">(</span><span class="identifier">unique_vector</span><span class="special">-></span><span class="identifier">back</span><span class="special">()</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span> + <span class="identifier">unique_vector</span><span class="special">-></span><span class="identifier">pop_back</span><span class="special">();</span> + <span class="comment">//...and the list has taken ownership of the value</span> + <span class="identifier">assert</span><span class="special">(</span><span class="identifier">unique_list</span><span class="special">-></span><span class="identifier">front</span><span class="special">()</span> <span class="special">!=</span> <span class="number">0</span><span class="special">);</span> + <span class="identifier">assert</span><span class="special">(</span><span class="identifier">unique_list</span><span class="special">-></span><span class="identifier">front</span><span class="special">()-></span><span class="identifier">number_</span> <span class="special">==</span> <span class="identifier">i</span><span class="special">);</span> + <span class="special">}</span> + <span class="identifier">assert</span><span class="special">(</span><span class="identifier">unique_list</span><span class="special">-></span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">100</span><span class="special">);</span> + + <span class="comment">//Now destroy the empty vector.</span> + <span class="identifier">file</span><span class="special">.</span><span class="identifier">destroy_ptr</span><span class="special">(</span><span class="identifier">unique_vector</span><span class="special">);</span> + <span class="comment">//The mapped file is unmapped here. Objects have been flushed to disk</span> + <span class="special">}</span> + <span class="special">{</span> + <span class="comment">//Reopen the mapped file and find again the list</span> + <span class="identifier">managed_mapped_file</span> <span class="identifier">file</span><span class="special">(</span><span class="identifier">open_only</span><span class="special">,</span> <span class="identifier">MappedFile</span><span class="special">);</span> + + <span class="identifier">unique_ptr_list_t</span> <span class="special">*</span><span class="identifier">unique_list</span> <span class="special">=</span> + <span class="identifier">file</span><span class="special">.</span><span class="identifier">find</span><span class="special"><</span><span class="identifier">unique_ptr_list_t</span><span class="special">>(</span><span class="string">"unique list"</span><span class="special">).</span><span class="identifier">first</span><span class="special">;</span> + <span class="identifier">assert</span><span class="special">(</span><span class="identifier">unique_list</span><span class="special">);</span> + <span class="identifier">assert</span><span class="special">(</span><span class="identifier">unique_list</span><span class="special">-></span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">100</span><span class="special">);</span> + + <span class="identifier">unique_ptr_list_t</span><span class="special">::</span><span class="identifier">const_iterator</span> <span class="identifier">list_it</span> <span class="special">=</span> <span class="identifier">unique_list</span><span class="special">-></span><span class="identifier">begin</span><span class="special">();</span> + <span class="keyword">for</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="identifier">i</span> <span class="special"><</span> <span class="number">100</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</span><span class="special">,</span> <span class="special">++</span><span class="identifier">list_it</span><span class="special">){</span> + <span class="identifier">assert</span><span class="special">((*</span><span class="identifier">list_it</span><span class="special">)-></span><span class="identifier">number_</span> <span class="special">==</span> <span class="identifier">i</span><span class="special">);</span> + <span class="special">}</span> + + <span class="comment">//Now destroy the list. All elements will be automatically deallocated.</span> + <span class="identifier">file</span><span class="special">.</span><span class="identifier">destroy_ptr</span><span class="special">(</span><span class="identifier">unique_list</span><span class="special">);</span> + <span class="special">}</span> + <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span> +<span class="special">}</span> +</pre> +<p> + </p> +</div> +</div> +<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> +<td align="left"></td> +<td align="right"><div class="copyright-footer">Copyright © 2005-2011 Ion Gaztanaga<p> + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>) + </p> +</div></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="streams.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../interprocess.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="architecture.html"><img src="../../../doc/src/images/next.png" alt="Next"></a> +</div> +</body> +</html> |