Boost C++ Libraries: Ticket #5673: Quick allocator error in multi thread https://svn.boost.org/trac10/ticket/5673 <p> Compiler: <strong>MSVS 2008</strong> use macros <strong>BOOST_SP_USE_QUICK_ALLOCATOR</strong> </p> <p> Exception (Access vialation by reading address) occured by constructor of <strong>shared_ptr</strong>. </p> <p> Cause of exception is multi thread creation of static mutex in quick allocator. </p> <p> shared_ptr call quick allocator. quick allocator use next code: </p> <pre class="wiki">lightweight_mutex::scoped_lock lock( mutex() ); </pre><p> function <strong>mutex()</strong> return internal static variable: </p> <pre class="wiki">boost_1_44_0\boost\smart_ptr\detail\quick_allocator.hpp template&lt;unsigned size, unsigned align_&gt; struct allocator_impl { ... static lightweight_mutex &amp; mutex() { static freeblock&lt; sizeof( lightweight_mutex ), boost::alignment_of&lt; lightweight_mutex &gt;::value &gt; fbm; static lightweight_mutex * pm = new( &amp;fbm ) lightweight_mutex; return *pm; } ... } </pre><p> 2 thread call mutex() (first time for this instantiation of template class allocator_impl). One start init <strong>pm</strong> and go to sleep. Other check that <strong>pm</strong> is initialized and return its value (in my case NULL) and raise exception. <br /> Initialization of static variable in C++ is not safe for multi thread. This code is incorrect. In dependence from realization of static variable you will be have access vialation or memory leak - flag of static variable initialization (construction) set before or after initialization. <br /> In MSVS 2008 flag set before and you take access vialation. <br /><br /> <strong>Decision</strong> <br /> Not resolve, but minimize problem. <br /> Idea:<br /> As I understand, This problem can appear in first initialization of <span class="underline">every</span> instantiation of shared_ptr - first use <span class="underline">every</span> instantiation of allocator_impl. <br /> If you synchronize of initialization <strong>pm</strong> then problem can appear only first initialization of <span class="underline">any</span> instantiation of shared_ptr. And I can create first fictive shared_ptr in non-multi thread and then normal use shared_ptr in multi thread. <br /> Realization:<br /> </p> <pre class="wiki">boost_1_44_0\boost\smart_ptr\detail\quick_allocator.hpp lightweight_mutex &amp; global_mutex() { static freeblock&lt; sizeof( lightweight_mutex ), boost::alignment_of&lt; lightweight_mutex &gt;::value &gt; fbm; static lightweight_mutex * pm = new( &amp;fbm ) lightweight_mutex; return *pm; } template&lt;unsigned size, unsigned align_&gt; struct allocator_impl { static lightweight_mutex &amp; mutex() { static freeblock&lt; sizeof( lightweight_mutex ), boost::alignment_of&lt; lightweight_mutex &gt;::value &gt; fbm; static lightweight_mutex * pm = NULL; if(pm == NULL) { lightweight_mutex::scoped_lock lock( global_mutex() ); if(pm == NULL) { pm = new( &amp;fbm ) lightweight_mutex; } } return *pm; } } </pre> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/5673 Trac 1.4.3 Steven Watanabe Sun, 16 Oct 2011 18:10:29 GMT component changed; owner set https://svn.boost.org/trac10/ticket/5673#comment:1 https://svn.boost.org/trac10/ticket/5673#comment:1 <ul> <li><strong>owner</strong> set to <span class="trac-author">Peter Dimov</span> </li> <li><strong>component</strong> <span class="trac-field-old">None</span> → <span class="trac-field-new">smart_ptr</span> </li> </ul> Ticket f@… Mon, 24 Oct 2011 15:41:43 GMT <link>https://svn.boost.org/trac10/ticket/5673#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5673#comment:2</guid> <description> <p> Hi, why does this global_mutex minimize the problem? </p> <p> Now thread A gets until gloabal_mutex init pm and then sleeps. During that time thread B goes to global_mutex and will get e.g. NULL and crash. </p> <p> Am I missing something? </p> </description> <category>Ticket</category> </item> <item> <author>Yury Podpruzhnikov <QWERTYura@…></author> <pubDate>Tue, 25 Oct 2011 16:16:17 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/5673#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5673#comment:3</guid> <description> <p> With global_mutex I can protect me from crash. </p> <p> At start (then I have only one thread) I can create first fictive shared_ptr. It initialize global_mutex. And next usage of any shared_ptr will be synchronize. </p> <p> Now I not sure in usage of shared_ptr because first usage new instantiation could use new mutex and produce crash. </p> </description> <category>Ticket</category> </item> </channel> </rss>