Boost C++ Libraries: Ticket #7360: Memory leak in pthread implementation of boost::thread_specific_ptr https://svn.boost.org/trac10/ticket/7360 <p> The potential leak occurs if an instance of thread_specific_ptr is created and then destroyed without ever being assigned to. Consider the following pieces of code, excerpted from the Boost.Thread library in release 1.49: </p> <p> From tss.hpp: </p> <pre class="wiki">thread_specific_ptr(): cleanup(detail::heap_new&lt;delete_data(), detail::do_heap_delete&lt;delete_data&gt;()) {} ~thread_specific_ptr() { detail::set_tss_data(this,boost::shared_ptr&lt;detail::tss_cleanup_function&gt;(),0,true); } </pre><p> There are only two places thread_specific_ptr calls set_tss_data: the destructor and in reset(). So if an instance of thread_specific_ptr is never used during its lifetime, the first call to set_tss_data will occur from the destructor. </p> <p> Now, looking at pthread/thread.cpp shows that set_tss_data has special handling for the combination of an empty cleanup function and a zero tss value which erases the corresponding node. But that handling is inside of a test for an existing node. Otherwise, a new node is unconditionally allocated. This is where I believe the leak originates. </p> <p> I think the tests in set_tss_data need to be rearranged in order to avoid gratuitously creating a new tss node when unused thread_specific_ptr instances are destroyed. </p> <pre class="wiki"> void set_tss_data(void const* key, boost::shared_ptr&lt;tss_cleanup_function&gt; func, void* tss_data,bool cleanup_existing) { if(tss_data_node* const current_node=find_tss_data(key)) { if(cleanup_existing &amp;&amp; current_node-&gt;func &amp;&amp; (current_node-&gt;value!=0)) { (*current_node-&gt;func)(current_node-&gt;value); } if(func || (tss_data!=0)) { current_node-&gt;func=func; current_node-&gt;value=tss_data; } else { erase_tss_node(key); } } else { add_new_tss_node(key,func,tss_data); // &lt;&lt;&lt;&lt;&lt;&lt; LEAK OCCURS HERE! } } </pre><p> Re-writing the last part of set_tss_data as follows appears to address the leaks we've observed: </p> <pre class="wiki">*************** *** 595,601 **** erase_tss_node(key); } } ! else { add_new_tss_node(key,func,tss_data); } --- 595,601 ---- erase_tss_node(key); } } ! else if(func || (tss_data!=0)) { add_new_tss_node(key,func,tss_data); } </pre> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/7360 Trac 1.4.3 viboes Tue, 11 Sep 2012 21:24:38 GMT status, component changed; owner set https://svn.boost.org/trac10/ticket/7360#comment:1 https://svn.boost.org/trac10/ticket/7360#comment:1 <ul> <li><strong>owner</strong> set to <span class="trac-author">viboes</span> </li> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">assigned</span> </li> <li><strong>component</strong> <span class="trac-field-old">None</span> → <span class="trac-field-new">thread</span> </li> </ul> Ticket viboes Tue, 11 Sep 2012 21:54:41 GMT <link>https://svn.boost.org/trac10/ticket/7360#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7360#comment:2</guid> <description> <p> Committed in trunk revision 80496.(posix part) </p> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Sat, 15 Sep 2012 15:08:33 GMT</pubDate> <title>milestone changed https://svn.boost.org/trac10/ticket/7360#comment:3 https://svn.boost.org/trac10/ticket/7360#comment:3 <ul> <li><strong>milestone</strong> <span class="trac-field-old">To Be Determined</span> → <span class="trac-field-new">Boost 1.52.0</span> </li> </ul> <p> Committed in trunk revision <a class="changeset" href="https://svn.boost.org/trac10/changeset/80533" title="Thread: Fixed windows part of 7360">[80533]</a>.(windows part) </p> Ticket viboes Sun, 23 Sep 2012 12:49:26 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/7360#comment:4 https://svn.boost.org/trac10/ticket/7360#comment:4 <ul> <li><strong>status</strong> <span class="trac-field-old">assigned</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">fixed</span> </li> </ul> <p> Committed revision <a class="changeset" href="https://svn.boost.org/trac10/changeset/80668" title="Thread: Merge from trunk">[80668]</a>. </p> Ticket